sla*_*lat 6 python ftp ftps ftplib python-2.7
所以,我正在尝试连接到ftp服务器以获取目录列表和下载文件.但是prot_p()函数之后的第一个命令引发了异常 - 从日志中产生这些错误:
*get* '150 Here comes the directory listing.\r\n'
*resp* '150 Here comes the directory listing.'
*get* '522 SSL connection failed; session reuse required: see require_ssl_reuse
option in vsftpd.conf man page\r\n'
*resp* '522 SSL connection failed; session reuse required: see require_ssl_reuse
option in vsftpd.conf man page'
Traceback (most recent call last):
File "C:\temp\download.py", line 29, in <module>
files = ftps.dir()
File "C:\Python27\lib\ftplib.py", line 522, in dir
self.retrlines(cmd, func)
File "C:\Python27\lib\ftplib.py", line 725, in retrlines
return self.voidresp()
File "C:\Python27\lib\ftplib.py", line 224, in voidresp
resp = self.getresp()
File "C:\Python27\lib\ftplib.py", line 219, in getresp
raise error_perm, resp
ftplib.error_perm: 522 SSL connection failed; session reuse required: see requir
e_ssl_reuse option in vsftpd.conf man page
Run Code Online (Sandbox Code Playgroud)
这是代码:
from ftplib import FTP_TLS
import os
import socket
host = 'example.com'
port = 34567
user = 'user1'
passwd = 'pass123'
acct = 'Normal'
ftps = FTP_TLS()
ftps.set_debuglevel(2)
ftps.connect(host, port)
print(ftps.getwelcome())
print(ftps.sock)
ftps.auth()
ftps.login(user, passwd, acct)
ftps.set_pasv(True)
ftps.prot_p()
print('Current directory:')
print(ftps.pwd())
files = ftps.dir()
ftps.quit()
Run Code Online (Sandbox Code Playgroud)
我想安全地这样做,因此使用FTP over TLS Explicit.我有一个想法,我可能需要操作FTPLib引用的Socket类中的一些设置.不可能更改服务器上的设置.我已经使用FileZilla客户端成功测试了服务器,旧版本的WinSCP引发了同样的错误 - 尽管升级到最新版本修复了它.
有任何想法吗?
hyn*_*cer 11
现在可以通过此类(FTP_TLS的后代)轻松修复Python 3.6+:
class MyFTP_TLS(ftplib.FTP_TLS):
"""Explicit FTPS, with shared TLS session"""
def ntransfercmd(self, cmd, rest=None):
conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = self.context.wrap_socket(conn,
server_hostname=self.host,
session=self.sock.session) # this is the fix
return conn, size
Run Code Online (Sandbox Code Playgroud)
它看起来比ftplib更可能是vsftpd问题,因为你提到升级到最新版本修复了问题.
如果你无法触及服务器的设置,FTP_TLS
那么对它进行子类化可能有助于解决你的问题,虽然在我看来这是一个非常HACK,参考这个SO问题并解答Python FTP TLS连接问题.你也可以看看这个python bug问题19500:
"服务器坚持认为数据连接使用TLS缓存会话是合理的.这可能是先前数据
连接或清除控制连接的缓存.如果这是拒绝允许数据传输的原因,然后'522'回复
应该表明这一点.注意:这对客户端设计有重要影响,但允许
服务器通过
拒绝与先前经过
身份验证的客户端执行完全协商来最小化TLS协商期间使用的周期.似乎vsftpd服务器通过强制执行"控制和数据连接之间的SSL会话重用"来实现这一点.
http://scarybeastsecurity.blogspot.com/2009/02/vsftpd-210-released.html
看看Python核心库ftplib.py的来源,没有任何关于数据连接与控制连接之间的SSL会话重用的想法(如果我在这里错了,请纠正我.我试过FTP_TLS.transfercmd(cmd) [,休息]),没有用).
在支持FTPS,IE WinSCP的其他FTP客户端上有详细记录此问题:https://winscp.net/tracker/668
请参阅附加的测试日志文件 在vsftpd.conf中将"require_ssl_reuse"设置为true的vsftpd服务器可以完成这一操作并可以重现.
希望这可以帮助.