How do I use FTP with SSL behind a NAT?

Previous  Top  Next

The problem is that the FTP protocol is really not too friendly with many firewall/proxy configurations.  The problem is that there's two connections between the client and server (the control connection and the data channel) and the data channel is established using commands (PORT and PASV) that communicate IP addresses.  Computers behind a NAT have IP addresses that only make sense in the Internal network and not the Internet. 

 

This is not usually a problem with unencrypted FTP because most NAT's will fix the connection by opening random ports and changing values being communicated in the PORT and PASV commands.  Unfortunately, SSL makes it nearly impossible for a NAT to make such a correction.

 

For Indy 10 TIdFTP

 

A FTP client using SSL should use PASV transfers (Passive := True) instead of PORT transfers (Passive = False) because a NAT can not translate the IP address given in a PORT command on the control connection.

 

If you must use PORT transfers, you should do the following:

 

1.Configure your NAT to forward a range ports to your computer behind the NAT.
2.Specify that port range with the DataPortMin and DataPortMin properties.
3.Set the ExternalIP property to the NAT's external Internet IP address.

 

You may also wish to consider clearing encryption from the control channel by setting the UseCCC property to True as a NAT might be able to intercept the IP address specified in the PORT command.  However, that does not work on some NAT's, you may not want to send unencrypted FTP commands, and some FTP servers do not support the CCC command.

 

If you are making a FTP client that will be deployed widely, you should make configuration options for port ranges to use with data channels, permitting the user to enter an external Internet IP address for their NAT's, and permitting the user to clear the command connection with the CCC command.

 

For Indy 10 TIdFTPServer

 

We do not recommend placing a FTP server using SSL behind a NAT at all. The NAT can not translate the IP address given as a reply to the PASV command on the control connection into an address that works outside of the internal network.  Unfortunately, PASV transfers are the default in some FTP clients.

 

If you must use a FTP server using SSL behind a NAT, you should do the following:

 

1.Configure your NAT to forward a range ports to your server. 
2.Specify that port range with PASVBoundPortMin and  BoundPortMax  properties.
3.Set the IP address given in PASV replies to your NAT's external Internet IP address using the OnPASVReply event but do not change the IP address for clients that are also on the internal network.

 

If you are writing a FTP server that will be deployed widely, you should make configuration options for port ranges, for specifying an external Internet IP address for connections from clients outside the network, and for permitting the CCC command.  You can permit the CCC command globally by setting the TIdFTPServer.FTPSecurityOptions.PermitCCC to True or you can permit the CCC command on a per-user basis by setting UserSecurity.PermitCCC property in the TIdFTPServerContext object after the user logged in.

 

See also:

 

How do I use Indy with a NAT (Network Address Translator)?
How do I use FTP with SSL?