FTPES – Reutilización de sesión requerida

Por lo tanto, estoy tratando de conectarme a un servidor ftp para obtener listados de directorios y descargar archivos. Pero el primer comando después de la función prot_p () está generando una excepción – Produciendo estos errores desde el registro:

*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  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 

Aquí está el código:

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

Quiero hacer esto de forma segura, por lo tanto, uso de FTP sobre TLS Explicit. Tengo la idea de que puedo necesitar manipular algunas configuraciones en la clase Socket referenciada por FTPLib. Cambiar la configuración en el servidor no es una posibilidad. He probado el servidor con éxito con el cliente FileZilla, una versión anterior de WinSCP estaba generando el mismo error, aunque una actualización a la versión más reciente lo solucionó.

¿Algunas ideas?

Ahora se puede arreglar fácilmente para Python 3.6+ por esta clase (descendiente de FTP_TLS):

 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 

Parece más probable que se trate de un problema vsftpd que ftplib, ya que mencionas que una actualización a la versión más reciente solucionó el problema.

Siempre que no pueda tocar la configuración del servidor, la FTP_TLS puede ayudar a resolver su problema, aunque en mi opinión es un HACK , haciendo referencia a esta pregunta y respuesta de SO sobre el problema de la conexión FTP con TLS de Python . También puedes echar un vistazo a este problema de Python 19500 :

“Es razonable que el servidor insista en que la conexión de datos utiliza una sesión en caché TLS. Esto podría ser un caché de datos anteriores.
Conexión o de una conexión de control despejada. Si esta es la razón de la negativa a permitir la transferencia de datos, entonces la respuesta ‘522’
debe indicar esto

Nota: Esto tiene un impacto importante en el diseño del cliente, pero permite
servidores para minimizar los ciclos utilizados durante la negociación TLS por
negarse a realizar una negociación completa con un previamente
cliente autenticado “.

Parece que el servidor vsftpd implementó exactamente eso al imponer la “reutilización de la sesión SSL entre el control y la conexión de datos”.

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

En cuanto al origen de la biblioteca central de Python, ftplib.py, no se tiene en cuenta la idea de la reutilización de la sesión SSL entre la conexión de datos y la conexión de control (corríjame si me equivoco aquí. He intentado FTP_TLS.transfercmd (cmd [, rest]) ¶, no funcionó).

Este problema está bien documentado en otros clientes FTP que admiten FTPS, IE WinSCP: https://winscp.net/tracker/668

Ver archivo de registro de prueba adjunto. Un servidor vsftpd con “require_ssl_reuse” establecido en verdadero en vsftpd.conf haría el truco y se puede reproducir.

Espero que esto ayude.