In this sixth part of a nineteen-part series on SSH, we'll take a look at FTP's difficulties with network address translation (NAT) and how to get around them. We'll also show you a way to forward the FTP data connection. This article is excerpted from chapter 11 of the book SSH, The Secure Shell: The Definitive Guide, Second Edition, written by Daniel J. Barrett, Richard E. Silverman and Robert G. Byrnes (O'Reilly; ISBN-10: 0596008953).
11.2.6 FTP and Network Address Translation (NAT)
Passive-mode transfers can also work around another common problem with FTP: its difficulties with network address translation, or NAT. NAT is the practice of connecting two networks by a gateway that rewrites the source and destination addresses of packets as they pass through. One benefit is that you may connect a network to the Internet or change ISPs without having to renumber the network (that is, change all your IP addresses). It also allows sharing a limited number of routable Internet addresses among a larger number of machines on a network using private addresses not routed on the Internet. This flavor of NAT is often called masquerading.
Suppose your FTP client is on a machine with a private address usable only on your local network, and you connect to the Internet through a NAT gateway. The client can establish a control connection to an external FTP server. However, there will be a problem if the client attempts the usual reverse-direction data connections. The client, ignorant of the NAT gateway, tells the server (via aPORTcommand) to connect to a socket containing the client’s private address. Since that address isn’t usable on the remote side, the server generally responds “no route to host” and the connection will fail.* Figure 11-5 illustrates this situation. Passive mode gets around this problem as well, since the server never has to connect back to the client and so the client’s address is irrelevant.
So far, we’ve listed three situations requiring passive-mode FTP: control connection forwarding, client inside a firewall, and client behind NAT. Given these potential problems with active-mode FTP, and that there’s no down side to passive mode that we know of, we recommend always using passive-mode FTP if you can.
220.127.116.11 Server-side NAT issues
The NAT problem we just discussed was a client-side issue. A more difficult problem can occur if the FTP server is behind a NAT gateway, and you’re forwarding the FTP control connection through SSH.
First, let’s understand the basic problem without SSH in the picture. If the server is behind a NAT gateway, then you have the mirror-image problem to the one discussed earlier. Before, active-mode transfers didn’t work because the client supplied its internal, non-NAT’d address to the server in thePORTcommand, and this address wasn’t reachable. In the new situation, passive-mode transfers don’t work because the server supplies its internal-only address to the client in thePASVcommand response, and that address is unreachable to the client (see Figure 11-6).
The earlier answer was to use passive mode; here the simplest answer is the reverse: use active mode. Unfortunately, this isn’t very helpful. If the server is intended for general Net access, it should be made useful to the largest number of people. Since client-side NAT and firewall setups requiring passive-mode FTP are common, it won’t do to use a server-side NAT configuration that requires active mode instead; this makes access impossible. One approach is to use an FTP server with special features designed to address this very problem. The wu-ftpd server we touched on earlier has such a feature. Quoting from the ftpaccess(5) manpage:
passive address <externalip> <cidr> Allows control of the address reported in response to a PASV command. When any control connection matching the <cidr> requests a passive data connection (PASV), the <externalip> address is reported. NOTE: this does not change the address the daemon actually lis- tens on, only the address reported to the client. This feature allows the daemon to operate correctly behind IP-renumbering firewalls.
For example: passive address 10.0.1.15 10.0.0.0/8 passive address 192.168.1.5 0.0.0.0/0
Clients connecting from the class-A network 10 will be told the passive connection is listening on IP-address 10.0.1.15 while all others will be told the connection is listening on 192.168.1.5
Multiple passive addresses may be specified to handle com- plex, or multi-gatewayed, networks.
This handles the problem quite neatly, unless you happen to be forwarding the FTP control connection through SSH. Site administrators arrange for FTP control connections originating from outside the server’s private network to have external addresses reported in thePASVresponses. But the forwarded control connection appears to come from the server host itself, rather than the outside network. Control connections coming from inside the private network should get the internal address, not the external one. The only way this will work is if the FTP server is configured to provide the external address to connections coming from itself as well as from the outside. This is actually quite workable, as there’s little need in practice to transmit files by FTP from a machine back to itself. You can use this technique to allow control-connection forwarding in the presence of server-side NAT or suggest it to the site administrators if you have this problem.
Another way of addressing the server-side NAT problem is to use an intelligent NAT gateway of the type mentioned earlier. Such a gateway automatically rewrites the FTP control traffic in transit to account for address translation. This is an attractive solution in some respects, because it is automatic and transparent; there is less custom work in setting up the servers behind the gateway, and there are fewer dependencies between the server and network configurations. As it happens, though, this solution is actually worse for our purposes than the server-level one. This technique relies on the gateway’s ability to recognize and alter the FTP control connection as it passes through. But such manipulation is exactly what SSH is designed to prevent! If the control connection is forwarded through SSH, the gateway doesn’t know there is a control connection, because it’s embedded as a channel inside the SSH session. The control connection isn’t a separate TCP connection of its own; it’s on the SSH port rather than the FTP port. The gateway can’t read it because it’s encrypted, and the gateway can’t modify it even if the gateway can read it, because SSH provides integrity protection. If you’re in this situation—the client must use passive-mode FTP, and the server is behind a NAT gateway doing FTP control traffic rewriting—you must convince the server administrator to use a server-level technique in addition to the gateway, specifically to allow forwarding. Otherwise, it’s not going to happen, and we see trucks filled with tapes in your future, or perhaps HTTP over SSL with PUT commands.
We have now concluded our discussion of forwarding the control connection of FTP, securing your login name, password, and FTP commands. If that’s all you want to do, you are done with this case study. We’re going to continue, however, and delve into the murky depths of data connections. You’ll need a technical background for this material as we cover minute details and little-known modes of FTP. (You might even wonder if we’ve accidentally inserted a portion of an FTP book into the SSH book.) Forward, brave reader!