Nginx基于IP段的安全加固核心是allow/deny指令,仅适用于HTTP层的server/location块,不支持stream模块;需按顺序配置、以deny all收尾,配合geo模块可实现跨location复用,四层代理须用iptables/nftables替代。

在 Nginx 中实施基于 IP 段的访问安全加固,核心是利用 allow 和 deny 指令构建精准的黑白名单策略,但必须明确适用场景和配置边界——这些指令仅在 http 上下文(如 server 或 location 块)中生效,不适用于四层 stream 模块。
一、标准 HTTP 层 IP 段控制(适用于 Web 服务)
这是最常用且直接的方式,适合管理后台、API 接口等敏感路径:
- 在
location或server块内按顺序写入规则,Nginx 自上而下匹配,命中即终止 - 支持 CIDR 表示法(如
192.168.1.0/24)、单 IP(10.0.0.5),也支持 IPv6 - 务必以
deny all;收尾,否则未显式拒绝的 IP 默认放行
示例:只允许办公网段访问管理后台
location /admin/ {
allow 172.16.0.0/12; # 允许内网全部 172.16.x.x ~ 172.31.x.x
allow 203.0.113.10/32; # 允许特定运维 IP
deny all; # 拒绝其余所有
}二、用 geo 模块实现动态 IP 分组控制
当规则较复杂(如需跨多个 location 复用、或配合条件跳转),推荐用 geo 指令预定义变量:
-
geo块必须放在http级别,不能嵌套在 server 或 location 中 - 通过变量(如
$allowed)在任意 location 中统一判断,避免重复配置 - 支持
default值设定默认行为,逻辑更清晰
示例:
http {
geo $allowed {
default 0;
192.168.0.0/16 1;
10.0.0.0/8 1;
2001:db8::/32 1; # IPv6 支持
}
<pre class="brush:php;toolbar:false;">server {
location /api/ {
if ($allowed = 0) { return 403; }
# 后续正常代理或处理
}
}}
三、四层负载均衡(stream 模块)不能用 allow/deny
若你使用 Nginx 做 TCP/UDP 代理(如数据库、SSH、Redis 转发),stream 块中写 allow 会直接报错:"allow" directive is not allowed here。原因在于它工作在传输层,不解析 HTTP,也不加载 ngx_http_access_module。
- 替代方案是用系统防火墙(iptables 或 nftables)控制进入 Nginx 监听端口的源 IP
- 例如:只允许 10.10.0.0/16 访问 TCP 端口 5555
nft add rule ip filter INPUT tcp dport 5555 ip saddr 10.10.0.0/16 accept nft add rule ip filter INPUT tcp dport 5555 drop
该方式更底层、性能更高,也更符合四层场景的安全实践。
四、增强防护:结合连接限制与日志审计
单纯 IP 控制不够,建议叠加行为管控:
- 用
limit_conn_zone+limit_conn限制每个 IP 段的最大并发连接数 - 启用
access_log并记录$remote_addr,便于事后追溯异常访问 - 对关键路径额外加 Basic Auth,形成双重验证(IP 白名单 + 用户凭证)
例如:
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
location /backup/ {
allow 192.168.5.0/24;
deny all;
auth_basic "Backup Area";
auth_basic_user_file /etc/nginx/.htpasswd;
limit_conn perip 3; # 每个 IP 最多 3 个连接
}
}


















