第一部分.理解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上网的用户而言基本没辙.但是,有其它的解 决办法么?有!就是我们接下来要谈到的被动模式.
主动模式的传输数据流程如下(服务器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行)服务器通过数据流端口,将用户所需要的目录数据信息发向客户端.
在整个通信过程中,客户端都是主动去连接服务器,并没有开放端口被连接,这确实为客户端的防火墙减轻了不少麻烦.但麻烦消失了么?没有!被动模式只是把麻 烦"移"到了服务器上而已,服务器则需要动态的开一个高端端口来传输数据,怎样处理这个端口是我们面临着的困难.不过不用怕,天才的程序员们为我们想好了 一切,我们只需要按我们的要求设置参数就行.接下来让我们分析各种可能存在的情况.
被动模式的传输数据流程如下(服务器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
listen=yes
anonymous_enable=yes
port_enable=yes
connect_from_port_20=yes
connect_from_port_20=yes
pasv_enable=yes
pasv_min_port=10000
pasv_max_port=10100
这是一个简单的VSFTPD配置,第一部分允许匿名用户访问,第二部分声明允许主动模式,第三部分声明允许被动模式,并把服务器开放的被动连接的端口限制 在10000-10100范围以内,以便我们设置相应的防火墙规则.我在内网测试了,可以正常使用,更详细的VSFTPD配置可查看man文档或访问http://blog.chinaunix.net/u3/94705/showart_1917230.html.
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服务器.
首先开启转发功能.
#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后,我们再从客户端测试发现也可以正常使用.
登录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后,我们再从客户端测试发现也可以正常使用.
安全性的参数,确实有点儿得不偿失,如果你看完我的建议,仍然坚持要使用它,那祝你好运.
Comments 1 条评论
博客作者 Faris
来看看~~不错