vsftpd过不了NAT

本文涉及的产品
云防火墙,500元 1000GB
公网NAT网关,每月750个小时 15CU
简介:

 VSFTPD与iptables NAT的设置详解 


本文关键字:vsftp iptables NAT xinetd redirect 主动模式 被动模式

 

       FTP协议的特点就是数据流端口与控制流端口分离,这使得管理员在设置防火墙规则时,需要多考虑一些因素.同时由于FTP服务器本身的重要性和不安全性,许多管理员想将其置于防火墙机器后,这样一来就更麻烦了.通常是客户端能登录上服务器,但无法列出目录,无法传输数据等等,让许多新手管理员摸不清头脑,到论坛里撒分“跪求”解决办法.其实这并不是想像的那么难,看了本文后,你将明白这一切.


第一部分.理解FTP的主动模式与被动模式
       其实网上关于FTP传输的主被动模式的讲解已很多,要想让客户机与服务器之间畅通无阻的传输数据,必须首先理解它们的传输原理,这样我们遇到问题时才可以对症下药.我们通过抓包分析来理解其转输过程.

       主动模式(Port模式)
       主动模式的传输数据流程如下(服务器ip:192.168.200.1,客户端ip:192.168.200.8):
               1..192.168.200.8.55722 > 192.168.200.1.ftp: PORT 192,168,200,8,178,210
               2..192.168.200.1.ftp > 192.168.200.8.55722: 200 PORT command successful. Consider using PASV.
               3..192.168.200.8.55722 > 192.168.200.1.ftp: ......ACK
               4..192.168.200.8.55722 > 192.168.200.1.ftp: LIST
               5..192.168.200.1.ftp-data > 192.168.200.8.45778:......SYN
               6..192.168.200.8.45778 > 192.168.200.1.ftp-data: ......SYN.ACK
               7..192.168.200.1.ftp-data > 192.168.200.8.45778: ......ACK
               8..192.168.200.1.ftp > 192.168.200.8.55722: 150 Here comes the directory listing.
               9..192.168.200.1.ftp-data > 192.168.200.8.45778:
                       -rw-r--r--    1 0        0               6 Mar 23 08:53 filetest
                       drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
       从上面的数据得出主动模式的传输过程如下:
               A.(第1行)客户端向服务器申请PORT模式的数据传输,并通过PORT命令告知服务器"我的IP是192.168.200.8,我开放端口45778等你".
                       (45778是通过PORT命令后的最后两个数字算出来的.178*256 + 210 = 45778)
               B.(第2行)服务器在检查所收到的PORT命令的语法和安全性等因素后,向客户端告知PORT命令成功,并同时建议客户端考虑使用PASV.
                       (PASV就是我们接下来要讲的被动模式)
               C.(第3行)客户端确认收到从服务器传来的信息并应答.
               D.(第4行)客户端向服务器申请列出目录信息的数据.
               E.(第5,6,7行)服务器收到客户端的申请后,主动用自己的20端口去连接客户端的45778端口,以便传送数据.
                       (注意:这是重要的地方,所谓主动模式,就是指服务器从自己的数据端口主动去连接客户端)
               F.(第8行)当服务器与客户端的数据流端口成功连接后,服务器便通过控制端口21向客户发送信息:你需要的目录列表传来了.
               G.(第9行)服务器通过数据流端口,将用户所需要的目录数据信息发向客户端.
       在整个通信过程中,服务器仅用了两个固定的低端端口,即控制端口21(ftp)和数据端口20(ftp-data),防火墙规则很好设置,只需放开这两个端口就行.而客户端就没那么幸运了,动态的开放了一个高端端口等待连接,这让处于局域网内部,通过共享同一IP上网的用户而言基本没辙.但是,有其它的解决办法么?有!就是我们接下来要谈到的被动模式.

       被动模式(Passive模式)
       被动模式的传输数据流程如下(服务器ip:192.168.200.1,客户端ip:192.168.200.8):
               1..192.168.200.8.40137 > 192.168.200.1.ftp: PASV
               2..192.168.200.1.ftp > 192.168.200.8.40137: Entering Passive Mode (192,168,200,1,11,187)
               3..192.168.200.8.40137 > 192.168.200.1.ftp: ......ACK
               4..192.168.200.8.43422 > 192.168.200.1.3003: ......SYN
               5..192.168.200.1.3003 > 192.168.200.8.43422: ......SYN.ACK
               6..192.168.200.8.43422 > 192.168.200.1.3003: ......ACK
               7..192.168.200.8.40137 > 192.168.200.1.ftp: LIST
               8..192.168.200.1.ftp > 192.168.200.8.40137: 150 Here comes the directory listing.
               9..192.168.200.1.3003 > 192.168.200.8.43422:
                       -rw-r--r--    1 0        0               6 Mar 23 08:53 filetest
                       drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
       从上面的数据得出主动模式的传输教程如下:
               A.(第1行)客户端向服务器申请PASV模式的数据传输.
               B.(第2行)服务器新开放一个数据流端口,进入监听模式.并告诉客户"你连接192.168.200.1吧,我开放了3003端口等你呢".
                       (3003端口是通过第2行最后两个数字计算出来的,11*256 + 187 = 3003)
               C.(第3行)客户端确认收到从服务器传来的信息并应答.
               D.(第4,5,6行)当客户端获知服务器已新开了一个数据流端口让自己去连接后,便从本地随机选择一个端口去连接服务器指定的端口,以便传送数据.
                       (注意:这是重要的地方,与主动模式不一样,服务器不会去主动连接客户端,而是新开一个端口,被动的等客户端来连接,这就是所谓的被动模式)
               E.(第7行)当客户端与服务器的数据流端口成功连接后,客户端便向服务器申请列出目录信息的数据.
               F.(第8行)服务器便通过控制端口21向客户发送信息:你需要的目录列表传来了.
               G.(第9行)服务器通过数据流端口,将用户所需要的目录数据信息发向客户端.
       在整个通信过程中,客户端都是主动去连接服务器,并没有开放端口被连接,这确实为客户端的防火墙减轻了不少麻烦.但麻烦消失了么?没有!被动模式只是把麻烦"移"到了服务器上而已,服务器则需要动态的开一个高端端口来传输数据,怎样处理这个端口是我们面临着的困难.不过不用怕,天才的程序员们为我们想好了一切,我们只需要按我们的要求设置参数就行.接下来让我们分析各种可能存在的情况.


第二部分.服务器相关设置实战
       (注:本文所有例子均采用RHEL5+VSFTPD服务器,且默认客户端无防火墙.)
       机器布局如下:
               |客户机|:::::::::::::::::|LINUX网关|------|VSFTPD服务器|
               客户机的IP: 10.10.10.10/8
               LINUX网关IP: 10.10.10.20/8,  192.168.1.1
               VSFTPD服务器IP: 192.168.1.8/24

 

       1.配置VSFTPD服务器,配置文件如下:
               listen=yes
               anonymous_enable=yes

               port_enable=yes
               connect_from_port_20=yes

               pasv_enable=yes
               pasv_min_port=10000
               pasv_max_port=10100
       这是一个简单的VSFTPD配置,第一部分允许匿名用户访问,第二部分声明允许主动模式,第三部分声明允许被动模式,并把服务器开放的被动连接的端口限制在10000-10100范围以内,以便我们设置相应的防火墙规则.我在内网测试了,可以正常使用

 

       2.网关设置
       首先开启转发功能.
               #echo 1 > /proc/sys/net/ipv4/ip_forward
       再设置相关NAT规则.
               #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 20:21 -j SNAT --to 10.10.10.20
               #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 10000:10100 -j SNAT --to 10.10.10.20
               #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 21 -j DNAT --to-destination 192.168.1.8
               #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 10000:10100 -j DNAT --to-destination 192.168.1.8
       前两条规则把内网的FTP服务器的相关端口的数据转发出去.
       后两条规则把外网对网关的相关端口的数据转发给FTP服务器.

 

       3.客户端测试
       登录10.10.10.10,测试结果如下:
               [root@X ~]# ftp 10.10.10.20
               Connected to 10.10.10.20 (10.10.10.20).
               220 (vsFTPd 2.0.5)
               Name (10.10.10.20:root): anonymous
               331 Please specify the password.
               Password:
               230 Login successful.
               Remote system type is UNIX.
               Using binary mode to transfer files.
               ftp> passive //关掉被动模式,我们先测试主动模式.
               Passive mode off.
               ftp> ls
               200 PORT command successful. Consider using PASV.
               150 Here comes the directory listing.
               -rw-r--r--    1 0        0              13 May 06 20:24 filetest
               drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
               226 Directory send OK.
       (到此,我们发现主动模式是配置无误了,可以成功连接.可是在上部分我们说过,主动模式的可应用性不高,接着我们再测试一下被动模式)
               ftp> passive
               Passive mode on.
               ftp> ls
               227 Entering Passive Mode (192,168,1,8,39,109)
               ftp: connect: Connection timed out
       当我输入ls命令后,系统返回了一条信息"227 Entering Passive Mode (192,168,1,8,39,109)".接着我等啊等,等来的是不幸的消息,系统提醒我连接超时了.
       这是怎么回事儿?回过头去看看第一部分被动模式传输过程就知道了,原来我们是"第D步"失败了!
       当然会失败啊!服务器告诉我们,可以去连接192.168.1.8的39*256+109=10093端口以便传输数据,可是192.168.1.8对客户端10.10.10.10来说是不可见的,它在10.10.10.20后面躲猫猫呢.
       此时,我们的解决办法有两个.其一,截获服务器传向客户端的数据(被动模式传输过程的第B步),修改相关数据,以欺骗客户端让它连接服务器的网关10.10.10.20,因为服务器192.168.1.8在10.10.10.20背后,对客户端来说是不可见的.其二,由服务器亲自出面发布"假"信息欺骗客户端,达到同样的效果.
       这两种解决办法都很好实现,关于第一种,我们在网关服务器上加载两个模块,以截获并修改数据.登录10.10.10.20操作如下:
               #modprobe ip_nat_ftp
               #modprobe ip_conntrack_ftp
       然后我们再在客户端上测试.
               ftp> ls
               227 Entering Passive Mode (10,10,10,20,39,108)
               150 Here comes the directory listing.
               -rw-r--r--    1 0        0              13 May 06 20:24 filetest
               drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
               226 Directory send OK.
       怎么样,一次性就成功了吧.我们看到第二行的信息,ip已被修改成10.10.10.20,客户端在收到这信息后,就会去连接10.10.10.20,然后经过10.10.10.20的转发,于是我们理所当然的成功了.
       再看看第二种解决办法,我们怎样让服务器出面发布"假"消息去欺骗客户端呢?vsftp的作者早想到这点了,我们只需要在vsftpd的配置文件中加入如下两行即可.
               pasv_addr_resolve=yes        //允许vsftpd去欺骗客户
               pasv_address=10.10.10.20        //让vsftpd以这个地址去欺骗客户
       重启vsftpd后,我们再从客户端测试发现也可以正常使用.

 

       4.如果使用了xinetd的redirect怎么办?
       就在我以为这篇挫文完成了的时候,一个朋友在QQ群里寻求帮助,他的情况是没有使用NAT,而是使用了xined的redirect(重定向)功能,始终没有调试成功.他在网关上做了如下的事情.
       A.打开转发功能
                #echo 1 > /proc/sys/net/ipv4/ip_forward
       B.添加了/etc/xinetd.d/vsftpd文件,内容如下:
               service ftp
               {
                       disable         = no
                       wait            = no
                       socket_type     = stream
                       user            = root
                       log_on_failure  += USERID
                       log_on_success  += PID HOST EXIT
                       bind            = 10.10.10.20
                       redirect        = 192.168.1.8 21
               }
       并启动xinetd监听相应的端口.
       C.然后在客户端测试.
               # ftp 10.10.10.20
               Connected to 10.10.10.20 (10.10.10.20).
               220 (vsFTPd 2.0.5)
               Name (10.10.10.20:root): anonymous
               331 Please specify the password.
               Password:
               230 Login successful.
               Remote system type is UNIX.
               Using binary mode to transfer files.
               ftp> passive
               Passive mode off.
               ftp> ls
               500 Illegal PORT command.
               ftp: bind: Address already in use
               ftp> passive
               Passive mode on.
               ftp> ls
               227 Entering Passive Mode (192,168,1,8,39,65)
               ftp: connect: Connection timed out
       正如你所看到的那样,客户端能成功连接到服务器,可是当想从服务器列出数据的时候,无论主动模式还是被动模式都失败了.这是正常的,我们只用xinetd重定向了21端口,却没有对可能要开启的数据端口做仍何操作,所以,我们还得借助NAT把数据端口的事儿搞定.登录10.10.10.20,执行如下操作
               #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 20 -j SNAT --to 10.10.10.20
               #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 10000:10100 -j SNAT --to 10.10.10.20
               #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 10000:10100 -j DNAT --to-destination 192.168.1.8
       再登录客户端连接测试.郁闷,与先前的测试一样,不论是主动模式还是被动模式,都失败.
       控制端口能连接上,数据端口按我们设置的规则也能连接上,可为什么还是失败?难道xinetd的redirect有什么特殊的地方,上网关服务器一看,还真是有特殊的情况.
       在10.10.10.20上执行netstat -antup,显示结果如下:
               tcp        0      0 10.10.10.20:21              10.10.10.10:43039           ESTABLISHED 2303/xinetd
               tcp        0      0 192.168.1.1:45459           192.168.1.8:21              ESTABLISHED 2303/xinetd
       原来xinetd的转发机制是:先开启21端口让客户机连接,自己再开启一个端口去连接内部网络的FTP服务器,然后自己做中间人,中转数据.
       如果这样的话,vsftpd服务器会"发现"是192.168.1.1(网关服务器的内网ip)在与它连接并发送控制指令的,这在接下来进行数据传输的时候会遇到困难,请看第一部分主动模式传输过程的第B步.客户端通过网关xinetd模式向服务器转达的PORT命令,通不过vsftpd的安全性检查,因为vsftpd服务器只知道192.168.1.1在与它连接.就好像张三给你说,你把这份重要的数据给李四送去吧,这可是十分不安全的啊,vsftpd服务器号称最安全的FTP服务器,可不是那么"笨"的.不过我们可以将它变"笨",只需给它加个参数,让它不检查安全性即可.
       我们在vsftpd的配置文件中加上如下一行:
               port_promiscuous=yes
       重启vsftpd服务器,接着在客户端测试:
               ftp> passive
               Passive mode off.
               ftp> ls
               200 PORT command successful. Consider using PASV.
               150 Here comes the directory listing.
               -rw-r--r--    1 0        0              13 May 06 20:24 filetest
               drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
       主动模式测试成功,可被动模式还是不行,原因上一小节已经讲了.由于xinetd的redirect机制与NAT没关系,先前的第一种通过截获数据并修改数据包的做法行不通了,只得改改服务器的参数,让服务器去忽悠客户端吧.
       同样,在服务器上加上这两行参数:
               pasv_addr_resolve=yes        //允许vsftpd去欺骗客户
               pasv_address=10.10.10.20        //让vsftpd以这个地址去欺骗客户
       重启vsftpd服务器,在客户端用被动模式测试连接.
               ftp> ls
               227 Entering Passive Mode (10,10,10,20,39,21)
               425 Security: Bad IP connecting.
       崩溃了吧,仍然不能连接.看到Security这个提示信息,我们就明白了,仍然是vsftpd的安全选项在作怪.它正在与192.168.1.1交流着呢,突然来了一个10.10.10.10要来连接它,它当然不愿意啦,前文已说过,号称最安全的FTP服务器,可不是那么"笨"的.没办法,再次将它变笨吧.给它再设置一个参数,在vsftpd的配置文件中加上如下一行:
               pasv_promiscuous=yes
       再登录客户端测试一下,发现可以正常使用了,大功告成.
       
       5.写在最后
       FTP是在70年代设计出来的,当时的互联网是一个封闭的网络,与现代网络环境还是有很大的差异,现代网络中不管你使用Port模式还是Passive模式,都可能产生问题.看完本文后,希望你能有所收获,如果发现本文有错误,请回复或者直接加我QQ(864235428)联系.同时我再说下,xinetd的redirect是一个很优秀的功能,但他不适合用来处理FTP,数据端口是动态的,它无能为力,还得需要iptables,相反,由于它需要建立两个连接的这种机制,使得我们一再要更改vsftpd关于安全性的参数,确实有点儿得不偿失,如果你看完我的建议,仍然坚持要使用它,那祝你好运.

       欢迎访问http://huabo2008.cublog.cn/




     本文转自rshare 51CTO博客,原文链接:http://blog.51cto.com/1364952/1969802,如需转载请自行联系原作者





相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
Linux
vsftpd 修改指定端口
vsftpd的一般默认端口为21,一般来说端口21不太方便开放,因此多数时间需要修改指定默认的端口。
2201 0
|
8月前
|
网络协议 安全 Linux
配置vsftpd服务
FTP是TCP/IP协议族中的应用层协议,用于可靠地传输文件,基于C/S架构,使用20(数据)和21(命令)端口。有两种传输模式:主动模式,客户端告知服务器数据端口,服务器发起连接;被动模式,服务器响应客户端的PASV命令,客户端建立数据连接。安装Linux的vsftpd服务涉及`yum install vsftpd`,创建用户,重启服务并设置开机启动。配置文件`vsftpd.conf`可调整访问权限和行为。通过FTP命令如`help`,`get`,`put`进行文件操作。匿名用户模式可允许无密码访问,需修改配置文件开启。
226 0
|
存储 安全 算法
最简单的方法理解vsftpd和tftp
最简单的方法理解vsftpd和tftp
202 0
|
Linux 网络安全 开发工具
Linux防火墙操作firewall、iptable
Linux防火墙操作firewall、iptable
193 0
|
网络协议 网络安全 开发工具
|
网络协议 数据安全/隐私保护 安全
vsftpd虚拟用户配置,SLB代理vsftpd
如何配置vsftpd的虚拟用户,代理vsftpd增加安全性。
2537 0
|
安全 Shell Linux