简体   繁体   English

Python:nlst()使用FTP_TLS挂在“清单上来了”

[英]Python: nlst() hangs on “here come the listing” by using FTP_TLS

I am been stuck in this for couple of days. 我被困在这几天。 I am using python to connect to my server by using FTP_TLS . 我正在使用python通过使用FTP_TLS连接到我的服务器。 I have seen many post on this error and had done almost all the changes but still nno luck. 我已经看到过很多关于此错误的文章,并做了几乎所有的更改,但还是很不幸。 I can connect to my server, make directories but when it comes on the listing ftps.nlst() , ftps.retrlines('LIST') or ftps.dir() all got stuck/hangs at: 我可以连接到服务器,创建目录,但是当它出现在清单ftps.nlst()ftps.retrlines('LIST')ftps.dir()都卡在/挂在:

150 Here comes the directory listing. 150这是目录列表。

Below is my server vsftpd configuration file: 以下是我的服务器vsftpd配置文件:

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
chroot_local_user=YES
allow_writeable_chroot=YES
pam_service_name=vsftpd
pasv_enable=YES
pasv_promiscuous=YES
pasv_min_port=40000
pasv_max_port=55999
pasv_address = ip_address
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH
user_sub_token=abc
local_root=/home/abc/ftp
user_sub_token=username
local_root=/path/to/username/images
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

Debug Log is: 调试日志为:

*get* '220 (vsFTPd 3.0.3)\n'
*resp* '220 (vsFTPd 3.0.3)'
*welcome* '220 (vsFTPd 3.0.3)'
getwelcome >>>220 (vsFTPd 3.0.3)
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketType.SOCK_STREAM, proto=6, laddr=('192.168.81.11', 59660), raddr=('81.19.0.237', 21)>
*cmd* 'AUTH SSL'
*put* 'AUTH SSL\r\n'
*get* '234 Proceed with negotiation.\n'
*resp* '234 Proceed with negotiation.'
*cmd* 'USER username'
*put* 'USER username\r\n'
*get* '331 Please specify the password.\n'
*resp* '331 Please specify the password.'
*cmd* 'PASS ***************'
*put* 'PASS ***************\r\n'
*get* '230 Login successful.\n'
*resp* '230 Login successful.'
*cmd* 'PBSZ 0'
*put* 'PBSZ 0\r\n'
*get* '200 PBSZ set to 0.\n'
*resp* '200 PBSZ set to 0.'
*cmd* 'PROT P'
*put* 'PROT P\r\n'
*get* '200 PROT now Private.\n'
*resp* '200 PROT now Private.'
Current directory:
*cmd* 'PWD'
*put* 'PWD\r\n'
*get* '257 "/" is the current directory\n'
*resp* '257 "/" is the current directory'
>>>> /
*cmd* 'PWD'
*put* 'PWD\r\n'
*get* '257 "/" is the current directory\n'
*resp* '257 "/" is the current directory'
<<<>>>257 "/" is the current directory
*cmd* 'CWD /uploads/'
*put* 'CWD /uploads/\r\n'
*get* '250 Directory successfully changed.\n'
*resp* '250 Directory successfully changed.'
*cmd* 'TYPE A'
*put* 'TYPE A\r\n'
*get* '200 Switching to ASCII mode.\n'
*resp* '200 Switching to ASCII mode.'
*cmd* 'EPSV'
*put* 'EPSV\r\n'
*get* '229 Entering Extended Passive Mode (|||44788|)\n'
*resp* '229 Entering Extended Passive Mode (|||44788|)'
*cmd* 'NLST'
*put* 'NLST\r\n'
*get* '150 Here comes the directory listing.\n'
*resp* '150 Here comes the directory listing.'
^C 
Traceback (most recent call last):
File "config/timelapse_test.py", line 45, in <module>
    filenames = ftps.nlst()
File "/usr/lib/python3.4/ftplib.py", line 558, in nlst
    self.retrlines(cmd, files.append)
File "/usr/lib/python3.4/ftplib.py", line 467, in retrlines
    with self.transfercmd(cmd) as conn, \
File "/usr/lib/python3.4/ftplib.py", line 398, in transfercmd
    return self.ntransfercmd(cmd, rest)[0]
File "/usr/lib/python3.4/ftplib.py", line 793, in ntransfercmd
    server_hostname=server_hostname)
File "/usr/lib/python3.4/ssl.py", line 364, in wrap_socket
    _context=self)
File "/usr/lib/python3.4/ssl.py", line 577, in __init__
    self.do_handshake()
File "/usr/lib/python3.4/ssl.py", line 804, in do_handshake
    self._sslobj.do_handshake()
KeyboardInterrupt

also in my code i have placed: 在我的代码中我也放置了:

ftps.ssl_version = ssl.PROTOCOL_SSLv23;
ftps.passive = True
ftps.prot_p()

Can someone guide me where i am doing things wrong? 有人可以指导我做错事情的地方吗?

Thanks 谢谢

The problem is probably that the FTP server requires that the TLS session in the new data channel is the same as the control channel. 问题可能出在FTP服务器要求新数据通道中的TLS会话与控制通道相同。 This has not been fixed in Python 3.7. 这在Python 3.7中尚未修复。 Subclass ftplib.FTP_TLS as in the solution found here https://stackoverflow.com/a/43301750 with a small fix by me: 在解决方案中找到ftplib.FTP_TLS子类,在这里找到https://stackoverflow.com/a/43301750 ,我做了一个小修复:

import ftplib


class ReusedSslSocket(SSLSocket):
    def unwrap(self):
        pass


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)  # reuses TLS session            
            conn.__class__ = ReusedSslSocket  # we should not close reused ssl socket when file transfers finish
        return conn, size

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM