Nginx反向代理下真实服务器IP暴露,Cloudflare隐藏失效求助
解决Cloudflare代理下服务器Remote Address显示真实IP的问题
核心原因
当使用Cloudflare作为反向代理时,正常情况下服务器的Remote Address(TCP连接层面的IP)应该是Cloudflare节点的IP。如果显示真实客户端IP,大概率是你的服务器没有限制仅接受Cloudflare IP的请求,导致客户端可以直接绕过Cloudflare访问真实服务器IP;或是Nginx配置有误,错误地将真实客户端IP覆盖到了remote_addr字段。
具体解决步骤
1. 限制服务器仅接受Cloudflare IP段的请求
这是最关键的一步,确保所有外部请求必须经过Cloudflare,直接访问真实IP的请求会被拦截。
方法一:通过防火墙配置(推荐)
在服务器防火墙(如iptables、ufw、firewalld)中添加规则,仅允许Cloudflare的IP段访问80(HTTP)和443(HTTPS)端口。以下是ufw的配置示例:
# 允许Cloudflare IPv4段 ufw allow from 103.21.244.0/22 to any port 80,443 ufw allow from 103.22.200.0/22 to any port 80,443 ufw allow from 103.31.4.0/22 to any port 80,443 ufw allow from 104.16.0.0/13 to any port 80,443 ufw allow from 104.24.0.0/14 to any port 80,443 ufw allow from 108.162.192.0/18 to any port 80,443 ufw allow from 131.0.72.0/22 to any port 80,443 ufw allow from 141.101.64.0/18 to any port 80,443 ufw allow from 162.158.0.0/15 to any port 80,443 ufw allow from 172.64.0.0/13 to any port 80,443 ufw allow from 173.245.48.0/20 to any port 80,443 ufw allow from 188.114.96.0/20 to any port 80,443 ufw allow from 190.93.240.0/20 to any port 80,443 ufw allow from 197.234.240.0/22 to any port 80,443 ufw allow from 198.41.128.0/17 to any port 80,443 # 允许Cloudflare IPv6段 ufw allow from 2400:cb00::/32 to any port 80,443 ufw allow from 2606:4700::/32 to any port 80,443 ufw allow from 2803:f800::/32 to any port 80,443 ufw allow from 2405:b500::/32 to any port 80,443 ufw allow from 2405:8100::/32 to any port 80,443 ufw allow from 2a06:98c0::/29 to any port 80,443 ufw allow from 2c0f:f248::/32 to any port 80,443 # 拒绝其他所有80/443端口的请求 ufw deny 80/tcp ufw deny 443/tcp
方法二:通过Nginx配置
在Nginx的全局配置或站点配置中添加allow/deny规则,只允许Cloudflare IP访问:
# 在http块或server块中添加 geo $cloudflare_ips { default 0; # Cloudflare IPv4段 103.21.244.0/22 1; 103.22.200.0/22 1; 103.31.4.0/22 1; 104.16.0.0/13 1; 104.24.0.0/14 1; 108.162.192.0/18 1; 131.0.72.0/22 1; 141.101.64.0/18 1; 162.158.0.0/15 1; 172.64.0.0/13 1; 173.245.48.0/20 1; 188.114.96.0/20 1; 190.93.240.0/20 1; 197.234.240.0/22 1; 198.41.128.0/17 1; # Cloudflare IPv6段 2400:cb00::/32 1; 2606:4700::/32 1; 2803:f800::/32 1; 2405:b500::/32 1; 2405:8100::/32 1; 2a06:98c0::/29 1; 2c0f:f248::/32 1; } server { listen 80; server_name your-domain.com; # 拒绝非Cloudflare的请求 if ($cloudflare_ips != 1) { return 403; } # 其他站点配置... }
2. 修正Nginx的真实IP配置(按需选择)
- 如果你想让
$remote_addr保留Cloudflare节点IP,同时获取真实客户端IP,可在Nginx日志中同时记录两个字段:
其中log_format cloudflare '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/your-domain-access.log cloudflare;$remote_addr是Cloudflare节点IP,$http_x_forwarded_for是真实客户端IP。 - 如果你之前配置了
real_ip_header X-Forwarded-For;和set_real_ip_from,这会把$remote_addr替换为真实客户端IP,想要恢复显示Cloudflare IP,直接移除这些配置即可。
3. 验证配置效果
- 重启防火墙或Nginx服务:
# 重启ufw ufw reload # 重启Nginx systemctl restart nginx - 访问你的网站,查看服务器日志中的
$remote_addr,应该显示Cloudflare的节点IP。 - 尝试直接用真实服务器IP访问,应该会被拦截(返回403或无法连接)。
内容的提问来源于stack exchange,提问作者Emin TATLI
相关产品推荐
相关产品推荐

