Nginx TCP代理支持基于客户端IP的四层精准分流,需1.9.13+版本并启用stream及stream_realip_module;通过map指令实现CIDR、单IP等灵活映射,配合include可热更新,结合日志可追溯路由路径。

Nginx 的 TCP 代理(stream 模块)本身不解析应用层协议,但支持基于四层信息(如客户端 IP、端口、连接特征)做精准分流。按 IP 分流是常见且实用的场景,比如按地域、租户或安全策略将不同来源的 TCP 连接路由到对应后端。
必须启用 stream 模块并确认版本支持
Nginx 需为 1.9.13+ 版本,且编译时包含 --with-stream 和 --with-stream_realip_module(用于可信代理下获取真实 IP)。运行以下命令验证:
nginx -V 2>&1 | grep -o with-stream nginx -V 2>&1 | grep -o with-stream_realip_module
若缺失,需重新编译安装;部分发行版(如 Ubuntu 22.04+)的 nginx-full 包已默认包含。
使用 map 指令实现 IP 到后端的映射
map 是最灵活、可读性强的方式,支持 CIDR 网段、单 IP、通配符匹配,并能设默认后端。配置示例如下:
stream {
# 定义 IP 映射关系
map $remote_addr $upstream_backend {
default mysql-default;
192.168.1.10 mysql-shard1;
192.168.1.11 mysql-shard1;
10.0.5.0/24 mysql-shard2;
2001:db8::/32 mysql-shard3;
}
upstream mysql-shard1 {
server 10.10.1.100:3306 max_fails=3 fail_timeout=30s;
server 10.10.1.101:3306 backup;
}
upstream mysql-shard2 {
server 10.10.2.200:3306;
}
upstream mysql-shard3 {
server 10.10.3.150:3306;
}
upstream mysql-default {
server 10.10.0.50:3306;
}
server {
listen 3306;
proxy_pass $upstream_backend;
proxy_timeout 1h;
proxy_responses 1; # 可选:限制响应数,防连接滥用
}
}-
$remote_addr默认取直接客户端 IP;若 Nginx 前有 L4 负载均衡(如 AWS NLB),需配合set_real_ip_from+real_ip_header提前还原真实 IP。 -
map块必须在stream { }最外层定义,不能嵌套在server内。 - 匹配顺序从上到下,首个命中即生效;
default行确保未匹配 IP 有兜底路由。
支持动态更新与热重载
IP 规则变更无需重启 Nginx:
- 将
map配置单独存为/etc/nginx/stream_maps/ip_route.map,用include引入; - 修改该文件后执行
nginx -s reload,Nginx 会原子加载新映射表; - 配合脚本或配置中心(如 Consul Template),可实现 IP 白名单/黑名单自动同步。
日志记录与故障排查
开启连接级日志便于审计和定位问题:
log_format stream_log '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $upstream_addr'; access_log /var/log/nginx/tcp-access.log stream_log; error_log /var/log/nginx/tcp-error.log warn;
日志中 $upstream_addr 会显示实际转发的目标地址,配合 $upstream_backend 变量,可清晰追溯每个连接的路由路径。
不复杂但容易忽略细节。


















