nginx tcp代理需启用stream模块并在顶层配置stream块,原样转发mysql等tcp流量;须验证模块存在、正确加载、独立于http块,再通过upstream和server定义数据库转发规则。

在 Nginx 中配置 TCP 代理实现数据库连接转发,核心是启用并正确使用 stream 模块——它工作在传输层(四层),不解析协议内容,原样转发 MySQL、PostgreSQL 等 TCP 流量,安全高效。
确认 stream 模块已启用
Nginx 默认不编译该模块,需提前验证或启用:
- 运行
nginx -V 2>&1 | grep -o with-stream,输出with-stream表示已内置支持 - 若无输出,Ubuntu/Debian 可安装动态模块:
sudo apt install nginx-mod-stream,然后在nginx.conf首行添加:load_module /usr/lib/nginx/modules/ngx_stream_module.so; - CentOS/RHEL 可用
yum install nginx-mod-stream或重新编译时加--with-stream
在顶层配置 stream 块
stream 必须放在 http 块之外(即主配置文件最外层),不能嵌套在 http 内:
- 编辑
/etc/nginx/nginx.conf,在events { ... }后、http { ... }前插入: stream { log_format proxy '$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time "$upstream_addr"'; access_log /var/log/nginx/tcp-access.log proxy; <pre class="brush:php;toolbar:false;">include /etc/nginx/stream-conf/*.conf;}
- 创建目录:
sudo mkdir -p /etc/nginx/stream-conf,便于按服务拆分管理
编写数据库转发规则
以 MySQL(默认端口 3306)为例,新建 /etc/nginx/stream-conf/mysql.conf:
upstream mysql_backend { server 192.168.10.5:3306; # 真实数据库 IP 和端口 # 可加 backup 或多节点实现简单高可用 }server { listen 3307; # 对外暴露的代理端口(避免与本地 MySQL 冲突) proxy_pass mysql_backend; proxy_timeout 1h; # 长连接建议设大些,如 3600s proxy_responses 1; # 确保连接建立即转发,不等待响应 }- 客户端连接时,只需连
nginx_ip:3307,Nginx 自动转到后端真实 MySQL
验证与注意事项
配置完成后务必测试连通性与权限:
- 检查语法:
sudo nginx -t,成功后再重载:sudo nginx -s reload - 防火墙开放代理端口(如 3307),但限制来源 IP:
ufw allow from 10.0.2.0/24 to any port 3307 - MySQL 用户需授权允许从 Nginx 服务器 IP 连接(不是客户端 IP),例如:
CREATE USER 'app'@'192.168.10.100' IDENTIFIED BY 'pwd'; GRANT ALL ON *.* TO 'app'@'192.168.10.100'; - 避免在
stream块中混用http相关指令(如location、proxy_set_header),它们无效且会报错











