FTPS over a NAT Firewall is a problem, but there are solutions. First, an explanation of the problem: The reason why FTPS (and even FTP without SSL) is a problem with firewalls is that unlike most internet protocols, FTP requires two socket connections, not just one. The first connection, called the control connection, is the one where all of the commands and responses are exchanged between client and server. The second connection, called the data connection, is where all of the data is transferred (files and file listings). There are two ways to setup the data connection - active or passive. Active mode means that the data connection will be opened from the server to the client (the client will listen for an incoming connection from the server). Passive mode is just the opposite, the client will open the data connection on the server (the server will listen for an incoming connection from the client). Passive mode is recommended, especially for SSL connections.
A normal, unencrypted, passive FTP data connection gets configured and opened like so:
SERVER-->CLIENT: 227 Ok, Entering Passive Mode (193,21,1,121,15,6)
The client sends the PASV command, and the server says "OK", and tells the client the ip address and port that he is listening to. The first four octets in the parenthesized response form the dotted ip address (220.127.116.11) and the last 2 form the port number (15*256 + 6) = 3846. At this point, the server is listening for an incoming data connection - and the client can go ahead and make that connection so that the two sides can begin transferring data.
When you throw a NAT (Network Address Translation) in the middle
you now have the following communication:
SERVER-->NAT: 227 Ok, Entering Passive Mode (10,0,1,121,15,6)
NAT-->CLIENT: 227 Ok, Entering Passive Mode (193,21,1,121,15,6)
As you can see, the NAT must spy on the servers response to the PASV command. The NAT sees that the server is listening on 10.0.1.121 port 3846. The server is of course on a private IP address that the client cannot reach. The NAT has the public IP address that the client is communicating with. So the NAT replaces the servers response with his own - telling the client to open the connection to HIS ip address and port. In turn of course, when the NAT receives a connection to that location, he will forward it on to the FTP servers IP and port.
Now throw in another complication: SSL. Now the NAT cannot spy on the PASV response, nor can he alter it. So the client would attempt to open the data connection on an IP address that was not accessible, since it is behind the firewall.
What is the solution?
There are several possible solutions you can explore:
- Some FTP servers will allow you to specify an IP address (and port range) to use for passive mode connections. You'd set this to your public IP address.
- Some FTP clients (including IPWorks components) can be smart enough to try the ip address specified by the server in the response to the PASV command, and it that fails, fall back to the same ip address that the initial connection was made to. Though that is not always the desired behavior, you can accomplish this with the IPWorks FTP components by using the UseRemoteHostAddressForPassive config:
Note that the component will not do this automatically, for security reasons.
- Some NATs will allow you to specify port ranges that will automatically forward to a specific location. If you can configure this port range to match the passive port range used by the FTP server - that may be a solution.
- Another solution is to set your FTP server up to use the EPSV command (Extended Passive Mode). The EPSV command only sends the port - and the IP address is inferred to be the same as the IP address of the control connection. The IP*Works! FTPS control supports UseEPSV as a configuration option:
will add support for EPSV.