ngx_stream_access_module基于 IP 的流式访问控制实践指南

1. 前言

自 Nginx 1.9.2 起,官方在 Stream 子系统(四层 TCP/UDP 代理)中引入了 ngx_stream_access_module,用最简洁的 allow/deny 语义完成对客户端源地址的黑白名单控制。相比 HTTP 阶段常用的 ngx_http_access_module,它更专注于 L4 连接层,能保护 MySQL、Redis、MQTT、Syslog 等非-HTTP 后端。([nginx.org][1])

2. 典型应用场景

场景目标亮点
数据库内网暴露仅允许运维网段接入 MySQL 3306在 Nginx 上统一做四层防火墙,免后端逐台配置
UDP 日志网关仅允许特定 IDC 的收集器访问流量进入业务 VPC 前先做 ACL
物联网 MQTT Broker针对海外节点放行 IPv6 前缀与 HTTP ACL 混用,统一策略中心

3. 指令速查

指令语法作用域说明
allow`allow <addressCIDRunix:all>;`stream,server放行匹配地址/网段;unix: 代表全部本地 UNIX-Domain Socket
deny`deny <addressCIDRunix:all>;`同上拒绝匹配地址/网段;亦支持 all 全拒绝([nginx.org][1])

匹配顺序:按配置文件从上到下第一次命中即终止判定;未命中走默认策略。

4. 工作原理深入

  1. 阶段:发生在 preread 阶段(握手之后、业务代理之前),因此可在真正连接后端前就丢弃非法连接。
  2. 数据结构:解析指令后所有条目以前缀树保存,查找复杂度 O(log N)
  3. IPv6 支持:与 IPv4 同级,允许在同一 server 块混用;支持 /0–/128 任意前缀。
  4. UNIX-Domain Socket:当 Nginx 作为本机进程间代理(listen unix:/tmp/mysock)时,可利用 unix: 进行专门 ACL。

5. 基础配置与逐条解析

stream {
    # ① TCP 负载均衡到后端 MySQL
    upstream mysql_backend {
        server 10.0.0.10:3306 max_fails=3 fail_timeout=30s;
        server 10.0.0.11:3306;
    }

    server {
        listen 3306 reuseport;

        # ② 先阻止内网误写死地址
        deny 192.168.1.1;

        # ③ 放行两段内网 & 指定 IPv6
        allow 192.168.1.0/24;
        allow 10.1.1.0/16;
        allow 2001:db8::/32;

        # ④ 其余全部拒绝
        deny  all;

        proxy_pass mysql_backend;
        # ⑤ 观察日志
        access_log /var/log/nginx/mysql_stream.log;
    }
}
  • 先拒绝再放行? 实际上 顺序优先:如果把 deny all 写在最上面,会导致全部连接被立即拒绝。
  • IPv6 注意掩码::/0 相当于全部 IPv6,需要配合精细的 /32+ 前缀分段放行。

6. 与 ngx_http_access_module 的差异

特性stream(access)http(access)
工作层次L4 (TCP/UDP)L7 (HTTP)
可用指令allow / denyallow / deny
常见变量$remote_addr(仅日志)$remote_addr$binary_remote_addr
强制返回码关闭 TCP 连接返回 403 / 444
场景DB/MQ/自定义协议网站、API 网关

若需要在同一台 Nginx 对 HTTP 和 MySQL 均做 ACL,需分别在 http {}stream {} 各写一份规则,互不影响。

7. 动态模块与编译选项

默认编译时自动启用;如需裁剪体积,可 --without-stream_access_module;若使用 动态模块

./configure --with-stream --with-stream=dynamic
make && make install
# 配置文件中
load_module modules/ngx_stream_access_module.so;

这样可在运行时按需加载。([nginx.org][2])

8. 调试与排错

  • 快速验证nginx -t 只检查语法,不做 ACL 测试;可用 nc -vz 模拟不同 IP(借助 --source 选项)连通性。
  • access_log:在 stream 块显式声明日志路径,观察连接被 403 (“Forbidden”) 还是被硬断 (client closed connection)。
  • 连接追踪:结合 tcpdumpss -tn state TIME-WAIT 确认连接生命周期是否如预期。

9. 性能与最佳实践

  1. 条目顺序:把最常命中的网段写在最前面,减少匹配次数。
  2. 不可替代防火墙iptables/nftables内核栈 前就丢弃包,仍是第一道防线;Nginx ACL 更灵活,用于细粒度应用层转发。
  3. 集中管理:可搭配 include /etc/nginx/acl/*.conf; 把公共网段分文件维护,或借助 动态重载 工具(Ansible、SaltStack)。

10. 结语

ngx_stream_access_module 用极低成本在 Nginx 层增加了一道 面向传输层协议的访问控制网关。对于需要同时代理多种协议、并希望统一安全策略的场景,它是既轻量又高效的解决方案。熟练掌握 allow/deny 回溯顺序、CIDR 写法以及日志诊断技巧,就能在生产环境中快速隔离非法流量并保障关键服务安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello.Reader

请我喝杯咖啡吧😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值