Cloudflare+Apache反向代理下Flask获取真实客户端IP问题
解决Flask通过Apache+Cloudflare反向代理获取真实访客IP的问题
核心问题分析
你的Apache日志已显示真实IP,说明mod_remoteip已生效,但Flask仍获取127.0.0.1,原因有两点:
- 未配置Apache信任Cloudflare的代理IP段,导致
mod_remoteip处理后的真实IP未正确传递给反向代理后端; - 反向代理未将真实IP通过请求头传递给Flask,且Flask未信任该反向代理。
分步解决方案
1. 完善Apache的mod_remoteip配置
在Apache全局配置(如/etc/apache2/apache2.conf)或虚拟主机配置中,添加Cloudflare的可信代理IP段,确保mod_remoteip仅处理来自Cloudflare的请求:
# 确保加载mod_remoteip(若未加载) LoadModule remoteip_module modules/mod_remoteip.so # 添加Cloudflare所有IP段为可信代理 RemoteIPTrustedProxy 173.245.48.0/20 RemoteIPTrustedProxy 103.21.244.0/22 RemoteIPTrustedProxy 103.22.200.0/22 RemoteIPTrustedProxy 103.31.4.0/22 RemoteIPTrustedProxy 141.101.64.0/18 RemoteIPTrustedProxy 108.162.192.0/18 RemoteIPTrustedProxy 190.93.240.0/20 RemoteIPTrustedProxy 188.114.96.0/20 RemoteIPTrustedProxy 197.234.240.0/22 RemoteIPTrustedProxy 198.41.128.0/17 RemoteIPTrustedProxy 162.158.0.0/15 RemoteIPTrustedProxy 104.16.0.0/13 RemoteIPTrustedProxy 104.24.0.0/14 RemoteIPTrustedProxy 172.64.0.0/13 RemoteIPTrustedProxy 131.0.72.0/22 RemoteIPTrustedProxy 2400:cb00::/32 RemoteIPTrustedProxy 2606:4700::/32 RemoteIPTrustedProxy 2803:f800::/32 RemoteIPTrustedProxy 2405:b500::/32 RemoteIPTrustedProxy 2405:8100::/32 RemoteIPTrustedProxy 2a06:98c0::/29 RemoteIPTrustedProxy 2c0f:f248::/32 # 指定从CF-Connecting-IP头获取真实IP RemoteIPHeader CF-Connecting-IP
2. 修改Apache虚拟主机的反向代理配置
在ProxyPass指令前添加RequestHeader,将处理后的真实IP传递给Flask:
<VirtualHost *:80> ServerName xxx.xxx ServerAdmin xxx@xxx.xxx RemoteIPHeader CF-Connecting-IP # 传递真实IP到Flask RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s" ProxyPass / http://127.0.0.1:5000/ ProxyPassReverse / http://127.0.0.1:5000/ ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <IfModule mod_ssl.c> <VirtualHost *:443> ServerName xxx.xxx ServerAdmin xxx@xxx.xxx SSLCertificateFile /etc/cloudflare/xxx.pem SSLCertificateKeyFile /etc/cloudflare/xxx.key Protocols h2 h2c http/1.1 RemoteIPHeader CF-Connecting-IP Include /etc/letsencrypt/options-ssl-apache.conf # 传递真实IP到Flask RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s" ProxyPass / http://127.0.0.1:5000/ ProxyPassReverse / http://127.0.0.1:5000/ ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> </IfModule>
3. 配置Flask信任反向代理
根据Flask版本选择以下一种方式:
方式一:Flask 2.3+ 原生配置
from flask import Flask app = Flask(__name__) # 信任本地Apache反向代理 app.config['TRUSTED_PROXIES'] = ['127.0.0.1']
方式二:使用Werkzeug ProxyFix中间件(兼容所有版本)
from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # x_for=1 表示信任第一个X-Forwarded-For头中的IP app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
验证配置
完成上述步骤后,重启Apache和Flask应用,在Flask中直接通过request.remote_addr即可获取真实访客IP。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

