白名单与黑名单的核心区别在于逻辑起点和规则顺序:白名单先allow后deny all,适用于严格限制场景;黑名单先deny后allow all,用于临时封禁;二者须按域名或路径隔离配置,并注意cdn、https及四层代理下的适配。

白名单和黑名单的核心区别在于逻辑起点:白名单是“只放行指定 IP,其余一律拒绝”,黑名单是“先封禁特定 IP,其余默认放行”。关键不是写多少条规则,而是 顺序 和 位置 —— 写错一行,整个策略就失效。
白名单配置:先允许多个,最后统一拒绝
适用于后台管理页、API 调试接口、数据库代理等需严格限制访问的路径。
- 所有
allow指令必须写在deny all;之前,且不能遗漏deny all;;否则未匹配的请求会默认放行 - 支持 IPv4 单地址(如
allow 203.0.113.25;)、IPv4 网段(如allow 192.168.50.0/24;)、IPv6(如allow 2001:db8::/32;) - 必须放在
server或location块内,不能写在http全局块中(否则影响所有站点) - 示例(仅允许内网和本地访问后台):
location /admin/ {<br> allow 192.168.10.0/24;<br> allow 127.0.0.1;<br> deny all;<br>}
黑名单配置:先拒绝,再兜底放行
适合临时屏蔽扫描 IP、恶意爬虫或已知攻击源,不影响正常流量。
-
deny规则写在allow all;前面,顺序不可颠倒;allow all;是必需的兜底项 - 可叠加多条
deny,例如同时封禁两个不同网段:deny 198.51.100.0/24;和deny 203.0.113.64/27; - 注意:根路径
location / { }中设黑名单时,要确认是否覆盖了静态资源或健康检查接口 - 示例(封禁两个恶意 IP,其余照常访问):
location / {<br> deny 203.0.113.5;<br> deny 198.51.100.12;<br> allow all;<br>}
按域名或路径隔离,避免互相干扰
一台服务器托管多个网站时,黑白名单必须各自独立配置,不能共用。
- 每个
server_name对应一个server块,在其内部设置对应规则 - 比如
admin.example.com的server块里配白名单,www.example.com的server块里配黑名单,两者互不干扰 - 若想对某类请求(如 PHP 脚本)做控制,应写在
location ~ \.php$ { }中,而非location / { },否则可能被 rewrite 绕过
进阶建议:提升可维护性与适配复杂场景
当规则变多、需跨服务复用,或面对 CDN/HTTPS 时,基础写法就不够用了。
- 用
geo指令在http块预定义变量(如$is_admin_ip),再在location中用if ($is_admin_ip = 0) { return 403; }控制,性能更好、更易脚本化更新 - 把 IP 列表抽成外部文件(如
/etc/nginx/conf.d/ip-whitelist.conf),然后用include引入,便于自动化运维和版本管理 - 经 CDN 或 HTTPS 反向代理后,真实客户端 IP 常被覆盖为代理 IP,需启用
real_ip_module并配置set_real_ip_from+real_ip_header还原原始 IP - 四层(TCP)场景(如保护 MySQL 3306 端口)要用
stream模块,规则写在stream { }块内,且白名单模式下可省略deny all;(默认隐含)











