使用Nginx进行TCP/UDP/IPV6端口转发【原创】
nginx安装添加stream模块
先确定nginx安装时,编译的时候添加了--with-stream
这个模块支持。nginx 版本 >=1.9才支持。
# ../sbin/nginx -V nginx version: nginx/1.10.3 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-pcre --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-stream
修改nginx配置文件
比如10.32.7.76有访问10.35.30.121的3306端口权限。10.45.23.47也想访问,利用nginx转发tcp。在10.32.7.76安装nginx转发访问10.35.30.121的3306端口-->10.32.7.76的端口12345
在nginx.conf最后一行添加
stream { #将12345端口转发到10.35.30.121的3306端口 server { listen 12345; proxy_connect_timeout 5s; proxy_timeout 20s; proxy_pass 10.35.30.121:3306; } }
如果报错nginx: [emerg] "stream" directive is not allowed,请注意如果你用的是nginx的1.10版本的stream,那么http段和steam段是平行的
nginx reload操作。
测试端口转发
服务器10.45.23.47访问10.35.30.121端口3306是不通的,也访问不了数据库
现在访问转发服务器10.32.7.76的端口12345,测试一下
访问成功。
nginx转发UPD、IPV6
在nginx.conf
添加如下配置,并使用nginx -s reload
重载nginx使其生效,同时注意防火墙/安全组放行对应的端口。
stream { #将12345端口转发到192.168.1.23的3306端口 server { listen 12345; proxy_connect_timeout 5s; proxy_timeout 20s; proxy_pass 192.168.1.23:3306; } #将udp 53端口转发到192.168.1.23 53端口 server { listen 53 udp reuseport; proxy_timeout 20s; proxy_pass 192.168.1.23:53; } #ipv4转发到ipv6 server { listen 9135; proxy_connect_timeout 10s; proxy_timeout 30s; proxy_pass [2607:fcd0:107:3cc::1]:9135; } }
- listen:后面填写源端口(也就是当前服务器端口),默认协议为TCP,可以指定为UDP协议
- proxy_connect_timeout:连接超时时间
- proxy_timeout:超时时间
- proxy_pass:填写转发目标的IP及端口号
注意:nginx可以将IPV4的数据包转发到IPV6,IPV6的IP需要使用[]
括起来。
nginx转发并记录日志
stream {
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log logs/tcp-access.log proxy ;
upstream kams{
hash $remote_addr consistent; # 保持 session 不变,四层开启
server 192.168.35.119:8080 max_fails=3 fail_timeout=20s;
server 192.168.35.120:8080 max_fails=3 fail_timeout=20s weight=10;
}
server {
listen 6080;
proxy_connect_timeout 10s;
proxy_timeout 30s;
proxy_pass kams;
}
}
- 这个模块提供一致性hash作为负载均衡算法。
- 该模块通过使用客户端信息(如:$ip, $uri, $args等变量)作为参数,使用一致性hash算法将客户端映射到后端机器
- 如果后端机器宕机,这请求会被迁移到其他机器
server
_id_ 字段,如果配置id字段,则使用id字段作为server标识,否则使用server ip和端口作为server标识,- 使用id字段可以手动设置server的标识,比如一台机器的ip或者端口变化,id仍然可以表示这台机器。使用id字段
- 可以减低增减服务器时hash的波动。
server
weight 字段,作为server权重,对应虚拟节点数目- 具体算法,将每个server虚拟成n个节点,均匀分布到hash环上,每次请求,根据配置的参数计算出一个hash值,在hash环
- 上查找离这个hash最近的虚拟节点,对应的server作为该次请求的后端机器。
- 该模块可以根据配置参数采取不同的方式将请求均匀映射到后端机器,比如:
consistent_hash $remote_addr
:可以根据客户端ip映射consistent_hash $request_uri
: 根据客户端请求的uri映射consistent_hash $args
:根据客户端携带的参数进行映射
总结
目前能实现端口转发的工具大致有:rinetd、SSH、iptables、nginx、haproxy,其中rinetd配置最为简单,但不支持UDP转发,并且该软件已经好几年未更新,如果您服务器上已经安装了nginx,不妨用nginx做端口转发。
参考
使用Nginx进行TCP/UDP端口转发 - 小z博客
https://www.xiaoz.me/archives/10578
nginx 转发tcp连接 - imcati - 博客园
https://www.cnblogs.com/imcati/p/11717802.html
(3条消息) Nginx 配置TCP代理转发_jeikerxiao-CSDN博客_nginx tcp代理
https://blog.csdn.net/jeikerxiao/article/details/87863341
nginx报错”stream”/”upstream” directive is not allowed 错误 – 慢慢赚钱博客
https://moneyslow.com/nginx%E6%8A%A5%E9%94%99stream-upstream-directive-is-not-allowed-%E9%94%99%E8%AF%AF.html
一致性hash模块 - The Tengine Web Server
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html
nginx upstream 一致性哈希模块 – 运维生存时间
http://www.ttlsa.com/nginx/nginx-upstream-consistent-hash-module/
openresty(nginx) 配置 stream 转发 - 码农教程
http://www.manongjc.com/detail/25-oxormpgvyfjuinu.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?