我有一个需要连接到FTPS服务器,我能够成功地连接使用lftp。然而,当我尝试使用Python ftplib.FTP_TLS时,它超时了,堆栈跟踪显示它正在等待服务器发送欢迎消息或类似消息。有谁知道问题是什么以及如何解决?我想知道是否有一些需要做的服务器端,但如何来lftp客户端工作正常。任何帮助都是非常感谢的。
下面是堆栈跟踪:
ftp = ftplib.FTP_TLS()
ftp.connect(cfg.HOST, cfg.PORT, timeout=60)
File "C:\Users\username\Softwares\Python27\lib\ftplib.py", line 135, in connect
self.welcome = self.getresp()
File "C:\Users\username\Softwares\Python27\lib\ftplib.py", line 210, in getresp
resp = self.getmultiline()
File "C:\Users\username\Softwares\Python27\lib\ftplib.py", line 196, in getmultiline
line = self.getline()
File "C:\Users\username\Softwares\Python27\lib\ftplib.py", line 183, in getline
line = self.file.readline()
File "C:\Users\username\Softwares\Python27\lib\socket.py", line 447, in readline
data = self._sock.recv(self._rbufsize)
socket.timeout: timed out
使用lftp成功登录到相同的ftp服务器:
$ lftp
lftp :~> open ftps://ip_address:990
lftp ip_address:~> set ftps:initial-prot P
lftp ip_address:~> login ftps_user_id ftps_user_passwd
lftp sftp_user_id@ip_address:~> ls
ls: Fatal error: SSL_connect: self signed certificate
lftp ftps_user_id@ip_address:~> set ssl:verif-certificate off
lftp ftps_user_id@ip_address:~> ls
lftp ftps_user_id@ip_address:/>
顺便说一句,我正在使用Python 2.7.3。我用谷歌搜索了很多,但没有找到任何有用的东西。
我仍然有这个问题,感谢如果有人可以帮助。在仔细查看FTP.connect()时,连接到服务器不是问题,但从服务器获得确认(或欢迎消息)是一个问题。lftp没有这个问题,FileZilla也没有任何问题,就像这里的日志一样-
Status: Connecting to xx.xx.xx.xxx:990...
Status: Connection established, initializing TLS...
Status: Verifying certificate...
Status: TLS/SSL connection established, waiting for welcome message...
Response: 220- Vous allez vous connecter sur un serveur prive
Response: 220- Seules les personnes habilitees y sont autorisees
Response: 220 Les contrevenants s'exposent aux poursuites prevues par la loi.
Command: USER xxxxxxxxxxxxx
Response: 331 Password required for xxxxxxxxxxxxx.
Command: PASS **********
Response: 230 Login OK. Proceed.
Command: PBSZ 0
Response: 200 PBSZ Command OK. Protection buffer size set to 0.
Command: PROT P
Response: 200 PROT Command OK. Using Private data connection
Status: Connected
Status: Retrieving directory listing...
Command: PWD
Response: 257 "/" is current folder.
Command: TYPE I
Response: 200 Type set to I.
Command: PASV
Response: 227 Entering Passive Mode (81,93,20,199,4,206).
Command: MLSD
Response: 150 Opening BINARY mode data connection for MLSD /.
Response: 226 Transfer complete. 0 bytes transferred. 0 bps.
Status: Directory listing successful
7条答案
按热度按时间oogrdqng1#
扩展到目前为止已经提出的解决方案,问题是隐式FTPS连接需要在我们有机会调用login()之前自动对套接字进行ssl Package 。人们提出的很多子类都是在connect方法的上下文中这样做的,我们可以更普遍地通过修改self.sock的get/set来管理这一点,并在set上自动换行:
使用方法基本上与标准FTP_TLS类相同:
w1e3prcc2#
同样的问题我已经研究了半天,终于弄明白了。
对于隐式FTP TLS/SSL(默认端口990),我们的客户端程序必须在创建套接字后立即构建TLS/SSL连接。但是python的类
FTP_TLS
不会从类FTP中重新加载connect函数。我们需要修复它:这个派生类重新加载connect函数,并围绕TLS的套接字构建 Package 器。成功连接并登录FTP服务器后,您需要调用:**
FTP_TLS.prot_p()
**在执行任何FTP命令之前!希望对你有帮助哦~
3z6pesqy3#
这里有一个更“工业化”的实现。
让我们注意到,在前面的示例中,名为'context'的属性在init中丢失。
下面的代码在Python 2.7和Python 3中都能完美运行。
代码
使用示例
输出示例
fnx2tebb4#
扩展NERV的响应-这对我帮助很大,下面是我如何能够解决我的问题与端口990上的隐式TLS连接需要身份验证。
文件名:ImplicitTLS.py
然后从我的主应用程序中,我这样做了:
就这样,我可以下载文件,等等。 prop 去NERV的原始答案。
lo8azlld5#
NERV的回答和布拉德德克尔的样本真的很有帮助。为他们点赞。他们节省了我的时间。
不幸的是,最初它对我不起作用。
在我的例子中,一旦我从
ssl.wrap_socket
方法中删除了ssl_version
参数,连接就可以工作了。此外,要向服务器发送任何命令,我必须覆盖FTP_TLS
类中的ntransfercmd
方法,并删除ssl_version
参数。这就是我的代码:
强制性样本:
tuwxkamq6#
我在使用隐式TLS的FTP服务器上也遇到了同样的问题(也是被动模式)。我犯了很多错误:
提出的解决方案。为了记录在案,我基于@乔治Leslie-Waksman的解决方案是:
新颖之处在于
ntransfercmd
覆盖。然后,它的使用类似于
ftplib.FTP_TLS
(在以前的帖子中有很多例子)。覆盖
connect
而不是使用sock
属性/ setter也可以工作。klr1opcd7#
我知道这个线程是很老,ftp是不流行,因为它曾经是,但无论如何,在情况下,它可以帮助任何人,我想作出额外的贡献。我遇到了一个类似的情况,试图连接到ftp服务器使用隐式(端口990)ftp在被动模式。在这种情况下,在协商初始连接之后,服务器通常会提供一个新的主机IP地址和端口,可能与用于进行初始连接的IP地址和端口不同,实际的数据传输应该通过该IP地址和端口进行。没什么大不了的,ftp客户端,包括python,可以处理这个问题,只有这个特定的服务器提供了一个不可路由的(可能是防火墙内部的)IP地址。我注意到FileZilla连接没有问题,但python ftplib不能。然后我遇到了这个线程:
How to replace a non routable IP address with server address on ftplib
这给了我线索使用Grzegorz Wierzowiecki方法论,我扩展了该线程中提到的方法,并提出了这个,解决了我的问题。
然后代码被这样调用
我想可以用一个标识不可路由地址的IF语句来 Package 主机被更改回的行,有点像这样: