Network services - FTP

By Kurt Seifried [email protected]



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 -D 21
ipfwadm -I -a accept -P tcp -S -D 21
ipfwadm -I -a deny -P tcp -S -D 21


ipchains -A input -p tcp -j ACCEPT -s -d 21
ipchains -A input -p tcp -j ACCEPT -s -d 21
ipchains -A input -p tcp -j DENY -s -d 21

An example of the same using TCP_WRAPPERS in /etc/hosts.allow:


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.

FTP servers

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.


Ok, the thing deserves a 1.x release version now, it seems to be doing
useful work on various production sites.

Before the 1.0 release details, something potentially interesting: my next
project. Before I start investigating the feasability, I want to judge the
demand. I'm considering a "vssshd", which would be a very cut down/minimal
server-only implementation of the ssh2 protocol. The intended audience
would be paranoid people who want no-frills secure remote access. I'm not
saying the current sshd implementations are insecure; however, their
design leaves something to be desired. In particular there seems to be
rather too much use of "root" (witness the severity of the deattack.c
flaw). I am tempted to investigate the possibility of writing a minimal
sshd where all protocol parsing and in particular SSL code runs as
non-root in a chroot() environment.


Approximate changelog:
- Fix build on RedHat7.2
- Fix build on Mandrake systems

vsftpd is an FTP server, or daemon. The "vs" stands for Very Secure.
Obviously this is not a guarantee, but a reflection that I have written
the entire codebase with security in mind, and carefully designed the
program to be resilient to attack.

Recent evidence shows that vsftpd is also extremely fast and scalable. vsftpd
has achieved ~4000 concurrent users on a single machine, in a production

vsftpd is now a proven stable solution. Of particular note, RedHat used vsftpd
to enable to support 15,000 concurrent users across their
server pool. This extreme load was generated by the release of RedHat 7.2
to the world.




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 Apache’s .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.

ProFTPD’s 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

Let’s 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 IP’s). 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 wouldn’t 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, all other machines will be denied access.

<Limit LOGIN>
Order Allow,Deny
Allow from 10.1.,
Deny from all

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 immediately gets bumped when they try to connect to port 21, as opposed to simply being denied login if it’s 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>

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>
<Limit READ>

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:


proftpd-ldap allows you to do password look ups using an LDAP directory, you can download it from:


WuFTPD used to have numerous security issues however 2 years ago a security audit was done by SuSE and many of the problems were removed. If you use WuFTPD make sure it is a descendant of the audited version (it should be unless the vendor is using an ancient codebase).

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 “guestgroup”’s, 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:

billybob:x:500:500:Billy Bob:/home/billybob/./:/usr/bin/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


NcFTPD is a high volume ftp server, however it is only free for personal or .edu usage. You can get it from:


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:


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 and it is covered in the LASG here.


sftp runs over ssh which makes for relatively ftp sessions. You can get it from:



Last updated on 1/9/2001

Copyright Kurt Seifried 2001 [email protected]