nginx stream模块无法使用limit_req、rewrite、map等http模块,因其工作在tcp/udp传输层,不解析http请求内容;仅支持基于连接的限速(limit_conn)、ip分级路由(geo/map)、健康检查与slow_start等四层平滑控制。

在 Nginx 的 TCP 代理模式(即使用 stream 块而非 http 块)下,无法直接使用 limit_req、rewrite、map 等 HTTP 层模块——因为这些模块只工作于应用层(HTTP),而 stream 是工作在传输层(TCP/UDP),不解析请求内容,仅转发原始字节流。
TCP 代理本身不支持“请求级”过滤
这是关键前提:Nginx stream 模块本质是四层负载均衡器,它能看到连接(IP+端口)、能做连接限速或黑白名单,但**看不到 HTTP 方法、URI、Header、Body 等请求内容**,因此无法实现类似 “拦截 /admin/delete” 或 “清洗 X-Forwarded-For 头” 这类基于语义的平滑过滤。
所谓“平滑过滤”,在 TCP 层只能体现为:
- 连接建立阶段的准入控制(如 IP 限连、地域封禁)
- 连接速率的削峰(如限制每秒新建连接数)
- 连接存活期的管控(如空闲超时、长连接保活)
- 后端节点健康状态驱动的自动摘除与恢复(避免流量打到宕机节点)
用 stream 模块实现可落地的“平滑”准入与调度
虽不能过滤请求内容,但可通过以下配置让 TCP 流量接入更可控、更稳定:
-
基于客户端 IP 的连接限速:防止连接洪泛攻击
limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;limit_conn conn_per_ip 20;
→ 单个 IP 最多维持 20 个并发 TCP 连接,超出则拒绝新连接(返回 RST) -
全局新建连接速率限制:防突发建连毛刺
limit_conn_zone $server_addr zone=conn_per_server:10m;limit_conn conn_per_server 1000;limit_conn_log_level error; -
结合 geo/map 做 IP 分级路由:将高风险地区流量导向蜜罐或限速池
geo $bad_region { default 0; 192.168.1.0/24 1; }map $bad_region $upstream_group { 1 "malicious_backend"; 0 "normal_backend"; }proxy_pass $upstream_group; -
启用健康检查 + slow_start:新节点上线时逐步放量,避免冷启动冲击
upstream db_cluster { server 10.0.1.10:3306 max_fails=3 fail_timeout=30s slow_start=60s;server 10.0.1.11:3306;
→ 新恢复节点在 60 秒内线性提升权重,从 0% 到 100%
真正需要“请求内容过滤”时的替代路径
若业务明确要求对 TCP 流量中的协议载荷(如 Redis 命令、MySQL 查询、gRPC 方法)做识别与干预,Nginx stream 无法胜任。此时应:
- 在上层部署协议感知代理(如 Envoy 支持 MySQL/Redis/gRPC 的过滤插件)
- 将 TCP 流量先经由一个轻量级 L7 网关(如基于 Lua 的 OpenResty)解包处理,再转给后端;或
- 在后端服务自身实现鉴权与限流(如 Redis 的
rename-command、MySQL 的账号权限分级),Nginx 仅做连接层兜底
小结:平滑不是“削请求”,而是“控连接”
在 TCP 代理场景下,“平滑过滤”的实质是通过连接粒度的限速、分级、健康联动,把不可控的原始连接流,转化为节奏可控、风险隔离、故障自愈的稳定入口。它不追求 HTTP 层的精细清洗,而是守住四层防线,为上层业务争取缓冲空间和响应时间。











