【问题标题】:FTPS with Python ftplib - Session reuse required带有 Python ftplib 的 FTPS - 需要会话重用
【发布时间】:2013-01-17 12:34:53
【问题描述】:

所以,我正在尝试连接到 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

代码如下:

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()

我想安全地执行此操作,因此使用 FTP over TLS Explicit。我的想法是我可能需要操作 ftplib 引用的 Socket 类中的一些设置。更改服务器上的设置是不可能的。我已经使用 FileZilla 客户端成功测试了服务器,旧版本的 WinSCP 也出现了同样的错误 - 尽管升级到最新版本修复了它。

有什么想法吗?

【问题讨论】:

    标签: python ftp python-2.7 ftps ftplib


    【解决方案1】:

    当您提到升级到最新版本解决了该问题时,它看起来比 ftplib 更可能是 vsftpd 问题。

    如果您无法触摸服务器的设置,则将 FTP_TLS 子类化可能有助于解决您的问题,尽管在我看来这是一个非常HACK,参考这个 SO question & answers @987654321 @。你也可以从这个python bug issue 19500看看:

    " 服务器坚持数据连接是合理的 使用 TLS 缓存会话。这可能是以前数据的缓存
    连接或清除的控制连接。如果是这个原因 对于拒绝允许数据传输,然后是“522”回复
    应该指出这一点。

    注意:这对客户端设计有重要影响,但允许
    服务器以最小化 TLS 协商期间使用的周期
    拒绝与之前的
    经过身份验证的客户端。”

    看来 vsftpd 服务器通过强制执行完全实现了这一点 “控制和数据连接之间的 SSL 会话重用”。

    http://scarybeastsecurity.blogspot.com/2009/02/vsftpd-210-released.html

    查看Python核心库ftplib.py的源码,没有 任何关于数据连接之间的 SSL 会话重用的想法 与控制连接(如果我在这里错了,请纠正我。我试过了 FTP_TLS.transfercmd(cmd[, rest])¶,没用)。

    这个问题在其他支持 FTPS 的 FTP 客户端上有很好的记录, IE。 WinSCP:https://winscp.net/tracker/668

    请参阅附加的测试日志文件。带有“require_ssl_reuse”的 vsftpd 服务器 在 vsftpd.conf 中设置为 true 就可以了,并且可以被复制。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。我从来没有控制过 FTP 服务器配置,因此失去了访问权限,无法测试这个解决方案。
    • @slat,您只能在客户端实施第一个解决方案。不幸的是,您无法将其测试为失去访问权限。那么我猜没有赏金:)
    【解决方案2】:

    现在可以通过这个类(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
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 2021-09-04
    • 2015-01-05
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多