I wanted to share few files from my home server computer, so I’ve decided to run FTP server on that box. I’ve chosen not to use SFTP/SCP because I don’t like the way progress reporting is handled – progress bars are updated only after quite large chunk of data are transferred, otherwise dialogs are frozen. FTP is quite robust, and there is plenty of client software. I myself use built-in FTP feature of Total Commander.
There were few aspects I had to take care of. First of all, security. FTP itself doesn’t provide any encryption, even during login phase. There are some possibilities, like FTPS – which is basically FTP over SSL, but I’ve already had VPN (OpenVPN specifically), so I didn’t have to worry about it. Having VPN solved also an other problem, but I’ll come back to this later. If you don’t have/need any VPN, you can configure FTP daemon to use encryption. I encourage using any kind of encryption. Otherwise your account passwords would be transmitted through the network in plain text.
Next thing was software and its configuration. I had some experience with ProFTPd daemon, and it has opinion of being very versatile and safe, so it was an obvious choice. Then I had to choose from two configuration options. First is stand-alone server, when FTP daemon works all the time on its own, handling connections, staying in memory. This option is more natural when FTP load is larger, when connections are incoming quite often. In that scenario, it is better for daemon to stay in memory all the time, so there is no overhead for daemon starting.
Second form is working via “super-daemon” inetd, which starts FTP daemon only when a connection is incoming. It is good configuration for sites, where clients are connecting from time to time, and there is no need to keep the daemon in memory all the time. This would be naturally proper solution in my case, but I had some negative experiences with it. Specifically, my server, working on poor hardware (p2-266), was hammered to death by a brute-force attack. Inetd was forking FTP software for each connection, and this took all available memory (which is quite low “normally”), swap, and so on.
I chose stand-alone configuration, mainly for its flexibility.
I wanted to be sure that no one unwanted would “steal” any resources. In my system configuration it was quite easy. All I had to do was to bind FTP daemon only to VPN interface (10.69.120.10/24 in my case). To do this, I had to put these lines into proftpd.conf:
DefaultAddress 10.69.120.10 SocketBindTight on
If I used inetd, I could limit FTP service to VPN only by engaging hosts.allow and hosts.deny files. I could put:
to /etc/hosts.deny and:
to /etc/hosts.allow (don’t forget the dot). This could do the trick, but still inetd would be engaged in handling an incoming connection. To lock connection on lower lever, I could do it using firewall. Having INPUT rule with default ACCEPT (check it with iptables -t filter -L command – the output should be something like Chain INPUT (policy ACCEPT)), I could do:
$ iptables -t filter -A INPUT -s 10.69.120.0/24 -p tcp --dport 21 -j ACCEPT
$ iptables -t filter -A INPUT -s 0.0.0.0/0 -p tcp --dport 21 -j DROP
Having it with default to DROP or REJECT, the first command would suffice, but also data port has to be open (20).
If you don’t have VPN, you can limit incomming connections to IP addresses you are using, i. e. your home IP address. To do this, replace IP subnet specification from iptables command with your address, for example 192.168.0.155/32. You can of course add whole subnet, or even replace “-s some_ip” with “-i interface” to allow connections by some network interface, like your internal network controller.
Generally, that’s it. I have a secure FTP server, I don’t have to worry about my password being sniffed, resources being eaten, and I can freely download my data over the VPN.