Nginx 通过 map 指令结合外部 IP 文件与定时脚本实现正向代理动态白名单:先用脚本生成 whitelist.map 将 $remote_addr 映射为允许标记,再在 server 块中引用该 map 并用 if 判断拦截未授权请求,最后通过 crontab 定时更新文件并重载配置。

Nginx 本身不原生支持正向代理的动态白名单(尤其是基于 ngx_http_proxy_connect_module 的被动正向代理场景),但可以通过外部脚本 + crontab + Nginx 重载机制实现「定时更新白名单」的效果。关键在于:白名单逻辑不由 Nginx 原生解析,而是由配置文件或 Lua 脚本控制,再通过定时任务触发更新与热重载。
以下是以常见生产实践为基础的可行方案,适用于已启用 ngx_http_proxy_connect_module 的正向代理服务(监听如 8118 端口):
✅ 白名单落地方式:用 map + 外部 IP 列表文件
Nginx 不支持在 location 中直接 include 动态 IP 列表,但可通过 map 指令将 $remote_addr 映射为允许/拒绝标记,并配合 if 或 deny/allow 实现控制。
1. 准备白名单文件(纯文本,每行一个 IPv4/IPv6)
# /etc/nginx/conf.d/whitelist.ip 192.168.1.100 10.0.5.22 2001:db8::1
2. 编写生成 map 配置的脚本(例如 /usr/local/bin/update_whitelist.sh)
#!/bin/bash
WHITELIST_FILE="/etc/nginx/conf.d/whitelist.ip"
MAP_CONF="/etc/nginx/conf.d/whitelist.map"
# 生成 map 块:将白名单 IP 映射为 1,其余为 0
cat > "$MAP_CONF" << 'EOF'
map $remote_addr $is_allowed {
default 0;
EOF
while IFS= read -r ip; do
[[ -n "$ip" ]] && echo " $ip 1;" >> "$MAP_CONF"
done < "$WHITELIST_FILE"
echo "}" >> "$MAP_CONF"
# 语法检查 + 重载(仅当配置变更时)
nginx -t && nginx -s reload⚠️ 注意:脚本需有执行权限(
chmod +x /usr/local/bin/update_whitelist.sh),且确保nginx用户能读取/etc/nginx/conf.d/下的文件。
3. 在正向代理 server 块中引用该 map
server {
listen 8118;
resolver 100.96.0.2;
# 引入白名单判断
include /etc/nginx/conf.d/whitelist.map;
location / {
if ($is_allowed = 0) {
return 403;
}
proxy_pass $scheme://$http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}✅ 此方式兼容正向代理核心逻辑(包括 CONNECT 方法),且
map在 Nginx 启动/重载时一次性加载,性能无损耗。
✅ 配置 crontab 定时更新(例如每 5 分钟拉一次远程白名单)
# 编辑 root 的 crontab sudo crontab -e
添加一行(示例:每 5 分钟从内网 API 或本地文件更新):
*/5 * * * * /usr/local/bin/update_whitelist.sh >/var/log/nginx/whitelist_update.log 2>&1
? 若白名单来源是 HTTP 接口(如
curl -s https://api.example.com/ips),可在脚本中替换cat $WHITELIST_FILE为:curl -s https://api.example.com/whitelist | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$|^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$' > /etc/nginx/conf.d/whitelist.ip
✅ 补充建议:避免重载抖动
- 使用
nginx -t && nginx -s reload是安全的,但高频重载(如每秒)可能影响连接。建议最小间隔 ≥ 1 分钟。 - 如需更高可靠性,可加锁防止并发重载:
flock -n /tmp/nginx_whitelist_lock -c '/usr/local/bin/update_whitelist.sh'
- 日志中记录每次更新的 IP 数量,便于审计:
echo "$(date): $(wc -l < $WHITELIST_FILE) IPs loaded" >> /var/log/nginx/whitelist.log
不依赖第三方模块,不修改 Nginx 源码,利用 Nginx 原生 map + if + crontab,即可稳定支撑正向代理的定时白名单更新。


















