NginxStream-配置转发FTP
# Nginx 配置转发FTP
nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx⽀持四层负载均衡。默认编译的时候该模块并未编译进去,需要编译的时候添加**--with-stream**,使其⽀持stream代理。
# 安装stream模块
(1)查看已安装Nginx编译参数
[root@test11 local]# nginx -V
nginx version: nginx/1.15.9
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module
2
3
4
5
6
(2)下载对应版本Nginx源码并重新编译
下载地址:http://nginx.org/en/download.html (opens new window)
wget http://nginx.org/download/nginx-1.15.9.tar.gz
tar -zxvf nginx-1.15.9.tar.gz
cd nginx-1.15.9
2
编译
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-stream --with-stream_realip_module --without-http_rewrite_module
(3)执行make
注意:只执行make,不执行make install ,执行make install 会把原有nginx目录覆盖
make
(4)关闭Nginx服务
nginx -s stop
(5)替换原有的nginx启动文件
# 备份原有的启动文件
cp /usr/bin/nginx /usr/bin/nginx-no-stream
# 将我们编译生成的nginx文件复制过去,并覆盖
cp /usr/local/src/nginx-1.15.9/objs/nginx /usr/bin/nginx
cp:是否覆盖"/usr/bin/nginx"? y
# 确认是否覆盖成功
[root@test11 nginx-1.15.9]# md5sum /usr/local/src/nginx-1.15.9/objs/nginx /usr/bin/nginx
90ac5d23625cfc5557084fe8d94d6a7f /usr/local/src/nginx-1.15.9/objs/nginx
90ac5d23625cfc5557084fe8d94d6a7f /usr/bin/nginx
2
3
4
5
6
7
8
9
10
(6)配置成功
# 配置转发FTP
参考:https://blog.51cto.com/u_15127630/2738588 (opens new window)
(0)配置思路
先了解下FTP的连接方式
FTP连接模式具有两种,分别为主动模式(PORT)以及被动模式(PASV)。
主动模式:
当FTP客户端以主动模式连接服务端时,客户端以动态选择的端口号向服务器的命令端口发起连接;
连接建立后,用户在发出列目录或传输文件的命令后,会要求建立数据连接;
FTP客户端在控制连接上发出主动模式指令,告知服务器客户端的数据连接端口号;
服务端收到指令后,会使用20号端口连接客户端指定的数据连接端口号,从而建立数据连接。
被动模式:
被动模式的连接过程与主动模式类似,区别点在于客户端发出列目录或传输文件的命令后,客户端会发送PASV指令至服务端;
服务端收到PASV指令后,告知客户端服务端的数据连接IP地址和端口号;
客户端根据返回的服务端数据连接IP和端口号,发起数据连接。
存在问题 & 解决思路:
当前,客户端需要通过Nginx代理方能访问FTP服务端。通过Nginx stream可以实现控制命令的转发,但是对于客户端和服务端协商的数据连接,较难实现代理。
不过查阅相关文档,vsftpd支持设置数据连接的端口范围,亦支持设置数据连接的IP。
因此,我们可以指定vsftpd模式为被动模式(默认即为被动模式),设置数据连接IP地址为Nginx代理地址,合理设置数据连接端口范围(Nginx监听本地此端口范围内数据)。当ftp客户端与vsftpd服务端协商数据连接后,ftp客户端根据数据连接IP(已设置为Nginx代理地址)以及端口号发起连接(实际连接至Nginx服务器),Nginx将此端口上监听的数据转发至vsftpd对应的数据端口。
(1)FTP配置
# 开启pasv模式
pasv_enable=YES
# pasv模式下,数据连接最小端口号
pasv_min_port=50000
# pasv模式下,数据连接最大端口号
pasv_max_port=50002
# 关闭pasv模式下,关闭对IP地址的检查,此检查确保控制连接和数据连接来自同一IP
pasv_promiscuous=YES
2
3
4
5
6
7
8
pasv_promiscuous关闭存在安全隐患; 在实际组网情况下,Nginx转发时可设置保留源IP信息,但是客户端与服务端无法直接访问,因此只能放弃保留源IP信息。
(2)重启vsftpd
systemctl restart vsftpd
(3)Nginx配置
这里需要将ftp配置的数据连接端口号范围内的端口都配置转发,即pasv_max_port
与pasv_max_port
之间的端口
stream{
# FTP端口转发
upstream ftp{
hash $remote_addr consistent;
server 10.8.10.16:21;
}
server {
listen 18989;
proxy_connect_timeout 300s;
proxy_timeout 300s;
proxy_pass ftp;
}
# 转发客户端发送到Nginx代理机的数据连接
server {
listen 50000;
proxy_pass ftp_pasv1;
}
upstream ftp_pasv1 {
server 10.8.10.16:50000;
}
# 转发客户端发送到Nginx代理机的数据连接
server {
listen 50002;
proxy_pass ftp_pasv3;
}
upstream ftp_pasv3 {
server 10.8.10.16:50002;
}
# 转发客户端发送到Nginx代理机的数据连接
server {
listen 50001;
proxy_pass ftp_pasv2;
}
upstream ftp_pasv2 {
server 10.8.10.16:50001;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(3)重启Nginx
nginx -s reload
(4)配置完成
访问Nginx配置的地址可以成功获取FTP信息