I'm trying to upload a file using ftplib
over an sshtunnel. I can login successfully to the remote end ftp server over this tunnel, but the program times out when trying to send the file.
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()
I can certanly connect and login:
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'
... but a time out rises when trying to upload the file ...
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
any hint?
thanks!
So the thing is I was missing tunneling the data port of FTP. In order to avoid creating a second tunnel, I just used sftp instead.
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)
With the previous I can upload a file to a remote SFTP server over an SSH tunnel. Yes, is not FTP, but it worked for me.
If FTP is the only possible way, then a second ssh tunnel for the data channel will be needed.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.