nginx 的 map 指令是实现灵活高效 ip 黑名单的理想选择,它在请求初始化阶段执行一次、无副作用、支持嵌套与外部文件联动,比 if + deny 更安全可维护。

Nginx 的 map 指令是实现灵活、高效 IP 黑名单屏蔽的理想选择,它比传统的 if + deny 更安全、更可维护,尤其适合动态更新或分级策略场景。
为什么用 map 而不是 if + deny?
if 在 location 外部使用有诸多限制和潜在风险(如变量未初始化、正则匹配副作用),而 map 是在 server 块顶层定义的变量映射机制,只在请求初始化阶段执行一次,无副作用、支持嵌套逻辑、可与 geo 或外部文件联动。
典型误区:直接写 if ($remote_addr = "1.2.3.4") { deny all; } —— 这不仅低效,还可能因 if 的执行时机导致规则失效或冲突。
基础 IP 黑名单:静态 map 定义
在 http 块中定义一个映射变量,将黑名单 IP 映射为非空值(如 "1"),再在 server 或 location 中统一拦截:
- 在
nginx.conf的http块内添加:
default 0;
192.168.1.100 1;
203.0.113.55 1;
2001:db8::1 1;
}
- 在
server块中启用拦截:
注意:if 此处仅用于判断已计算好的变量,是安全的;真正耗时/易错的匹配逻辑全部交给 map 完成。
进阶:从外部文件加载黑名单
当 IP 数量较多或需频繁更新时,避免硬编码。Nginx 支持 include 语法加载 map 配置:
- 新建文件
/etc/nginx/conf.d/blacklist.map:
192.168.1.100 1;
203.0.113.55 1;
# 可用脚本自动生成,支持注释(Nginx 1.19+ 解析时自动忽略以 # 开头的行)
- 在
http块中引用:
include /etc/nginx/conf.d/blacklist.map;
}
配合定时任务(如 cron + curl 下载最新黑名单)+ nginx -t && nginx -s reload,即可实现自动化黑白名单管理。
组合策略:按地域 + 行为分级封禁
map 支持链式调用与多条件叠加。例如:先用 geo 判断国家,再结合 IP 列表做精细控制:
- 定义地域标记:
default "";
include /etc/nginx/geoip-country.dat;
}
- 定义高危地区 + 特定 IP 组合封禁:
default 0;
"CN" 1;
"RU" 1;
}
map $remote_addr $is_suspicious {
default 0;
1.2.3.4 1;
5.6.7.8 1;
}
map "$high_risk_region:$is_suspicious" $block_reason {
default "";
"1:0" "region";
"0:1" "ip";
"1:1" "both";
}
- 拦截时可记录原因:
return 403 "Forbidden: blocked by $block_reason rule";
}
这样既保留日志可追溯性,又为后续 WAF 或审计系统提供结构化字段。











