Due to this two-channel setup, the inherent insecurities of a non-encrypted data stream, and the complexities of a Firewall and the NAT system and whatnot, FTP is slowly being replaced by SFTP which uses a single port (22) and the SSH protocol to transfer files. But since SFTP isn't everywhere (especially on Windows machines), FTP is still needed.
Let's add some more complexities: Active vs Passive FTP. In Active FTP, the Data Channel is on Port 20 and it is initiated by the FTP Server. This is nice because the Server's firewall has a known port (port 20) that needs to be opened. Unfortunately, this requires the client's firewall be wide open to listen for that incoming connection, which may be blocked. Some firewalls will expect these connections, however, and permit the access.
Passive FTP, on the other hand, has the client initiate the data connection. This works to not open wide the firewall on the client network, but requires that the FTP Server's firewall has holes. Since the server will only be set up once for multiple clients, this can be a better method than expecting everyone to open their firewall.
An issue with Passive FTP behind a firewall, however, is that the server is initiating the connection using its own, private IP. With normal FTP, apparently the firewall may rewrite these packets. But with FTPS, which is secured using an SSL certificate, this data is encrypted and the firewall cannot make those packet changes.
VSFTP on Debian GNU/Linux allows us to set up Passive FTP on a NAT system with FTPS (or FTPES, meaning "explicit SSL" which is Port 21 still. There is also FTPS on port 990, which uses implicit SSL, and this HowTo doesn't cover that.)
First install VSFTP:
# aptitude update
# aptitude install vsftpd
I highly recommend that you use a real SSL certificate, available here and other places. If not, however, you can create and use a self-signed SSL Certificate:
# mkdir /etc/vsftpd
# cd /etc/vsftpd
# openssl req -new -x509 -days 9999 -nodes -out vsftpd.pem -keyout vsftpd.pem
Answer the questions and when you're done you'll have a file named /etc/vsftpd/vsftpd.pem which is your self-signed cert.
Edit the /etc/vsftpd.conf file to have these options, which of course you can adjust:
Note this line (below); this will allow VSFTP to rewrite its own passive packets to allow for that data channel to function. Set this as the firewall's external IP, not the 220.127.116.11 example I have here:
In your firewall, allow these ports through and port-forward them to this same internal server:
Now you need to add a user to your system:
If you want to prevent this user from logging in with SSH or at a console, you'll need to set this user to not have a shell (aka, set to /bin/false ) in /etc/passwd:
and make sure that is a valid (even though fake) shell option in /etc/shells:
Finally, we'll turn off VSFTP's checking of the shell access in the file /etc/pam.d/vsftpd by commenting out (putting a #) the line:
#auth required pam_shells.so
We'll restart VSFTP
# /etc/init.d/vsftpd restart
and we should now be able to use FTPS from another computer, assuming you have your Firewall and Port Forwarding set up correctly for port 21 and ports 24000-24100 (or whatever you set in vsftpd.conf). Instructions for connecting with various options (Dolphin, FileZilla, and cURL) can be found here.
More about FTP here
More about FTPS in VSFTP here
More about VSFTP logging here and conf options here
More about disabling PAM authentication to allow VSFTP to use /bin/false here
Great prices on SSL Certificates here.
Thanks everyone who has written about this elsewhere and thanks to the developers of VSFTP.