[环境]:
linux主机:华为企业云
ftp服务端:vsftpd
客户端:ftp命令行工具,安卓端ES文件浏览器
[现象]:
在ES文件浏览器中,使用被动方式没法连接,使用主动方式可以连接,但是没法列出文件(图形界面的工具有一些细节没法看到,反正就是不正常)。
使用ftp的命令行连接时也不正常,主动方式时:ls命令提示 Failed to establish connection。被动方式时:ls命令执行后卡在 Entering Passive Mode,最后提示Connnection timed out。
[解决]:
1. 尝试在server端执行ftp命令,发现能正常使用。考虑到是vsftp的配置问题,通过查看手册,将pasv_enable 和 port_enable 都设置为YES,重试,问题依旧。
2. 查看file transfer protocol 的wiki,重新梳理了一下主动方式和被动方式的区别。感觉问题出在防火墙或者nat上。
3. 发现在华为企业云的管理控制台中,有个安全组的设置,里面可以控制出站和入站流量。
4. 分析,因为我用的client大部分都是在nat里边的,所以主动方式不可取,因为就算我告诉了server我client的端口号,由于我在nat里,server还是无法与我建立连接。
so,应该选择被动方式。但是我怎么知道server端会监听哪个端口呢?允许所有端口的入站流量肯定不可取。vsftpd配置文件中提供了 pasv_max_port 和 pasv_min_port 这两个配置命令。然后,用这两个配置命令限制一下端口的范围,然后在华为企业云的管理控制台中配置一下这些端口的入站规则。
5. client尝试使用passive的方式连接server,成功。
[进一步验证]
1. 在华为企业云的管理控制台中关闭之前开启的用于数据连接的端口入站规则。
2. 使用telnet连接server的21端口,输入user 和 pass命令登录。
3. 发送port命令,发现然后就卡住了,(这个可能是两个原因,nat或者我没监听我用port命令发送的端口。不过我猜测还是nat的原因)
4. 关闭后重新进行第1步和第2步。
5. 发送pasv命令,服务端返回一个六元组,重新开启一个终端(假设叫做终端2),在终端2中使用telnet登录 server,端口为六元组中的端口。
6. 连接建立不了,因为我们在第1步中拒绝了这个端口的入站流量。
7. 在华为企业云的管理控制台中打开用于数据连接的端口入站规则。
8. 重复第2步和第5步,发现数据连接能成功建立。
9. 在控制连接的终端上发送LIST命令,发现在终端2中,server端返回了LIST命令的执行结果。
10. 通过验证,可以知道之前出现的问题源自server端不让数据连接的流量入站。
[总结]
现在复习一下主动方式(active)和被动方式(passive)的区别:
先要知道,ftp协议分为控制连接和数据连接,对于控制连接的建立,这两种方式是一致的,client用本机的某个端口,连接server的21端口(ftp server端的默认端口,该端口在server端可修改)。
对于数据连接:
在active方式中,client通过控制连接发送 PORT M 命令,其中,M是端口号。表示client监听了M端口,由server主动与该端口建立数据连接。
在passive方式中,client通过控制连接发送 PASV 命令,server端收到该命令之后,会返回一个六元组,类似(192,168,1,1,4,20)。表示了服务端的ip和监听端口号,ip地址由前四个数确定,在本例中,端口号=4*256+20。感觉该六元组中的ip应该会被 client忽略,client与server建立数据连接使用的是控制连接中server的ip和六元组中的端口号。