0

I use Python ftplib to connect to an FTP server which is running on active mode; That means the server will connect my client machine on a random port when data is sent between us.

Can I specify the client's data port (or port range) and let the server connect the certain port? I don't want to open all ports to the FTP server in my firewall iptables.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
bluesea007
  • 211
  • 3
  • 11

3 Answers3

1

There is no way to do this with the standard ftplib module.

You're either going to have find an alternate library which offers this functionality or monkey-patch the makeport() method on your FTP object if you're feeling brave.

David Webb
  • 190,537
  • 57
  • 313
  • 299
0

You can re-implement the sendport method of FTP to send your desired IP address instead of the deduced one. Something like this:

class PatchedFTP(FTP):
    def sendport(self, host, port):
        return super(MyFTP, self).sendport("192.0.2.1", port)

ftp = PatchedFTP(ftp_server)

# the rest of the code would be the same

Though usually, better solution is to use the passive mode. Commonly, people try to use the active mode, because the passive mode does not work with the default code, because its external IP is reported wrong. For a workaround, see:
Cannot list FTP directory using ftplib – but FTP client works

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
-2

Since Python 3.3, ftplib functions that establish connections take a source_addr argument that allows you to do exactly this.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • The `source_address` (there's no `source_addr`) controls source address and port of the outgoing connections (so the control connection and outgoing data connections in the passive mode). It has no effect on the listening ports in the active mode. – Martin Prikryl Jul 21 '21 at 12:18