Monday, September 14, 2015

Configuring vsftpd to support proxy FTP


I've had to deal with a legacy application that is hard coded to use proxy ftp sessions. These are initiated by using the "proxy" command in a stock ftp client.

It was giving us trouble with vsftpd refusing to transfer files when using "proxy get" to initiate a passive session between the vsftpd server and another server.

What is a proxy FTP? In a nutshell, a proxy session lets you open a connection to a second FTP server, so that you can transfer files between both servers from instead of between the primary server and your FTP client.

The ftp(1) man page documents what "proxy" does. It is important to read it and understand what happens when you use this:
     proxy ftp-command
                 Execute an ftp command on a secondary control connection.
                 This command allows simultaneous connection to two remote ftp
                 servers for transferring files between the two servers.  The
                 first proxy command should be an open, to establish the sec-
                 ondary control connection.  Enter the command "proxy ?" to
                 see other ftp commands executable on the secondary connec-
                 tion.  The following commands behave differently when pref-
                 aced by proxy: open will not define new macros during the
                 auto-login process, close will not erase existing macro defi-
                 nitions, get and mget transfer files from the host on the
                 primary control connection to the host on the secondary con-
                 trol connection, and put, mput, and append transfer files
                 from the host on the secondary control connection to the host
                 on the primary control connection.  Third party file trans-
                 fers depend upon support of the ftp protocol PASV command by
                 the server on the secondary control connection.

So how does this impact vsftpd when using it to handle the primary control connection?

The first thing that might happen is that if you issue a proxy get, it might  fail with the following message:
500 Illegal PORT command

This is fixed by adding the following parameter to vsftpd.conf:
port_promiscuous=YES
What this parameter does is authroize vsftpd to open a data connection with the proxy server, instead of limiting it between vsftpd and the FTP client.

Then, you might get:
500 OOPS: vsf_sysutil_bind

This happens because the vsftpd process is trying to bind to port 20 to the IP address of the server. By stracing the process, I found out that this does not work because the vsftpd process that handles communication with clients is unprivileged. This privilege separation is by design. The workaround I found is to add this to vsftpd.conf:
connect_from_port_20=NO

This makes vsftpd bind to another port (I didn't even check which one) but it works. By default it is set to "NO", but it is left to "YES" in the example configuration file and thus why it was there in the first place.

Good luck