FTP used to be the most used protocol on the Internet by sheer data traffic until it was surpassed by HTTP a few years ago (yes, there was a WWW-free Internet once upon a time). FTP does one thing, and it does it well, transferring of files between systems. The protocol itself is insecure, passwords, data, etc is transferred in cleartext and can easily be sniffed, however most ftp usage is 'anonymous', so this isn't a huge problem. One of the main problems typically encountered with ftp sites is improper permissions on directories that allow people to use the site to distribute their own data (typically copyrighted material, etc). Again as with telnet you should use an account for ftping that is not used for administrative work since the password will be flying around the network in clear text.
Problems with ftp in general include:
ž Clear text authentication, username and password.
ž Clear text of all commands.
ž Password guessing attacks
ž Improper server setup and consequent abuse of servers
ž Several nasty Denial of Service attacks still exist in various ftp servers
ž Older version of WU-FTPD and derivatives have root hacks
Securing FTP isn't to bad, between firewalling and TCP_WRAPPERS you can restrict access based on IP address / hostname quite well. In addition most ftp servers run chroot'ed by default for anyone anonymous access, or an account defined as guest. With some amount of work you can set all users that are ftping in to be chroot'ed to their home directory or wherever appropriate. You can also run ftp servers that encrypts the data (using such things as SSL/etc.) however this means your ftp clients must speak the encryption protocol, and this isn't always practical. Also make very sure you have no publicly accessible directories on your ftp server that are both readable and writeable, otherwise people will exploit it to distribute their own software (typically warez or porn).
An example of firewalling rules:
ipfwadm -I -a accept -P tcp -S 10.0.0.0/8 -D 0.0.0.0/0 21 ipfwadm -I -a accept -P tcp -S some.trusted.host -D 0.0.0.0/0 21 ipfwadm -I -a deny -P tcp -S 0.0.0.0/0 -D 0.0.0.0/0 21
ipchains -A input -p tcp -j ACCEPT -s 10.0.0.0/8 -d 0.0.0.0/0 21 ipchains -A input -p tcp -j ACCEPT -s some.trusted.host -d 0.0.0.0/0 21 ipchains -A input -p tcp -j DENY -s 0.0.0.0/0 -d 0.0.0.0/0 21
An example of the same using TCP_WRAPPERS in /etc/hosts.allow:
in.ftpd: 10.0.0.0/255.0.0.0, some.trusted.host
And in /etc/hosts.deny:
There are several encrypted alternatives to ftp as mentioned before, SSLeay FTPD, and other third party utils. Since most ftp accounts are not used as admin accounts (cleartext passwords, you have been warned), and hopefully run chroot'ed, the security risk is minimized. Now that we have hopefully covered all the network based parts of ftp, lets go over securing the user accounts and environment.
There are numerous ftp server software packages available for Linux. The popular ones (Wu-FTPD and ProFTPD) have had a severe number of problems, so make sure your version is up to date.
ProFTPD is a GPL licensed ftp server that can run on a variety on UNIX platforms. It supports newer features such as virtual ftp, per directory configuration (using .ftpaccess files similar to Apaches .htaccess files), support for expired accounts and more. It also supports really useful features such as limiting downloads and much tighter security controls then WU-FTPD. I highly recommend it over any other freely available FTP server for UNIX.
ProFTPDs main configuration file is /etc/proftpd.conf, it has a rather Apache-esque configuration style which I like a lot. ProFTPD can be run from inetd (and make use of TCP_WRAPPERS) or it can be run as a stand-alone server. It also supports per directory config files to limit access and so forth. ProFTPD supports virtual ftp as well (although unlike virtual www serving, extra IP addresses are required) and each site can be configured differently (different anonymous access, if any, and more things along those lines). The general proftpd.conf typically has a section covering global settings (inetd or standalone, maximum number of processes to run, who to run as, and so on), followed by a default config, followed by specific site (virtual sites) configuration. On a server doing virtual hosting it is probably a good idea to turn DefaultServer off, so any clients ftping in aimlessly are denied instead of being dumped into a default site.
Sample configuration for a ProFTPD server being run from inetd with no anonymous access:
ServerName "ProFTPD Default Installation" ServerType inetd DefaultServer on Port 21 Umask 022 MaxInstances 30 User nobody Group nobody <Directory /*> AllowOverwrite on </Directory>
Lets say, like me, that you are paranoid and want to control access to the ftp server by IP addresses, hostnames and domain names (although I would recommend only relying on IPs). You could accomplish via firewall rules, but that tends to slow the machine down (especially if you are adding lots of rules as would be prone to happen). You could use TCP_WRAPPERS, but you wouldnt be able to selectively limit access to virtual sites, anonymous sites, just the server itself. Or you could do it in the proftpd.conf file using the <Limit LOGIN> directive.
The following example will limit access to 10.1.*.* and 22.214.171.124, all other machines will be denied access.
<Limit LOGIN> Order Allow,Deny Allow from 10.1., 126.96.36.199 Deny from all </Limit>
If you place this within a <VirtualHost> or <Anonymous> directives it applies only to that virtual site or anonymous setup, if placed in a <Global> directive it will apply to all the <VirtualHost> and <Anonymous> sections, and if placed in the server config (i.e. with the ServerName and related items) it will behave like TCP_WRAPPERS would, anyone not from 10.1.*.* or 188.8.131.52 immediately gets bumped when they try to connect to port 21, as opposed to simply being denied login if its in a <Global>, <VirtualHost> or <Anonymous> section.
If you want to add anonymous access simply append:
<Anonymous ~ftp> User ftp Group ftp RequireValidShell off UserAlias anonymous ftp MaxClients 10 DisplayLogin welcome.msg DisplayFirstChdir .message <Directory *> <Limit WRITE> DenyAll </Limit> </Directory> </Anonymous>
This would assign the ftp users home directory (assuming a normal setup ~ftp would probably be /home/ftp) as the root anonymous directory, the ProFTPD would run as the user ftp and group ftp when people log in anonymously (as opposed to logging in as a normal user), and anonymous logins would be limited to 10. As well the file /home/ftp/welcome.msg would be displayed when anonymous users ftp in, and any directory with a .message file containing text would be displayed when they changed into it. The <Directory *> covers /home/ftp/*, and then denies write access for all, meaning no-one can upload any files. If you wanted to add an incoming directory simply add the following after the <Directory *> directives:
<Directory incoming> <Limit WRITE> AllowAll </Limit> <Limit READ> DenyAll </Limit> </Directory>
This would allow people to write files to /home/ftp/incoming/, but not read (i.e. download) them. As you can see ProFTPD is very flexible, this results in ProFTPD requiring more horsepower then WU-FTPD, but it is definitely worth it for the added control. You can get ProFTPD and the documentation from: http://www.protftpd.net/.
proftpd-ldap allows you to do password look ups using an LDAP directory, you can download it from: http://horde.net/~jwm/software/proftpd-ldap/.
I would not recommend the use of WU-FTPD, it has many security problems, and quite a few Linux vendors do not use WU-FTPD on their own ftp servers. I would highly recommend ProFTPD which is freely available and covered in the next section.
One of the main security mechanisms in WU-FTPD is the use of chroot. For example; by default all people logging in as anonymous have /home/ftp/ set as their root directory. They cannot get out of this and say look at the contents of /home/ or /etc/. The same can be applied to groups of users and / or individuals, for example you could set all users to be chroot'ed to /home/ when they ftp in, or in extreme cases of user privacy (say on a www server hosting multiple domains) set each user chroot'ed to within their own home directory. This is accomplished through the use of /etc/ftpaccess and /etc/passwd (man ftpaccess has all the info). I will give a few examples of what needs to be done to accomplish this since it can be quite confusing at first. ftpd also checks /etc/ftpusers and if the user attempting to login is listed in that file (like root should be) it will not let the user login via ftp.
To chroot users as they login into the ftp server is rather simple, but poorly documented. The ftp server check /etc/ftpaccess for guestgroups, which are simply "guestgroup some-group-on-the-system" i.e. "guestgroup users". The groupname needs to be defined in /etc/group and have members added. You need to edit their passwd file line so that the ftp server knows where to dump them. And since they are now chroot'ed into that directory on the system, they do not have access to /lib, etc so you must copy certain files into their dir for things like ls to work properly (always a nice touch).
Setting up a user (billybob) so that he can ftp in, and ends up chroot'ed in his home directory (because he keeps threatening to take the sysadmin possum hunting). In addition to this billybob can telnet in and change his password, but nothing else because he keeps trying to run ircbots on the system. The system he is on uses shadowed passwords, so that's why there is an 'x' in billybob's password field.
First off billybob needs a properly setup user account in /etc/passwd:
this means that the ftp server will chroot billybob into /home/billybob/ and chdir him into what is now / (/home/billybob to the rest of us). The ftpaccess man file covers this bit ok, and of course /usr/sbin/passwd needs to be listed in /etc/shells.
Secondly, for the ftp server to know that he is being chroot'ed he needs to be a member of a group (badusers, ftppeople, etc) that is defined in /etc/group. And then that group must be listed in /etc/ftpaccess.
Now you need to copy some libraries and binaries in the chroot jail, otherwise billybob won't be able to do a whole lot once he has ftp'ed in. The files needed are available as packages (usually called anonftp), once this is installed the files will be copied to /home/ftp/, you will notice there is an /etc/passwd, this is simply uses to map UID's to usernames, if you want billybob to see his username and not UID, add a line for him (i.e., copy his line from the real /etc/passwd to this one). The same applies to the group file as well.
without "billybob:*:500:500:::" in /home/billybob/etc/passwd:
drwxr-xr-x 2 500 500 1024 Jul 14 20:46 billybob
and with the line added to /home/billybob/etc/passwd:
drwxr-xr-x 2 billybob 500 1024 Jul 14 20:46 billybob
and with a line for billybob's group added to /home/billybob/etc/group:
drwxr-xr-x 2 billybob billybob 1024 Jul 14 20:46 billybob
Billybob can now ftp into the system, upload and download files from /home/billybob to his hearts content, change his password all on his own, and do no damage to the system, nor download the passwords file or other nasty things.
FTP is also a rather special protocol in that the clients connect to port 21 (typically) on the ftp server, and then port 20 of the ftp server connects to the client and that is the connection that the actual data is sent over. This means that port 20 has to make outgoing connections. Keep this in mind when setting up a firewall either to protect ftp servers or clients using ftp. As well there is 'passive' ftp and usually used by www browsers/etc, which involves incoming connections to the ftp server on high port numbers (instead of using 20 they agree on something else). If you intend to have a public ftp server put up a machine that JUST does the ftp serving, and nothing else, preferably outside of your internal LAN (see Practical Unix and Internet Security for discussions of this 'DMZ' concept). You can get WU-FTPD from ftp://ftp.wu-ftpd.org/.
NcFTPD is a high volume ftp server, however it is only free for personal or .edu usage. You can get it from: http://www.ncftpd.com/ncftpd/.
The BSD ftp server (ftpd) has also been ported over to Linux, so if you have the urge to run it you can. Download it at: ftp://quatramaran.ens.fr/pub/madore/ftpd-BSD/.
Muddleftpd is a small ftp server. You can get it at: http://www.computing.edu.au/~kuiperba/muddleftpd/.
Troll ftpd is an extremely small and relatively secure ftp server. It cannot execute external programs, and is quite easy to configure. You can get it at: http://www.troll.no/freebies/ftpd.html.
BetaFTPD is a single threaded, small ftp server. You can get it at: http://members.xoom.com/_XOOM/sneeze/betaftpd.html.
Another GPL licensed FTP server, available from: http://www.ftp4all.de/v3/noframes/.
Also a drop in replacement for your favorite ftpd (probably WU-FTPD), also available as a set of patches for WU-FTPD. This is highly appropriate as most servers have many users that require ftp access. The tarball is available at: ftp://ftp.uni-mainz.de/pub/internet/security/ssl/, and as RPM packages at ftp://ftp.zedz.net/pub/replay/linux/redhat/.
SRP can also be used to encrypt the username/password login portion of your ftp session, or the entire session. You can get SRP at http://srp.stanford.edu/srp/ and it is covered in the LASG here.
sftp runs over ssh which makes for relatively ftp sessions. You can get it from: http://www.xbill.org/sftp/.
Written by Kurt Seifried