FastAPI WebSocket 无法获取真实 IP 错误记录
FastAPI WebSocket 无法获取真实 IP 错误记录
问题描述
在使用 FastAPI WebSocket 服务时,发现无法获取设备的真实 Remote IP,所有连接均显示为内网地址 10.x.x.1。以下是完整的排查过程及解决方案。
排查步骤
1. 基础信息检查
• 现象复现:通过 ws.client 确认连接的 IP 和端口均为 10.x.x.1。
• Header 检查:WebSocket 请求头中未发现 X-Forwarded-For、X-Real-IP 等代理相关字段。
• 网络拓扑验证:
公网 36.x.x.x -> 防火墙 NAT (10.x.x.1) -> 内部服务端口映射示例:36.x.x.x:18000 ➔ 10.x.x.180:800036.x.x.x:10002 ➔ 10.x.x.112:8001
2. 对比不同服务的表现
• 正常服务(10…x.x.112:8001):成功获取真实 IP(如 112.x.x.x)。
• 异常服务(10.x.x.180:8000):无论内网或外网访问,Remote IP 均为 10.x.x.1。
3. FastAPI IP 获取方式验证
通过以下代码尝试获取 IP,结果一致为 10.x.x.1:
# 方式 1: 握手信息
client_ip = websocket.client.host# 方式 2: 底层连接
client_ip = websocket._receive.client.host# 方式 3: 请求头检查
headers = websocket.headers
x_forwarded_for = headers.get("x-forwarded-for", "undefined")
4. 防火墙 NAT 规则差异分析
• 关键发现:
• 正常服务所在主机(10.x.x.112)的 NAT 规则为 Disabled。
• 异常服务所在主机(10.x.x.180)的 NAT 规则为 Enabled。
根本原因
防火墙 NAT 模式配置错误
当 NAT 规则启用(Enabled)时,防火墙会劫持并重写源 IP,导致后端服务只能看到防火墙的内网地址(10.x.x.1)。
而在 NAT 禁用(Disabled)模式下,原始源 IP 得以保留。
解决方案
-
调整防火墙 NAT 规则
将异常服务的 NAT 规则从 Enabled 改为 Disabled,确保源 IP 透传到后端服务。 -
验证结果
迁移服务到禁用 NAT 的规则组后,成功获取真实公网 IP。
额外发现:残留配置文件导致 IP 异常
现象
某次测试中获取到 47.x.x.x(阿里云 Nginx IP),但预期应为 36.x.x.x(设备直连 IP)。
排查
• 客户端配置冲突:旧版 .env 文件未清理,导致部分设备误连到阿里云代理服务器。
• 路径优先级问题:旧配置文件 software/.env 覆盖了新版 iot_client/.env。
修复
• 清理所有遗留的 software/.env 文件。
• 统一客户端配置路径,确保仅使用 iot_client/.env。
预防措施
-
代理头配置
如果必须启用 NAT,需在反向代理(如 Nginx)中配置以下 Header:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr;后端服务需读取这些字段以获取真实 IP。
-
配置管理规范
• 定期清理过期配置文件。
• 使用版本控制工具管理环境变量。 -
NAT 模式选择原则
• 直连场景:禁用 NAT 以保留源 IP。
• 需要隐藏内网时:启用 NAT 但需配置代理头。
总结与思考
• 网络层问题优先:IP 异常时首先检查防火墙、NAT、路由规则。
• 环境隔离的重要性:配置文件残留可能导致“幽灵问题”,需建立清理机制。
• 防御性编程:在代码中兼容多种 IP 获取方式:
def get_client_ip(websocket):headers = websocket.headersx_forwarded_for = headers.get("x-forwarded-for", "").split(",")[0]return x_forwarded_for or websocket.client.host
通过系统性排查,最终定位到 NAT 规则和环境配置两大核心问题。此类问题需结合网络架构与代码实现综合分析,避免陷入“单点验证”的误区。
相关文章:
FastAPI WebSocket 无法获取真实 IP 错误记录
FastAPI WebSocket 无法获取真实 IP 错误记录 问题描述 在使用 FastAPI WebSocket 服务时,发现无法获取设备的真实 Remote IP,所有连接均显示为内网地址 10.x.x.1。以下是完整的排查过程及解决方案。 排查步骤 1. 基础信息检查 • 现象复现࿱…...
Android自动化测试终极指南:从单元到性能全覆盖!
在快节奏的移动开发中,应用的稳定性与用户体验直接决定成败。手动测试效率低下,自动化测试成为提升质量的核心手段。本文将手把手带你掌握Android项目中的六大测试工具,涵盖单元测试、UI测试、性能测试、端到端测试等核心场景,助你构建坚如磐石的应用! 1. 单元测试:JUni…...
Python简单爬虫实践案例
学习目标 能够知道Web开发流程 能够掌握FastAPI实现访问多个指定网页 知道通过requests模块爬取图片 知道通过requests模块爬取GDP数据 能够用pyecharts实现饼图 能够知道logging日志的使用 一、基于FastAPI之Web站点开发 1、基于FastAPI搭建Web服务器 # 导入FastAPI模…...
Thunderbolt(雷电接口)详解
一、Thunderbolt的定义与核心特性 Thunderbolt 是由 Intel 和 Apple 联合开发的高速接口标准,结合PCIe和DisplayPort协议,支持 数据传输、视频输出、电源供应及设备级联。其核心特性包括: 超高带宽:Thunderbolt 4支持 40Gbps全双…...
基于springboot的房产销售系统(016)
摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于房产销售系统当然也不能排除在外,随着网络技术的不断成熟,带动了房产销售系统,它彻底改变了过去传统的…...
云盘搭建笔记
报错问题: No input file specified. 伪静态 location / {if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last;break;} } location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php/$1 last; break; } } 设…...
《从深海到卫浴:Relax Max如何用军工科技重塑生活仪式》
《从深海到卫浴:Relax Max如何用军工科技重塑生活仪式》 当瑞士联邦理工学院的一纸专利授权书揭开帷幕,卫浴行业终于意识到:Relax Max的「军工科技民用化」绝非营销噱头。这支由前潜艇工程师和航天材料学家组成的团队,将核潜艇…...
【vulhub/wordpress靶场】------获取webshell
1.进入靶场环境: 输入:cd / vulhub / wordpress / pwnscriptum 修改版本号: vim docker-compose.yml version: 3 保存退出 开启靶场环境: docker - compose up - d 开启成功,docker ps查看端口 靶场环境80…...
从OSI七层网络模型角度了解CAN通信协议
前言:先占个位置,文章内容皆来自网络,我只是搬运工,等后面理解深刻了再进行修文。 CAN通信协议的网络架构基于OSI七层模型进行设计,但实际实现中根据其应用场景(如汽车电子、工业控制等)进行了…...
人工智能助力家庭机器人:从清洁到陪伴的智能转型
引言:家庭机器人进入智能时代 过去,家庭机器人只是简单的“工具”,主要用于扫地、拖地、擦窗等单一任务。然而,随着人工智能(AI)技术的迅猛发展,家庭机器人正经历从“机械助手”向“智能管家”甚…...
【第14节】windows sdk编程:进程与线程介绍
目录 一、进程与线程概述 1.1 进程查看 1.2 何为进程 1.3 进程的创建 1.4 进程创建实例 1.5 线程查看 1.6 何为线程 1.7 线程的创建 1.8 线程函数 1.9 线程实例 二、内核对象 2.1 何为内核对象 2.2 内核对象的公共特点 2.3 内核对象句柄 2.4 内核对象的跨进程访…...
pytorch小记(十二):pytorch中 masked_fill_() vs. masked_fill() 详解
pytorch小记(十二):pytorch中 masked_fill_() vs. masked_fill()详解 PyTorch masked_fill_() vs. masked_fill() 详解1️⃣ masked_fill() 和 masked_fill_() 的作用2️⃣ masked_fill() vs. m…...
STM32U575RIT6单片机(四)
作业: 使用I2C获取SHT20传感器温湿度 使用I2C获取AP3216C三合一传感器: 光照, 接近, 红外 三个功能 合并的传感器 #ifndef SHT20_H #define SHT20_H#include "stdint.h" #include "i2c.h" #include "stdio.h" //1、确定从机的设备地址(代码不…...
EMQX安装与配置
EMQX安装与配置 EMQX安装与配置 https://www.emqx.com/zh/downloads-and-install/broker?osUbuntucd /usr/local/srcwget https://www.emqx.com/zh/downloads/broker/4.4.19/emqx-4.4.19-otp24.3.4.2-1-ubuntu16.04-amd64.deb sudo apt install ./emqx-4.4.19-otp24.3.4.2-1…...
JVM逃逸分析作用和原理
JVM逃逸分析作用和原理 在JVM的性能优化中,我们通常会关注内存分配、垃圾回收等问题。而逃逸分析(Escape Analysis)是JVM中一种精妙的优化技术,它可以在对象分配时判断该对象是否会在方法或线程之外被访问,从而影响其…...
拓展 Coco AI 功能 - 智能检索 Hexo 博客
在之前的文章中,我们成功让 Coco AI 检索 Hugo 博客,这对于博客作者来说是一大福音。然而,从 Hexo 迁移到 Hugo 的成本不容小觑,毕竟大多数开发者对 Node.js 更熟悉,而 Golang 相对陌生。那么,既然 Coco AI…...
爬虫基础之爬取猫眼Top100 可视化
网站: TOP100榜 - 猫眼电影 - 一网打尽好电影 本次案例所需用到的模块 requests (发送HTTP请求) pandas(数据处理和分析 保存数据) parsel(解析HTML数据) pyecharts(数据可视化图表) pymysql(连接和操作MySQL数据库) lxml(数据解析模块) 确定爬取的内容: 电影名称 电影主演…...
ffmpeg库视频硬解码使用流程
FFmpeg 的硬解码(Hardware Decoding)通过调用 GPU 或专用硬件的编解码能力实现,能显著降低 CPU 占用率。 一、FFmpeg 支持的硬件解码类型 FFmpeg 原生支持多种硬件加速类型,具体由 AVHWDeviceType 定义,包括&…...
LS-NET-006-思科MDS 9148S 查看内存
LS-NET-006-思科MDS 9148S 查看内存 方法一:使用 show version 命令 该命令可显示设备的基本系统信息,包括内存总量。 登录交换机的CLI(通过控制台或SSH连接)。输入命令: show version 在输出中查找类似以下内容…...
小程序API —— 54 路由与通信 - 编程式导航
在小程序中实现页面的跳转,有两种方式: 声明式导航:navigator 组件编程式导航:使用小程序提供的 API 编程式导航 API 提供了五个常用的 API 方法: wx.navigateTo():保留当前页面,跳转到应用内…...
关于金融开发领域的一些专业知识总结
目录 1. 交易生命周期 1.1 证券交易所 1.1.1 交易前 1) 订单生成(Order Generation) 2) 订单管理(Order Management) 1.1.2 交易执行 3) 交易匹配(Trade Matching) 1.1.3 交易后 4) 交易确认&…...
使用 `pytest` 框架时,可以通过极限封装将 YAML 文件的读取、解析
在使用 pytest 框架时,可以通过极限封装将 YAML 文件的读取、解析和测试用例的通用逻辑封装成共享的方法或 fixture,从而减少重复代码。以下是详细的实现步骤和示例。 1. 封装 YAML 文件读取和解析 将 YAML 文件的读取和解析逻辑封装到一个工具函数中,供所有测试用例调用。…...
蓝桥杯练习day3:反转字符串
一、题意 写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1: 输入:s [“h”,“e”,“…...
DeepSeek-R1深度解读
deepseek提出了一种通过强化学习(RL)激励大语言模型(LLMs)推理能力的方法,个人认为最让人兴奋的点是:通过RL发现了一个叫“Aha Moment”的现象,这个时刻发生在模型的中间版本中。在这个阶段&…...
15-双链表-双链表基本操作
题目 来源 827. 双链表 - AcWing题库 思路 此题我只想说,千万千万别漏了头结点和尾结点,不然根本查不出来是哪里出了问题,因为传入的k会有问题;最左边插入,相当于是在头结点的右边插入(也就是0号节点的右…...
正则表达式详解(regular expression)
💡 正则表达式(Regular Expression, regex)知识点总结 💡 正则表达式是一种用于匹配字符串的模式,广泛用于搜索、替换、验证等操作。 📌 正则表达式的主要作用 1️⃣ 字符串匹配 🧐 检查一个…...
经典面试题:C/C++中static关键字的三大核心作用与实战应用
一、修饰局部变量:改变生命周期,保留跨调用状态 核心作用: 延长生命周期:将局部变量从栈区移至静态存储区(数据段或BSS段),生命周期与程序一致保留状态:变量在函数多次调用间保…...
笔记:代码随想录算法训练营day57:99.岛屿数量 深搜、岛屿数量 广搜、100.岛屿的最大面积
学习资料:代码随想录 注:文中含大模型生成内容 99. 岛屿数量 卡码网题目链接(ACM模式) 先看深搜方法:找到未标标记过的说明找到一片陆地的或者一片陆地的一个角落,dfs搜索是寻找相连接的陆地其余部分并…...
【小也的Java之旅系列】01 分布式、集群、微服务的区别
前言 做Java开发多年,一直以来都有想把Java做成一个系列的想法,最近整理自己的笔记发现有很多值得写的内容,但这些内容又往往杂乱不堪。CSDN上有很多高质量的Java博客,但大多不是从一个人成长的角度去写的。而我们——一个技术人…...
基于视觉的核桃分级与套膜装置研究(大纲)
基于视觉的核桃分级与套膜装置研究:从设计到实现的完整指南 (SolidWorks、OpenCV、STM32开发实践) 🌟 项目背景与目标 1.1 为什么选择视觉分级与套膜? 产业痛点: 中国核桃年产量全球第一,但…...
