I'm trying to connect to a FTP server from behind a firewall that accepts outputs from the port range 6100–6200 only. I'm (rather naively, but based on a read of the documentation) trying:
from ftplib import FTP
host_address="the.ftp.ip.address"
ftp = FTP()
ftp.connect(host=hostaddress, source_address=("127.0.0.1", 6100))
But this gives the error:
In [42]: ftp = FTP(host_address, source_address=('127.0.0.1', 6100))
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
<ipython-input-42-071ac06087bd> in <module>
----> 1 ftp = FTP(destination, source_address=('127.0.0.1', 6100))
~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/ftplib.py in __init__(self, host, user, passwd, acct, timeout, source_address, encoding)
117 self.timeout = timeout
118 if host:
--> 119 self.connect(host)
120 if user:
121 self.login(user, passwd, acct)
~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/ftplib.py in connect(self, host, port, timeout, source_address)
154 self.source_address = source_address
155 sys.audit("ftplib.connect", self, self.host, self.port)
--> 156 self.sock = socket.create_connection((self.host, self.port), self.timeout,
157 source_address=self.source_address)
158 self.af = self.sock.family
~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/socket.py in create_connection(address, timeout, source_address)
841 if err is not None:
842 try:
--> 843 raise err
844 finally:
845 # Break explicitly a reference cycle
~/SOFTWARE/anaconda3/envs/GDAL/lib/python3.9/socket.py in create_connection(address, timeout, source_address)
829 if source_address:
830 sock.bind(source_address)
--> 831 sock.connect(sa)
832 # Break explicitly a reference cycle
833 err = None
OSError: [Errno 22] Invalid argument
From the same machine, I can successfully list the files using curl:
curl --ftp-port :6100-6200 --list-only $ftpserver
How can I connect to a regular (i.e. port 21) FTP server with ftplib circumventing my local firewall?