第一章:开门见山——那个“裸奔”的数据库,我看不下去了!
兄弟们,不知道你们有没有干过这种事:项目紧,任务急,为了图省事,直接把测试服务器,甚至是生产环境的Redis或者MySQL端口(比如3306, 6379)在防火墙上一开放,啪一下,就能连了。
方便是真方便,但你这相当于把家里的金库大门,直接对着大马路敞开啊!每天都有无数脚本小子在网络上扫描这些默认端口,尝试各种弱密码攻击。你这不叫开放,这叫“裸奔”,是在危险的边缘疯狂试探!
那有同学要问了:“我知道危险啊,但我需要用远程工具连上去看数据、做调试啊,不暴露端口怎么办?用SSH隧道?太麻烦!用跳板机?还得维护一台机器!”
今天,我就来给你介绍一位被你严重低估的“隐形保安”——Nginx Stream模块。它就能完美、优雅且强大地解决这个问题。
第二章:重新认识Nginx——它不只是个“网站前台”
在咱们的固有印象里,Nginx是干啥的?处理HTTP请求的,做反向代理的,动静分离的,负载均衡的。没错,它是个顶级的“网站前台”和“流量调度员”。
但你知道吗?从Nginx 1.9.0版本开始,它解锁了一个新姿势: 模块。这个模块让Nginx的能力,从应用层(HTTP/HTTPS)一下子下沉到了传输层(TCP/UDP)。
ngx_stream_core_module
打个比方你就懂了:
传统的HTTP反向代理:像一个大公司的前台总机。你打电话(发HTTP请求)过来,说“喂,我找销售部”,前台帮你转接到销售部的分机。她只处理“找部门”这种特定规则的请求。今天的Stream代理:像一家国际货运港的中央调度。它不关心集装箱里装的是玩具汽车还是冰箱(不解析HTTP协议),它只认集装箱上的目的港标签(目标端口)。你的货船(TCP数据流)来了,它根据标签,指挥吊车把集装箱准确无误地装上去往目的港的另一艘货船上。
所以,Stream模块的核心能力就是:“无脑”转发TCP/UDP数据流。这意味着,它几乎可以代理任何基于TCP/UDP的服务!
数据库?MySQL, PostgreSQL, Redis, 没问题!邮件服务?SMTP, POP3, IMAP, 拿下!SSH, RDP远程桌面?照样通吃!甚至你可以用它来代理游戏服务器、内网穿透……
第三章:Stream模块的“超能力”详解——不只是转发那么简单
如果你以为Stream模块就是个端口转发工具,那可就太小看它了。这位“保安”可是身怀绝技的:
负载均衡:没错,和HTTP模块一样,它可以在多个后端服务实例之间做负载均衡。你的数据库搞了主从复制、读写分离?用Stream模块,一个入口,智能分发到不同的数据库实例上,支持、
round-robin等算法。连接限速与控制:可以限制到后端服务的并发连接数,防止某个服务被海量连接拖垮。SSL/TLS终结/加密:可以在Nginx这一层就完成SSL/TLS的加解密。比如,你可以让客户端到Nginx走加密的SSL连接,而Nginx到后端服务走内网明文,既保证了公网传输的安全,又减轻了后端服务的计算压力。反过来,也可以做SSL加密转发。访问控制:基于IP地址允许或拒绝连接,这是最基本的安保措施。高可用与健康检查:虽然Stream模块默认的健康检查比较基础(主要靠连接成功与否),但通过一些第三方模块或商业版Nginx Plus,可以实现主动式健康检查,确保流量只被转发到健康的后端节点。日志记录:可以对TCP/UDP会话进行日志记录,方便你排查网络连接问题,看看是谁、在什么时候、想连你的服务。
least_conn
看到没,它不是一个简单的“端口映射工具”,而是一个企业级的传输层网关。
第四章:手把手实战——给你的数据库请一位“保安”
理论吹得再响,不如上手干一把。我们来一个最经典的场景:通过Nginx Stream代理,让公网安全地访问内网的Redis服务。
环境准备:
Nginx服务器:假设IP是 ,已经安装Nginx,且版本 >= 1.9.0。Redis服务器:假设IP是
123.123.123.123,端口
192.168.1.100,只在内部网络可达。
6379
第一步:确认你的Nginx“武功”没被废
Stream模块默认可能没有编译进去。检查一下:
nginx -V
在输出的巨长一串参数里,睁大眼睛找 这个字样。如果有,恭喜你,神功已成。如果没有……你可能需要重新编译安装Nginx,或者找找包含此模块的发行版。
--with-stream
第二步:配置你的“保安工作手册”
Nginx的配置文件通常是 。我们需要在
/etc/nginx/nginx.conf块的同级,配置一个
http块。
stream
# /etc/nginx/nginx.conf
# 这里是处理HTTP流量的传统区域,我们今天不碰它
http {
... # 你原来的各种server、location配置
}
# 注意!这里是和 http 平级的 stream 区域,我们的“保安”在这里上班
stream {
# 定义一个上游服务器组,名字叫 redis_backend
upstream redis_backend {
server 192.168.1.100:6379 max_fails=3 fail_timeout=30s;
}
# 定义一个Stream类型的服务器,用来监听外部请求
server {
# 监听本机的6390端口。注意!我们不用6379,用一个新的。
listen 6390;
# 重要:指定协议是TCP,Redis用的是TCP协议
proxy_pass redis_backend;
# 可选:设置代理连接的超时时间
proxy_timeout 3s;
proxy_connect_timeout 2s;
# 可选:开启日志,记录TCP连接信息
# 需要你在 http 块里定义一个合适的 log_format,比如 ‘main’
access_log /var/log/nginx/redis_stream.access.log main;
# 可选:简单的访问控制,只允许你的办公IP连接
# allow 202.96.134.100;
# deny all;
}
# 你还可以继续配置其他服务的代理,比如MySQL
# server {
# listen 33060;
# proxy_pass mysql_backend;
# ...
# }
}
配置文件解读:
:这是Stream功能的“大本营”,所有传输层代理配置都写在这里。
stream { ... }:定义后端真正的服务地址。这里可以写多个
upstream redis_backend { ... }做负载均衡。
server:在Stream语境下,这个
server { ... }块代表一个“监听器”。
server:让Nginx在公网IP的6390端口上“竖起耳朵”监听。我们故意不用Redis的默认6379端口,这也是一种简单的安全规避。
listen 6390:核心指令,把所有发到本机6390端口的TCP流量,原封不动地转发给
proxy_pass redis_backend里定义的
upstream。
192.168.1.100:6379:如果连接空闲超过这个时间,Nginx会主动关闭它。
proxy_timeout:记录下来谁连过,非常重要。
access_log
第三步:让“保安”上岗
保存配置文件。测试配置文件语法是否正确:
nginx -t
如果显示 ,就可以继续。
syntax is ok, test is successful
重载Nginx配置,让它生效:
systemctl reload nginx # 或者 service nginx reload
第四步:验收“保安”的工作成果
现在,不要再去直连你的 了。你的Redis客户端应该连接的是:
192.168.1.100:6379
主机:
123.123.123.123
端口:
6390
你可以用 测试一下:
redis-cli
redis-cli -h 123.123.123.123 -p 6390
然后输入 ,如果返回
ping,恭喜你!你的“隐形保安”正式上岗了!
PONG
你的连接路径现在是:。那个危险的6379端口,已经从公网上“消失”了。
你的电脑 -> Nginx公网IP:6390 -> 内网Redis服务器:6379
第五章:高级玩法与避坑指南
1. 负载均衡实战:
如果你的Redis有多个从节点做读扩展,可以这样配置:
stream {
upstream redis_cluster {
server 192.168.1.100:6379 weight=2; # 主库,权重高一点
server 192.168.1.101:6379; # 从库1
server 192.168.1.102:6379; # 从库2
}
server {
listen 6390;
proxy_pass redis_cluster;
}
}
2. SSL/TLS加密:
假设你要代理一个需要SSL的MySQL:
stream {
upstream mysql_backend {
server 192.168.1.200:3306;
}
server {
listen 33060 ssl; # 监听时开启SSL
proxy_pass mysql_backend;
# 指定SSL证书和密钥
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
# 如果你的MySQL也要求SSL,那么Nginx到后端也需要配置
# proxy_ssl on;
# proxy_ssl_certificate ...;
}
}
3. 常见大坑:
权限问题:在Linux上,Nginx默认可能没有权限绑定1024以下的端口(如80, 443)。如果你要用低端口,需要给Nginx主进程相应的权限,或者用等工具。协议混淆:一定要记住,
authbind块和
stream块是平级的,不能嵌套。
http里的
http、
server等指令在
location里是无效的。性能调优:对于高并发场景,你可能需要调整
stream、
worker_processes,以及在
worker_connections块内使用
stream 等指令来优化TCP代理性能。
proxy_buffer_size
第六章:总结——让“裸奔”成为历史
好了,到这里,相信你已经对Nginx Stream模块有了一个全新且深入的认识。它绝不是Nginx的一个小插件,而是一个能够极大提升你架构安全性和灵活性的神兵利器。
从今天起,忘掉那种把数据库端口直接暴露在公网上的危险操作吧。给你的核心服务请一位像Nginx Stream这样靠谱的“隐形保安”。
它不关心你后端跑的是什么协议(Redis, MySQL, SSH……),它只负责一件事:安全、可靠、高效地把网络数据包送到该去的地方。这种“专注”,正是它强大和优雅的地方。
行动起来,点开你的服务器,修改一下Nginx配置,让你家的服务端口,从此告别“裸奔”时代!
















暂无评论内容