如何检测请求来自本地HTTPS反向代理而非直接HTTP端口?
解决方法
启用ProxyFix后,request.remote_addr会被替换为X-Forwarded-For头中的客户端原始IP,因此无法再通过它判断请求是否来自反向代理。你需要捕获直接连接到Flask服务的原始IP(即反向代理的IP,或直接访问的客户端IP),具体实现步骤如下:
1. 添加自定义中间件捕获原始连接IP
创建一个中间件,在ProxyFix处理请求前,将TCP连接的原始IP保存到请求环境中:
class CaptureOriginalRemoteAddr: def __init__(self, app): self.app = app def __call__(self, environ, start_response): # 保存直接连接到Flask的原始IP environ['ORIGINAL_REMOTE_ADDR'] = environ['REMOTE_ADDR'] return self.app(environ, start_response)
2. 调整中间件加载顺序
先加载自定义中间件,再加载ProxyFix,确保原始IP被提前捕获:
REST_API = Flask(__name__) # 先捕获原始连接IP REST_API.wsgi_app = CaptureOriginalRemoteAddr(REST_API.wsgi_app) # 再应用ProxyFix处理客户端IP REST_API.wsgi_app = ProxyFix(REST_API.wsgi_app, x_for=1)
3. 修改请求校验逻辑
在before_request中检查原始连接IP是否为你的反向代理IP(比如本地Apache的127.0.0.1,或代理服务器的实际IP):
@REST_API.before_request def limit_remote_addr(): original_remote_addr = request.environ.get('ORIGINAL_REMOTE_ADDR') # 替换为你的反向代理IP或IP列表 allowed_proxy_ips = {'127.0.0.1'} if original_remote_addr not in allowed_proxy_ips: error_msg = get_error(ServerErrors.NO_PROXY) abort(403, error_msg)
注意事项
- 不要通过检查
X-Forwarded-For等请求头来判断,这类头可以被客户端伪造,存在安全风险。 - 确保
ProxyFix的x_for参数与你的代理层数匹配(比如单层代理设为1),避免客户端IP解析错误。
内容的提问来源于stack exchange,提问作者Db0
相关产品推荐
相关产品推荐

