要防御tcp代理层恶意并发连接攻击,需启用nginx stream上下文的limit_conn模块——工作在四层,统计established连接,超限即发rst拒绝,不解析协议、无排队;须单独编译stream与limit_conn模块,stream块内配置limit_conn_zone与limit_conn,不可与http块共用zone名,并配合超时、系统参数及防火墙加固。

要通过 limit_conn 模块防御 TCP 代理层的恶意并发连接攻击,核心是启用 Nginx 的 stream 上下文限流能力——它工作在四层(TCP/UDP),不解析 HTTP,专治 SYN 泛洪、慢连接、高频建连等资源耗尽类攻击。
确认并启用 stream 模块与 limit_conn 支持
Nginx 默认不编译 stream 模块,也需确保含 limit_conn 功能:
- 执行
nginx -V 2>&1 | grep -E "(with-stream|with-http_limit_conn_module)",若无输出,需重新编译:勾选「Stream 模块」和「连接数限制模块」 - 宝塔用户可在「软件商店 → Nginx → 设置 → 编译安装」中开启;编译后重启 Nginx
-
注意:
stream中的limit_conn与http块互不兼容,不能复用同一 zone 名称
在 stream 块中定义并应用连接限制
配置必须写在 nginx.conf 全局层级(http 块之外),例如:
- 在
stream块外顶部添加:limit_conn_zone $binary_remote_addr zone=stream_ip:10m;
该区域按客户端 IP 统计,10MB 可容纳约 16 万个独立 IP 的连接状态 - 在目标
stream { server { ... } }块内启用:limit_conn stream_ip 8;
表示单个 IP 最多同时建立 8 个 TCP 连接(如 SSH、MySQL、Redis 代理等) - 可叠加全局限制:
limit_conn_zone $server_addr zone=total_stream:10m;limit_conn total_stream 500;
防止某台机器被集中打爆,保护整个代理服务
理解生效逻辑与关键细节
stream 层的 limit_conn 行为更底层、更严格:
- 只统计已完成三次握手、且尚未关闭的 TCP 连接(ESTABLISHED 状态)
- 超限时 Nginx 直接发送 RST 包拒绝新连接,不排队、不转发、不记录请求头——响应快、开销极低
- 不支持
limit_req(无请求概念)、不感知协议内容,因此无法区分合法业务连接与恶意扫描 - 若上游是长连接服务(如数据库),需结合
proxy_timeout和系统级net.ipv4.tcp_fin_timeout避免连接堆积
配套加固建议
单靠 limit_conn 不足以应对复杂 TCP 攻击,建议组合使用:
- 设置合理超时:
tcp_nodelay on;proxy_timeout 30s;
避免慢连接长期占用 slot - 系统级防护:
调高文件描述符限制(fs.file-max)、启用net.ipv4.tcp_tw_reuse加速端口回收 - 日志与监控:
开启error_log /var/log/nginx/stream_error.log warn;,关注limit_conn rejected计数;配合 Prometheus + nginx-exporter 抓取nginx_stream_connections_active指标 - 前置过滤:在防火墙(如 iptables 或云厂商安全组)封禁已确认的恶意 IP 段,减轻 Nginx 负担










