Nginx实现Tcp连接内部映射跳转

钢枪 1年前 ⋅ 1074 阅读

不知道大家是否遇到过类似场景:有个接口是通过socket通信,对端服务器访问存在IP限制,只好通过跳板机,因为它具备访问对端服务器的权限。nginx1.9开始支持tcp层的转发,通过stream实现的,而socket也是基于tcp通信。

我现在遇到的情况是:我买了一个阿里云服务器,赠送了一个云数据库,不知道大家有没有用功阿里云的云数据。有点小坑,是映射的域名

是不是有点坑! 

想了一些办法,最后发现可以通过Nginx 实现映射!这里就用到了 nginx stream模块

安装nginx,stream模块默认不安装的,需要手动添加参数:–with-stream,官方下载地址:download,根据自己系统版本选择nginx1.9或以上版本
nginx.conf 配置,参考说明:ngx_stream_core_module
nginx.conf (请注意,stream配置不能放到http内,即不能放到/etc/nginx/conf.d/,因为stream是通过tcp层转发,而不是http转发) 否则会报 nginx: [emerg] "stream" directive is not allowed here in /usr/local/nginx/conf/nginx.conf:74

 

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;
    }
}

 我的是这么配置的

stream{
	server{
                # 配置本机暴露端口
		listen 3307; 
                # 配置数据库的ip和端口
		proxy_pass rm-8vb0nshxm67ft3epm58870.mysql.zhangbei.rds.aliyuncs.com:3306;

	}
}

编译nginx平滑添加stream模块

1、操作背景

      wget http://nginx.org/download/nginx-1.13.7.tar.gz

操作系统版本:CentOS Linux release 7.4.1708 (Core)
nginx版本:1.13.4

nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx支持四层负载均衡。默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream,使其支持stream代理。

2、nginx编译添加stream模块

2.1、查看原nginx编译参数

[root@test-server sbin]# nginx -V
nginx version: nginx/1.13.4
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/usr/local/nginx/tmp/client/ --http-proxy-temp-path=/usr/local/nginx/tmp/proxy/ --http-fastcgi-temp-path=/usr/local/nginx/tmp/fcgi/ --with-poll_module --with-file-aio --with-http_realip_module --with-http_addition_module --with-http_addition_module --with-http_random_index_module --with-http_stub_status_module --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/nginx/scgi_temp --with-pcre=/usr/local/src/pcre-8.41

2.2、添加stream模块进行重新编译

1
2
3
4
此处nginx源码目录为:/usr/local/src/nginx-1.13.4,即为编译命令执行目录。
编译命令如下:
./configure --with-stream
 

2.3、进行make操作

此处nginx源码目录为:/usr/local/src/nginx-1.13.4,即为编译命令执行目录。
make

此处一定不能使用make install命令,执行该命令会将原有nginx目录进行覆盖。

3、关停nginx同时复制新的nginx启动文件

1
2
3
4
5
6
7
8
关闭nginx服务
先杀掉Nginx:ps -ef | grep nginx | grep -v grep | awk '{print $2}' | xargs kill -9
 
备份原有nginx二进制文件。
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-no-strem
 
复制新编译好的nginx二进制文件。从此处nginx源码目录为:/usr/local/nginx-1.13.4。即为编译命令执行目录。
cp ./objs/nginx /usr/local/nginx/sbin/nginx

4、启动测试 

启动nginx。
systemctl start nginx

查看nginx模块信息。
nginx -V
nginx version: nginx/1.13.4
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/usr/local/nginx/tmp/client/ --http-proxy-temp-path=/usr/local/nginx/tmp/proxy/ --http-fastcgi-temp-path=/usr/local/nginx/tmp/fcgi/ --with-poll_module --with-file-aio --with-http_realip_module --with-http_addition_module --with-http_addition_module --with-http_random_index_module --with-http_stub_status_module --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/nginx/scgi_temp --with-pcre=/usr/local/src/pcre-8.41 --with-stream

可以看到stream模块已经编译到nginx内了。
复制代码

5、nginx stream模块配置简析

复制代码
stream段的配置要与http段在同级目录。此处引用的为官方nginx说明配置。
stream { upstream backend { hash $remote_addr consistent; server backend1.example.com:12345 weight=5; server 127.0.0.1:12345 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; } upstream dns { server 192.168.0.1:53535; server dns.example.com:53; } server { listen 12345; proxy_connect_timeout 1s; proxy_timeout 3s; proxy_pass backend; } server { listen 127.0.0.1:53 udp reuseport; proxy_timeout 20s; proxy_pass dns; } server { listen [::1]:12345; proxy_pass unix:/tmp/stream.socket; } }

举一个栗子,利用stream模块代理 zk服务的2181端口。

1
2
3
4
5
6
7
8
9
10
11
stream {
    upstream zk_server {
        server 172.16.3.8:2181 weight=5;
    }
    server {
        listen 2181 tcp;
        proxy_responses 1;
        proxy_timeout 20s;
        proxy_pass zk_server;
    }
}

 

6、编译nignx systemd服务启动文件

[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]

 


全部评论: 0

    我有话说: