在ftp被动模式下 ftp_put 上传文件

来源:互联网 发布:汽车配件淘宝店铺名字 编辑:程序博客网 时间:2024/04/30 00:03

前提:公司需求做一个内部图片管理系统,管理系统(下面称为 s1)和图片文件服务器(下面称为 s2)分2个服务器放置。都是linux系统的。

用户需求通过管理系统上传图片至另一个服务器中储存。使用php 中  ftp_put为核心去做功能。

但是做到最后。卡在一个问题上, s2安装完 vsftp服务后,如果开启了pasv被动连接功能,并设置  ftp_pasv($conn,ture)//打开被动传输模式,ftp_put/ftp_get 可以正常上传/下载数据。

 ftp_pasv($conn,false) 或不设置 //关闭被动传输模式,使用主动传输模式 ,则上传文件超时,s2多出一个大小为0的文件。


由于公司对于S2服务器的安全要求性非常高,如果要开启PASV,需要开启S2的相应端口。安全性相对较低,所以考虑用 port主动模式去实现。

看了不少资料,了解到:ftp连接默认的是使用 port主动模式。而s2 是开启了 vsftp(默认开启port模式),为什么提交数据会失败呢?


为此,特地研究了下 关于ftp的pasv 和 port 2种模式的差别。(下面这一段转载,感谢原作者的详细描述,让我如醍醐灌顶)


(一)主动FTP
主动方式的FTP是这样的:客户端从一个任意的非特权端口N(N>1024)连接到FTP服务器的命令端口,也就是21端口。然后客户端开始 监听端口N+1,并发送FTP命令“port N+1”到FTP服务器。接着服务器会从它自己的数据端口(20)连接到客户端指定的数据端口(N+1)。


针对FTP服务器前面的防火墙来说,必须允许以下通讯才能支持主动方式FTP:
1. 任何大于1024的端口到FTP服务器的21端口。(客户端初始化的连接)
2. FTP服务器的21端口到大于1024的端口。 (服务器响应客户端的控制端口)
3. FTP服务器的20端口到大于1024的端口。(服务器端初始化数据连接到客户端的数据端口)
4. 大于1024端口到FTP服务器的20端口(客户端发送ACK响应到服务器的数据端口)



(二)被动FTP
为了解决服务器发起到客户的连接的问题,人们开发了一种不同的FTP连接方式。这就是所谓的被动方式,或者叫做PASV,当客户端通知服务器它处于 被动模式时才启用。
在被动方式FTP中,命令连接和数据连接都由客户端发起,这样就可以解决从服务器到客户端的数据端口的入方向连接被防火墙过滤掉的问题。
当开启一个 FTP连接时,客户端打开两个任意的非特权本地端口(N > 1024和N+1)。第一个端口连接服务器的21端口,但与主动方式的FTP不同,客户端不会提交PORT命令并允许服务器来回连它的数据端口,而是提交 PASV命令。这样做的结果是服务器会开启一个任意的非特权端口(P > 1024),并发送PORT P命令给客户端。然后客户端发起从本地端口N+1到服务器的端口P的连接用来传送数据。


对于服务器端的防火墙来说,必须允许下面的通讯才能支持被动方式的FTP:
1. 从任何大于1024的端口到服务器的21端口 (客户端初始化的连接)
2. 服务器的21端口到任何大于1024的端口 (服务器响应到客户端的控制端口的连接)
3. 从任何大于1024端口到服务器的大于1024端口 (客户端初始化数据连接到服务器指定的任意端口)
4. 服务器的大于1024端口到远程的大于1024的端口(服务器发送ACK响应和数据到客户端的数据端口)



以上关于主动和被动FTP的解释,可以简单概括为以下两点:
1、主动FTP:
命令连接:客户端 >1024端口 -> 服务器 21端口
数据连接:客户端 >1024端口 1024端口 -> 服务器 21端口
数据连接:客户端 >1024端口 -> 服务器 >1024端口


(三) 主动与被动FTP优缺点:
主动FTP对FTP服务器的管理有利,但对客户端的管理不利。因为FTP服务器企图与客户端的高位随机端口建立连接,而这个端口很有可能被客户端的 防火墙阻塞掉。被动FTP对FTP客户端的管理有利,但对服务器端的管理不利。因为客户端要与服务器端建立两个连接,其中一个连到一个高位随机端口,而这 个端口很有可能被服务器端的防火墙阻塞掉。
幸运的是,有折衷的办法。既然FTP服务器的管理员需要他们的服务器有最多的客户连接,那么必须得支持被动FTP。我们可以通过为FTP服务器指定 一个有 限的端口范围来减小服务器高位端口的暴露。这样,不在这个范围的任何端口会被服务器的防火墙阻塞。虽然这没有消除所有针对服务器的危险,但它大大减少了危 险。


总结来说:port主动模式下,客户端(对应我的S1)通过端口 N>1024  发送port信息到服务器(对应我的S2),并开启端口N+1等待,服务器通过端口20主动连接客户端N+1;(命令连接由客户端发起,数据连接由服务器发起,至客户端,所以可能会被客户端防火墙拦截数据)

pasv被动模式下,客户端通过端口 N>1024  发送pasv信息到服务器,并开启端口N+1等待,服务器打开端口M>1024,并发送信息给客户端,客户端通过N+1主动连接到服务器M端口;(2次连接都由客户端发起,所以只需要考虑服务器的防火墙设置)


我尝试关闭S2的防火墙,ftp_put仍然失败。尝试关闭S1防火墙,ftp_put竟然成功了。就是说S1的防火墙拦截了数据传输中某个步骤的端口导致的。

综合 上面得到的结论,我了解到应该是在服务器通过端口20主动连接客户端这个步骤被防火墙拦截了,因为我S1并没有打开20端口。

我对S1的防火墙添加下行:

-A INPUT -p tcp -m tcp --dport 20 -j ACCEPT

测试还是失败。换成:

-A INPUT -p tcp -m tcp --sport 20 -j ACCEPT

测试成功!!

由于是要开启从20端口进来的信息,所以要用 SPORT。

1 0
原创粉丝点击