How to FTP through a NAT router/firewall

Network Address Translating (NAT) routers/firewalls present challenges for users of FTP (and particularly FTPS).

Note that as SFTP uses a single connection (usually on port 22), it is common to configure firewalls to permit use of port 22 for SSH and firewalls are generally not an issue).

As described in the FTP Protocol Overview, FTP uses multiple TCP/IP connections; one for sending the commands on, the rest for transferring data. The following diagram illustrates a typical session:

The three arrows indicate separate TCP/IP connections, with the commands being sent on the main FTP connection.

Problems can arise when a NAT router is introduced:

Since the main connection is outgoing the NAT firewall allows this connection to be made, but when the server tries to connect back to the client it is blocked by the firewall.

The technique called "passive mode" or PASV was introduced to reduce this problem. In this scheme connections are always made from the client to the server and not vice-versa.

This is why passive mode is generally preferable when NAT firewalls are involved.

Passive mode may be selected by setting the setConnectMode() method as follows:

ftp.setConnectMode(FTPConnectMode.PASV);

In fact, in plain FTP (i.e. not FTPS) active mode often works due to some magic in many NAT routers - they actually parse the FTP commands being sent and know what to do with the data transfer connections. However, FTPS never works in active mode if a NAT is involved since the NAT cannot parse the encrypted commands being sent.

Dealing with dual NATs

Unfortunately, some FTP sessions involve two NATs:

Usually, the main connection succeeds because the standard FTP port (21) is routed through to the correct FTP server, but then the file transfers failed because the ports that they use are not set up to forward to the server.

In this scenario, the server may be set up to only use particular ports for data transfers. The server-side NAT may then be configured to forward these ports to the server.