在尝试通过SSL / TLS使用FTP将文件推送到远程ftp服务器时,出现一个奇怪的错误。我找不到在线解决方案的痕迹:/ 请帮忙。
这是我的代码:
from ftplib import FTP_TLS
import sys, os
root = "\\home\\user\\test.txt"
dest = "/Destdir"
ftps = FTP_TLS('xxx.xxx.xxx.xxx')
ftps.set_debuglevel(1)
ftps.set_pasv(False)
ftps.connect(port=21, timeout=80)
ftps.login('user', 'pass')
ftps.prot_p()
ftps.ccc()
try:
ftps.cwd(dest)
except Exception as e:
print(e)
try:
file = open('test.txt', 'rb')
ftps.storbinary('STOR test.txt', file)
file.close()
except Exception as e:
print(e)
ftps.close()
这是脚本的输出:
*resp* '220 nas FTP server ready.'
*cmd* 'AUTH TLS'
*resp* '234 AUTH TLS command successful.'
*cmd* 'USER user'
*resp* '331 Password required for user.'
*cmd* 'PASS **********'
*resp* '230 User user logged in.'
*cmd* 'PBSZ 0'
*resp* '200 PBSZ command successful (PBSZ=0).'
*cmd* 'PROT P'
*resp* '200 Protection level set to Private.'
*cmd* 'CCC'
*resp* '200 Clearing control channel protection.'
*cmd* 'CWD /Destdir'
*resp* '250 CWD command successful.'
*cmd* 'TYPE I'
*resp* '200 Type set to I.'
*cmd* 'PORT 10,10,99,11,220,211'
*resp* '200 PORT command successful.'
*cmd* 'STOR test.txt'
*resp* "150 Opening BINARY mode data connection for 'test.txt'."
_ssl.c:704: The handshake operation timed out
由于与远程FTP服务器的连接很好,所以我认为这不是防火墙问题。
注意: 远程FTP服务器是Synology NAS,具有最新的操作系统。
EDIT_0:
另一种使用被动模式的尝试得到了结果:
*resp* '220 nas FTP server ready.'
*cmd* 'AUTH TLS'
*resp* '234 AUTH TLS command successful.'
*cmd* 'USER user'
*resp* '331 Password required for user.'
*cmd* 'PASS **********'
*resp* '230 User user logged in.'
*cmd* 'PBSZ 0'
*resp* '200 PBSZ command successful (PBSZ=0).'
*cmd* 'PROT P'
*resp* '200 Protection level set to Private.'
*cmd* 'CCC'
*resp* '200 Clearing control channel protection.'
*cmd* 'CWD /Destdir'
*resp* '250 CWD command successful.'
*cmd* 'TYPE I'
*resp* '200 Type set to I.'
*cmd* 'PASV'
*resp* '227 Entering Passive Mode (xxx,xxx,xxx,xxx,216,241)'
*cmd* 'STOR test.txt'
*resp* "150 Opening BINARY mode data connection for 'test.txt'."
_ssl.c:704: The handshake operation timed out
我现在也尝试了扩展被动模式,但也没有帮助:
*resp* '250 CWD command successful.'
*cmd* 'TYPE I'
*resp* '200 Type set to I.'
*cmd* 'EPSV'
*resp* '229 Entering Extended Passive Mode (|||55536|)'
*cmd* 'STOR test.txt'
*resp* "150 Opening BINARY mode data connection for 'test.txt'."
_ssl.c:704: The handshake operation timed out
EDIT_1: 因此,脚本可以部分工作,可以打开连接,开始文件传输。在远程服务器上创建了文件get,但是它不包含与源文件相同的数据。目标文件的大小为1KB,只有一些随机字符(文件是ANSII编码的,而源文件是UTF8。 同时,我可以使用WinSCP成功上传文件。
答案 0 :(得分:0)
您使用FTP活动模式:
ftps.set_pasv(False)
从您的评论看来,您似乎没有充分的理由这样做。
FTP活动模式通常不起作用,因为它要求客户端能够接受传入的连接。如果不打开本地(Windows和本地网络)防火墙和/或配置NAT,通常是不可能的。除非有特殊原因,否则不要尝试使用主动模式。使用被动模式。只需删除ftps.set_pasv
调用即可。被动模式是ftplib中的默认模式。
有关详细信息,请参见我在FTP connection modes上的文章。
答案 1 :(得分:0)
这很可能是防火墙问题。 FTP非常特殊,因为它每次传输使用不同的连接。当前根据您的跟踪有效的连接是 command 连接,该连接由客户端建立,并指向服务器的FTP端口(通常为21)。
数据连接是独立连接。在活动模式下,它是由服务器建立的,源于FTP-DATA端口(20),并瞄准客户端在其PORT
命令中发送的端口。在被动模式下,服务器将其响应PASV命令的响应发送到该端口,以侦听数据连接,然后客户端尝试打开与该(几乎随机)端口的新连接。
这意味着除非防火墙允许较大的地址范围,或者防火墙软件执行特殊处理以动态允许FTP命令传递的地址,否则防火墙可以允许命令连接,然后阻止任何数据连接。
参考: