FTP configuration issues

I found that it was a real mess to set up a FTP server in a DMZ, behind a firewall Cisco Asa (501 model with IOS version 7.0).

The FTP server is on the DMZ area, and therefore I natted a public IP to the private IP in the DMZ subnet of this server.

static (dmz,outside) <public IP> <private_IP> netmask 255.255.255.255

Doing so, I expect that my FTP server (like Vsftpd on Linux) to be reachable within its public IP, from the Asa external interface.

Choosing a FTP transfer mode

Before going further, let’s recall the two modes in which the FTP protocol can work :

  • active mode : this is the historical mode, but should be considered obsolete now because of the numerous issues it contains. In this mode, after the client initiate the communication on the port 21 (command chanel), the server initiate the data transfert chanel from its port 20 toward a port specified by the client. It causes two big problems :
    • the client must configure its firewaling to allow incomming traffic on this port. In the real life, this is most likely to be like allowing the 1024-65535 range port for incoming traffic. Not really secure, isn’t it ?
    • if the client is behind a NAT, it won’t work ! As the server initiate the connection, the router does not have any entry for the flow in its NAT table. It will just drop the connexion.
  • passive mode : the difference here is that the server chooses on what port the data transfert will be operated. The port is given to the client when this one initiate the communication. Actually, the server never initiate any connexion, so the name “passive”. The only thing to do on the server side is to set the right firewall rule to allow the server ports. The client then initiate the transfert on the given port. It solves the client side firewalling problem, because the firewall will see it as outbound traffic. With correct rules, especially if the firewall is statefull, this is an easy thing.

Configuring the passive mode on the server

So, is the passive mode the end of all problems ?

Not yet…

By default, the FTP server will be listening on its netword interface and answer to the FTP requests with its private IP, if, like probably in many case, the FTP server is located on a DMZ network.

In such a case, the client gets a private IP to connect with… and can never reach the server properly.

To workaround this problem, most of FTP servers can be configured to answer with there public IP.

With VSFTP, this is a line like :

pasv_address = $public_IP

There another two issues for that :

  • the server won’t be reachable anymore within its private IP, for instance from the local subnet
  • the Cisco Asa firewall drops the traffic

Cisco Asa issue

The Asa log file shows :

FTP port command different address: $IP_addr ($IP_addr2) to $IP_addr_3 on interface int_name

The explanation from the cisco website :
A client issued an FTP port command and supplied an address other than the address used in the connection. This error message is indicative

of an attempt to avert the site’s security policy. For example, one might attempt to hijack an FTP session by changing the packet on the way, and putting

different source information instead of the correct source information. The PIX Firewall drops the packet, terminates the connection, and logs the event.

In the error message displayed, the IP address in parentheses is the address from the PORT command.
Well, as there is nothing to do against this behaviour, I won’t use the pasv_address option.

Private IP issue

So, for now we stick with a server sending its private IP address in any case. That solves any issue in the local subnet, but is it possible to do anything for external clients which needs to get a public IP ?

Actually, and this is really not a satisfying answer, it depends on the client. Most of the FTP client must have the some options to workaround this issue, but not all.

Let’s check how it is with a few FTP clients.

Basic FTP command line client (Linux)

$ ftp X.X.X.X
ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-rw-r--    1 102      1001           21 Aug 16 10:53 test
226 Directory send OK.

Humm… it is working, but it shouldn’t as my server is configured for passive mode.

Let’s see what is going on with Wireshark… Two packets are interesting :

28    35    192.168.1.2    X.X.X.X   FTP    Request: PORT 192,168,1,2,173,87
29    36    X.X.X.X    192.168.1.2    FTP    Response: 200 PORT command successful. Consider using PASV.

From the client, we have a PORT request, which shows that our client is connecting in active mode.

Surprise, the server replies ! And says successful, even if the IP given is a private one. That should not work and, if any response, not go out of the external firewall…
Note : (192,168,1,2,173,87) is the FTP way to manage IPs and port. The IP is simply given by the four first numbers : 192,168,1,2 <=> 192.168.1.2.
The 2 last ones gives you the port number with this formula : 173,87 => 173 x 256 + 87 = port n°44375
Anyway, let’s try the passive mode :

ftp> passive on
Passive mode on.
ftp> dir
227 Entering Passive Mode (10,1,1,1,15,195)
receive aborted
waiting for remote to finish abort

We tried to switch to passive mode. The server gaves its IP, but its private one (192.168.10.1). The client trying to reach this address can’t and falls in timeout (I killed it, no more patience :) ) .

Now, let’s summarize.
Using the ftp basic client, we can’t go through in passive mode. We get a private IP and we have no workaround.
The active mode works, but it is thanks to the behaviour of VSFTP.

A look on the man page of VSFTP gives some answers : the

port_enable

directive, set to YES by default, allow the PORT command from the client even in passive mode. So, we could add in the vsftd.conf configuration file :

port_enable=NO

After that the server will answer

550 Permission denied

when a PORT command is issued. At the end, I won’t set this, because such a behaviour is actually nice.

I still wonder how VSFTP could get the public IP when the PORT command send the private IP. I guess, and it would be a smart behaviour, that the program checks the underlying protocol layers and takes the right IP from the IP header… I will have it confirmed and update this post.

Gftp

This Gnome FTP client behave like the ftp command line client in passive mode : it falls into timeout.

It doesn’t try by default to fail over active mode.

You can configure either active mode or ignoring the passive command IP in the options :

gftp - ftp connexion parameters

Filezilla

Filezilla has the most interesting behaviour. When the standard passive mode fails, it is able to fail over by using active mode or using the public IP seen from the server.

This can be configured in the connexion options :

filezilla connexion parameters

When Filezilla uses the public IP address instead of the transmitted one :

 PASV
227 Entering Passive Mode (10,1,1,1,15,209)
LIST
150 Here comes the directory listing.
226 Directory send OK.

When it is configured to switch to active mode :

PASV
227 Entering Passive Mode (10,1,1,1,15,179)
PORT 192,168,1,2,130,1
200 PORT command successful. Consider using PASV.
LIST
150 Here comes the directory listing.
226 Directory send OK.

Conclusion

I could not reach the point where I can be 100% sure that it will work in all configurations. The best I could do is a series of small fixes to get the best compromise as possible.

I guess that using VSFTD as a server and recomanding a good client as Filezilla will work pretty well – and that won’t be a big deal to get to such a configuration.

If anyone has some better ideas, or see I fooled somewhere before my conclusion, please let me know.

But anyway, really, FTP sucks. It is anoying that the use of this protocol is still required by some companies.