Nginx 配置防火墙
这篇笔记围绕 Nginx 在反向代理和 Cloudflare 接入场景下的访问控制配置展开,核心问题是如何在使用真实客户端 IP 的同时避免错误信任可伪造的请求头。文中先给出一种粗糙写法:在 server 中将 set_real_ip_from 设为 0.0.0.0/0,并通过 real_ip_header CF-Connecting-IP 改写 remote_addr,再配合 allow 与 deny all 做访问限制;但这种做法等于让任意来源都能提交 CF-Connecting-IP,攻击者可借此伪造来源地址。文章解释了 Nginx 默认情况下 remote_addr 代表 TCP 连接源 IP,未启用 real_ip 时相对可信,而一旦信任范围放得过宽,就会主动放弃这一安全边界。更稳妥的方案是从 Cloudflare 官方 IPv4、IPv6 地址接口拉取网段,生成 cloudflare_real_ip.conf,逐行写入 set_real_ip_from,并配置 real_ip_header 与 real_ip_recursive。随后可在 http 块全局 include,或在单个 server 块中按站点生效,更新脚本执行后通过 nginx -t 校验并 reload 服务。文中还提醒 allow 规则按顺序匹配,deny all 会直接拒绝并返回 403;如果 VPS 同时具备 IPv4 和 IPv6,放行列表也要同时覆盖两类地址。最后通过 crontab 每周自动刷新 Cloudflare 网段,适合需要在 Nginx、Cloudflare 和反向代理链路中正确处理真实 IP 与访问白名单的运维或后端开发者参考。
粗糙的配置#
在 server 模块:
粗糙的做法,物理 ip设置 0.0.0.0/0 但是攻击者可以伪造 CF-Connecting-IP;
server {
# --- Cloudflare 真实 IP 配置 ---
set_real_ip_from 0.0.0.0/0;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
allow 127.0.0.1;
deny all; # 拒绝其他人
location / {
# 传递真实 IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
可以在 server 模块设置防火墙,同时可以在 location 在针对路径设置防火墙
特别注意,有些 vps 有 ipv4 和 ipv6 地址的,所以在 allow 模块需要填入 ipv4 与 ipv6 的地址信息,这样可以保证可以访问。
allow 就是从上到下执行的,deny all 就是禁止入站,会触发 403。
在 Nginx 的世界里,$remote_addr 这个变量通常代表连接者的物理 IP(TCP 连接的源 IP)。如果不开启 real_ip 模块,这个物理 IP 确实是无法伪造的(因为握手需要回包)。
但是,当你配置了 set_real_ip_from 0.0.0.0/0 和 real_ip_header CF-Connecting-IP 之后,你实际上修改了 Nginx 的底层逻辑,让它主动放弃了对物理 IP 的信任。
更加安全的配置#
vim /root/update_cf_ips.sh
#!/bin/bash
# 定义生成文件的位置
CF_CONF_FILE="/etc/nginx/cloudflare_real_ip.conf"
echo "# Cloudflare Real IP List - Generated on $(date)" > $CF_CONF_FILE
echo "" >> $CF_CONF_FILE
echo "# IPv4" >> $CF_CONF_FILE
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
echo "set_real_ip_from $ip;" >> $CF_CONF_FILE
done
echo "" >> $CF_CONF_FILE
echo "# IPv6" >> $CF_CONF_FILE
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
echo "set_real_ip_from $ip;" >> $CF_CONF_FILE
done
# 添加必要的头部定义 (可选,也可以写在 nginx 主配置里)
echo "" >> $CF_CONF_FILE
echo "real_ip_header CF-Connecting-IP;" >> $CF_CONF_FILE
echo "real_ip_recursive on;" >> $CF_CONF_FILE
# 检查 Nginx 配置并重载
nginx -t && systemctl reload nginx
echo "Cloudflare IPs updated successfully."
去查看 /etc/nginx/cloudflare_real_ip.conf,你会发现里面已经整整齐齐地写好了几十行 set_real_ip_from ...;
# Cloudflare Real IP List - Generated on Sat Dec 13 06:11:07 AM UTC 2025
# IPv4
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# IPv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;
选择在 http {} 块(全局生效) 引入,或者在 server {} 块(单独生效) 引入。
http {
# ... 其他原有配置 ...
# 👇 一行搞定所有 Cloudflare IP 配置
include /etc/nginx/cloudflare_real_ip.conf;
# ...
}
虽然 Cloudflare 的 IP 不常变,但为了保险起见,我们可以设个 Cron 任务,每周自动更新一次。
运行 crontab -e,添加一行
# 每周一凌晨 4 点自动更新 Cloudflare IP 列表
0 4 * * 1 /bin/bash /root/update_cf_ips.sh >/dev/null 2>&1
评论
还没有评论,来发第一个吧