nginx stream 模块的 allow/deny 仅在 stream → server 块内生效,按顺序匹配、紧贴 listen/proxy_pass,支持 ip/网段/ipv6,白名单优先于黑名单,推荐 external include 管理。

直接用 allow 和 deny 指令就能实现,关键在规则顺序、作用位置和默认行为——它不依赖 HTTP 模块,也不解析协议内容,纯靠源 IP 控制连接建立阶段的放行或拦截。
必须放在 stream 块的 server 内部
allow/deny 只能在 stream → server 块里生效,不能写在 http 块中,也不能放在 upstream 或全局 stream 块顶层。每条规则按从上到下顺序匹配,一旦命中就终止检查。
- 规则必须紧贴在
listen和proxy_pass之前(或之间),否则会被忽略 - 一个 server 块只能对应一种端口+协议(如
listen 3306是 TCP;listen 53 udp是 UDP) - 若同时需要黑白名单混合控制,务必把
allow放在deny前面,否则可信 IP 可能被提前拒掉
白名单:只留 allow,其余自动拒绝
适合数据库主库、内部管理接口等强管控场景。Nginx 默认隐含 deny all,所以不用显式写最后一条 deny。
-
allow 10.0.1.100;→ 单个 IP -
allow 172.16.0.0/12;→ 私有网段 -
allow ::1;→ IPv6 本地回环 - 不写任何 deny,也不加
deny all,逻辑更清晰、不易误配
黑名单:先放通大范围,再精准屏蔽
适用于对外提供服务但需临时封禁攻击源的场景,比如 SSH、MQTT 或游戏登录端口。
- 先用
allow放行内网、办公网或全部(allow 0.0.0.0/0;) - 再用
deny列出要封的恶意 IP 或网段:deny 203.0.113.42;、deny 198.51.100.0/24; - 结尾建议加
deny all;显式收尾,避免未来新增 allow 时漏掉兜底控制
提升可维护性的实用技巧
当 IP 数量变多,硬编码在主配置里容易出错且难更新。推荐用外部文件 + include 管理。
- 新建
/etc/nginx/conf.d/whitelist_mysql.conf,内容为多行allow语句 - 在 server 块中写
include /etc/nginx/conf.d/whitelist_mysql.conf; - 配合脚本自动增删 IP 后执行
nginx -t && nginx -s reload,无需人工编辑主配置 - 注意:include 文件路径必须是绝对路径,且 nginx 主进程要有读取权限











