问题描述
我需要连接到使用lftp可以成功连接的FTPS服务器。但是,当我尝试使用Python ftplib.FTP_TLS时,超时,堆栈跟踪显示它正在等待服务器发送欢迎消息或类似消息。有谁知道问题是什么以及如何克服?我想知道是否有需要在服务器端完成的事情,但是如何让lftp客户端正常工作。任何帮助都非常感谢。
以下是堆栈跟踪:
ftp = ftplib.FTP_TLS()
ftp.connect(cfg.HOST,cfg.PORT,timeout = 60)
文件C :\Users\username\Softwares\Python27\lib\ftplib.py,第135行,连接
self.welcome = self.getresp()
文件C:\\ \\用户名\软件\Python27\lib\ftplib.py,第210行,在getresp
resp = self.getmultiline()
文件C:\ Users \用户名\ Software \Python27\lib\ftplib.py,第196行,在getmultiline
line = self.getline()
文件C:\ Users \\\\\\\\\\ Software \Python27\lib\ftplib.py,第183行,在getline
line = self.file.readline()
文件C:\ Users \\\\\\\\ Software \\\' Python27 \lib\socket.py,行447,在readline
数据中= self._sock.recv(self._rbufsize)
socket.timeout:超时
使用lftp到同一ftps服务器的成功登录:
$ b
$ lftp
lftp: 〜>打开ftps:// ip_address:990
lftp ip_address:〜> set ftps:initial-prot P
lftp ip_address:〜>登录ftps_user_id ftps_user_passwd
lftp sftp_user_id @ ip_address:〜> ls
ls:致命错误:SSL_connect:自签名证书
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。我使用Google进行了很多搜索,但没有发现任何有用的信息。
我仍然遇到这个问题,非常感谢有人能帮忙。仔细查看FTP.connect()与服务器的连接不成问题,但从服务器获取确认(或欢迎消息)是一个问题。 lftp没有这个问题,FileZilla也没有任何问题,或者在这里的日志 -
状态:连接到xx.xx.xx.xxx:990 ...
状态:建立连接,初始化TLS ...
状态:正在验证证书...
状态:TLS /建立SSL连接,等待欢迎消息...
响应:220- Vous allez vous connecter sur un serveur prive
响应:220- Seules les personnes habilitees y sont autorisees
响应:220 Les contrevenants s'exposent aux poursuites prevues par la loi。
命令:USER xxxxxxxxxxxxx
响应:331 xxxxxxxxxxxxx需要密码。
命令:PASS **********
响应:230登录确定。继续。
命令:PBSZ 0
响应:200 PBSZ命令OK。保护缓冲区大小设置为0.
命令:PROT P
响应:200 PROT命令确定。使用私人数据连接
状态:已连接
状态:正在检索目录列表...
命令:PWD
响应:257/是当前文件夹。
命令:类型I
响应:200类型设置为I.
命令:PASV
响应:227进入被动模式(81,93,20,199,4,206)。
命令:MLSD
响应:150打开MLSD /的BINARY模式数据连接。
回应:226转账完成。传输了0个字节。 0 bps。
状态:目录列表成功
对于隐式FTP TLS / SSL(默认端口990),我们的客户端程序必须构建一个在创建套接字后立即建立TLS / SSL连接。但是python的类 FTP_TLS
不会从类FTP重载 connect 函数。我们需要修正它:
class tyFTP(ftplib.FTP_TLS):
def __init __(self,
host ='',
user ='',
passwd ='',
acct ='',
keyfile = None,
certfile = None,
timeout = 60):
ftplib.FTP_TLS .__ init __(self,
host = host,
user = user,
passwd = passwd,
acct = acct,
keyfile = keyfile,
certfile = certfile,
timeout = timeout)
def connect(self,host ='',port = 0,timeout = -999):
连接到主机,参数是:
- host:要连接的主机名(字符串,默认以前的主机)
- port:连接的端口到(整数,默认以前的端口)
如果host!= '':
self.host =主机
如果端口> 0:
self.port = port
如果超时!= -999:
self.timeout = timeout
try:
self.sock = socket.create_connection(( self.host,self.port),self.timeout)
self.af = self.sock.family
#添加此行!
self.sock = ssl.wrap_socket(self.sock,
self.keyfile,
self.certfile,
ssl_version = ssl.PROTOCOL_TLSv1)
#add end
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
例外情况为e:
print(e)
返回self.welcome
此派生类重新加载连接函数和构建TLS插座周围的包装。成功连接并登录FTP服务器后,您需要在执行任何FTP命令之前调用: FTP_TLS.prot_p()
!
希望这可以帮助^ _ ^
I have a need to connect to FTPS server to which I am able to connect successfully using lftp. However, when I try with Python ftplib.FTP_TLS, it times out, the stack trace shows that it is waiting for the server to send welcome message or like. Does anyone know what the issue is and how to overcome? I wonder if there is something needs to be done on server side, but how come lftp client is working fine. Any help is greatly appreciated.
Here is the stack trace:
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
A successful login using lftp to the same ftps server:
$ 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:/>
BTW, I am using Python 2.7.3. I did quite a bit of search using Google but have not found anything helpful.
I am still having this issue, appreciate if someone can help. On looking closely the FTP.connect() the connection to server is not a problem but getting acknowledgement (or the welcome message) from server is an issue. lftp does not have this issue and FileZilla does not have any issue either as in the log here -
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
I've worked on the same problem for half a day and finally figured it out.
For the implicit FTP TLS/SSL(defualt port 990), our client program must build a TLS/SSL connection right after the socket is created. But python's class FTP_TLS
doesn't reload the connect function from class FTP. We need to fix it:
class tyFTP(ftplib.FTP_TLS):
def __init__(self,
host='',
user='',
passwd='',
acct='',
keyfile=None,
certfile=None,
timeout=60):
ftplib.FTP_TLS.__init__(self,
host=host,
user=user,
passwd=passwd,
acct=acct,
keyfile=keyfile,
certfile=certfile,
timeout=timeout)
def connect(self, host='', port=0, timeout=-999):
"""Connect to host. Arguments are:
- host: hostname to connect to (string, default previous host)
- port: port to connect to (integer, default previous port)
"""
if host != '':
self.host = host
if port > 0:
self.port = port
if timeout != -999:
self.timeout = timeout
try:
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
# add this line!!!
self.sock = ssl.wrap_socket(self.sock,
self.keyfile,
self.certfile,
ssl_version=ssl.PROTOCOL_TLSv1)
# add end
self.file = self.sock.makefile('rb')
self.welcome = self.getresp()
except Exception as e:
print(e)
return self.welcome
This derived class reloads the connect function and builds a wrapper around the socket to TLS. After you successfully connect and login to FTP server, you need to call: FTP_TLS.prot_p()
before executing any FTP command!
Hope this will help ^_^
这篇关于Python FTP隐式TLS连接问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!