【问题标题】:can't upload file using ftplib over ssh-tunnel无法通过 ssh-tunnel 使用 ftplib 上传文件
【发布时间】:2020-04-07 21:55:11
【问题描述】:

我正在尝试通过 sshtunnel 使用 ftplib 上传文件。我可以通过此隧道成功登录到远程端 ftp 服务器,但尝试发送文件时程序超时。

import paramiko
from sshtunnel import SSHTunnelForwarder
from ftplib import FTP

USER               = ["userSSH","passSSH"]
SSHPORT            = 22
SSHIP              = "A.B.C.D"
ROUTER_FTP_PORT    = 21
REMOTE_FTP         = "W.X.Y.Z"

fserver = SSHTunnelForwarder( (SSHIP, SSHPORT), 
    ssh_username        = USER[0], 
    ssh_password        = USER[1], 
    remote_bind_address = (REMOTE_FTP, ROUTER_FTP_PORT), )

fserver.start()
fport = fserver.local_bind_port

ftp = FTP()
ftp.connect("127.0.0.1",fport)
ftp.login("ftpUser","ftpPass")
file = open('lucas.cfg','rb')
ftp.storbinary('STOR lucas.cfg',file)
file.close()

我可以确定连接和登录:

In [8]: ftp.connect("127.0.0.1",fport)
Out[8]: '220 FTP server ready'

In [9]: ftp.login("ftpUser","ftpPass")
Out[9]: '230 User logged in'

...但是尝试上传文件时超时...

In [19]: ftp.storbinary('STOR lucas.cfg',file)
---------------------------------------------------------------------------
TimeoutError                              Traceback (most recent call last)
<ipython-input-19-0af0cb3b5ebf> in <module>()
----> 1 ftp.storbinary('STOR lucas.cfg',file)

/usr/lib/python3.6/ftplib.py in storbinary(self, cmd, fp, blocksize, callback, rest)
    502         """
    503         self.voidcmd('TYPE I')
--> 504         with self.transfercmd(cmd, rest) as conn:
    505             while 1:
    506                 buf = fp.read(blocksize)

/usr/lib/python3.6/ftplib.py in transfercmd(self, cmd, rest)
    397     def transfercmd(self, cmd, rest=None):
    398         """Like ntransfercmd() but returns only the socket."""
--> 399         return self.ntransfercmd(cmd, rest)[0]
    400 
    401     def login(self, user = '', passwd = '', acct = ''):

/usr/lib/python3.6/ftplib.py in ntransfercmd(self, cmd, rest)
    359             host, port = self.makepasv()
    360             conn = socket.create_connection((host, port), self.timeout,
--> 361                                             source_address=self.source_address)
    362             try:
    363                 if rest is not None:

/usr/lib/python3.6/socket.py in create_connection(address, timeout, source_address)
    722 
    723     if err is not None:
--> 724         raise err
    725     else:
    726         raise error("getaddrinfo returns an empty list")

/usr/lib/python3.6/socket.py in create_connection(address, timeout, source_address)
    711             if source_address:
    712                 sock.bind(source_address)
--> 713             sock.connect(sa)
    714             # Break explicitly a reference cycle
    715             err = None

TimeoutError: [Errno 110] Connection timed out

有什么提示吗?

谢谢!

【问题讨论】:

  • 你确定你有连接到 A.B.C.D : 21 ??? ...首先尝试通过控制台 telnet A.B.C.D 21 从哪里找到您的脚本
  • 是的,我确定。 A.B.C.D 是我用来绕过远程 ftp 服务器的 SSH 服务器。另一方面,我当然可以登录,如上所示:Out[9]: '230 User logged in' ...这意味着W.X.Y.Z 上通往端口21的隧道正在工作,但由于某种原因我不能put文件...跨度>
  • 您没有告诉我们有关您的隧道的任何信息。你转发数据端口了吗? + 您甚至可以使用任何现有的 FTP 客户端通过隧道传输文件吗?
  • @MartinPrikryl,我已经尝试将passiveactive 方法与FTP 一起使用,但没有一个可以通过SSH 工作。事实是数据端口没有被隧道化。为了解决这个问题(并避免为数据通道创建第二条隧道),我使用了 sftp。我将在答案中显示这一点。谢谢!

标签: python ftp ssh-tunnel


【解决方案1】:

所以问题是我缺少隧道传输 FTP 的数据端口。为了避免创建第二个隧道,我只使用了 sftp。

server = SSHTunnelForwarder( (SSHIP, SSHPORT), 
    ssh_username        = USER[0], 
    ssh_password        = USER[1], 
    remote_bind_address = (REMOTE_SFTP, ROUTER_SFTP_PORT), )

server.start()
sftpPort = server.local_bind_port

transport = paramiko.Transport(("127.0.0.1",sftpPort))
transport.connect(None,username,password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.put(fileLocal,fileRemote)

使用前面的方法,我可以通过 SSH 隧道将文件上传到远程 SFTP 服务器。是的,不是 FTP,但它对我有用。

如果 FTP 是唯一可能的方式,那么数据通道将需要第二个 ssh 隧道。

【讨论】:

    猜你喜欢
    • 2019-04-05
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2016-06-07
    相关资源
    最近更新 更多