The FreeBSD Diary
Providing practical examples since 1998If you buy from Amazon USA, please support us by using this link.
Anonymous FTP server --- by Kim Scarborough 30 November 2001
This article was written by Kim Scarborough <firstname.lastname@example.org>. Reviewers include Nik Clayton, Crist J. Clark, and Yonatan Bokovza.
Although much of the purpose of anonymous FTP has been rendered obsolete by HTTP, it still has one advantage: allowing anonymous uploads. [Ed. note: see also upload files via http.]
Often, people want to give me files too large to send through e-mail, so I'd like them to be able to upload them to my FreeBSD box without having to give them accounts. Anonymous FTP is the natural solution, but setting it up to allow uploads yet still be reasonably secure takes care.
Warning: the method outlined below requires the use of SUIDDIR. This can be a security risk if used carelessly. I believe that the setup below takes sufficient precautions that it won't be a problem. But do be aware.
NOTE: FreeBSD's ftpd now supports the -o option to
create a write-only FTP site. This makes the FTP daemon deny all
downloads, irrespective of the file permissions. To check if your ftpd
includes this option, see
Step 1: Set up a new partition
The first danger to be considered when setting up anonymous FTP uploads is the possibility of people filling up your drive. CERT advises that the upload directory be on a dedicated drive; I think a dedicated partition will suffice just as well. Either way, this will ensure that the important system partitions will not be filled.
Carve out a separate partition that will just be for uploads. The size is up to you, but I would recommend 750MB, which will leave enough room in case somebody wants to upload an ISO. Don't worry about mounting it yet; we'll do that in a minute. Actually creating a partition is beyond the scope of this article. It is recommended that you read Chapter 12 of The FreeBSD Handbook for more information. Either that or you can use quotas to limit the space used by the ftp daemon.
Step 2: Add the FTP user
Your FreeBSD system may already contain an entry in the password file for the ftp daemon. Recent versions of FreeBSD include such an entry. If so, you can skip this step.
You'll need to create a user that anonymous FTP uploads and downloads will execute as. If you chose to allow anonymous FTP when you first installed FreeBSD, you'll already have it; otherwise, you'll need to create it. In either case, run vipw and make sure the entry looks like this:
ftp:*:14:14:ftp:0:0:Mr. Anonymous FTP:/home/ftp:/nonexistent
Let's go over that vipw entry (also see the man page for
Step 3: Set up the directory structure
Now we set up the directories people will see when FTP'ing in. Create the directory you set as ftp's's home directory; here
Here are the commands to set up those directories in the ftp user's home directory.
We will deal with directory permissions in Step 5
Step 4: Set up /etc/fstab and recompile the kernel
To keep people from being able to delete other people's uploaded files, we'll need SUIDDIR (explained in more detail below). We have to do two things to mount a file system SUIDDIR.
First, let's edit
/dev/ad2s2f /home/ftp/incoming ufs rw,SUIDDIR 2 2
Substitute the device of the partition you created in step 1. The SUIDDIR option must be specified at mount time for it
to work. See the man pages
Next, we need to enable SUIDDIR in the kernel. Add this option to your kernel configuration file:
Then configure, compile, install, and reboot to a new kernel.
Step 5: Setting permissions
When your system comes back up, do this:
chown -R root:wheel /home/ftp cd /home/ftp chmod 755 etc pub chown nobody incoming chmod 5777 incoming
[Ed. note: It was recomended by one reviewer that we not use
The directories should now look like this:
drwxr-xr-x 4 root wheel 512 Nov 10 00:42 . drwxr-xr-x 14 root wheel 512 Oct 20 14:58 .. drwxr-xr-x 2 root wheel 512 Nov 10 00:44 etc drwsrwxrwt 2 nobody wheel 512 Nov 10 00:45 incoming drwxr-xr-x 2 root wheel 512 Nov 25 00:44 pub
You may have noticed there's no
Here's why we did it that way. First, it's a bad idea to make anything owned by ftp; that would mean that the anonymous
user would essentially own all those files/directories and might possibly be able to change things around. The man page
We set the above items using
Add those values up and you get 5777.
Read the man page for
We might want to put a couple of files in
Step 6: Edit /etc/login.conf
One extremely crucial thing I haven't discussed before about anonymous FTP uploads: it is imperative that the
anonymous user not be allowed to download files from
The permissions of a newly-created file are set by the user's umask. The default umask for users under FreeBSD is 022, which means that files will be created 644 and directories 755. We want the files that the anonymous FTP user creates to be 640, so that once they're uploaded, they can't be downloaded (since the SUIDDIR changes the ownership). So the umask for ftp needs to be 027.
This is why we gave the ftp user its own login class in step 2. We can now change the umask for just that user.
Add this line to
Run the command:
to rebuild it, and we're set. Now the uploaded files will be mode 640 (directories will be created mode 750, which makes them rather useless, but that's a small downside to this setup). Since they won't belong to ftp, they can't be read, but they will show up in directory listings. This will stop the warez kiddies from using your site as a dropbox, since there's no point in uploading giant files if they can't subsequently be downloaded. You will still get occasional files that their scripts upload for testing, but these will be fairly small. Just keep an eye on it so you can clear these out.
Step 7: Restart ftpd
Now all we have to do is restart ftpd with logging enabled. The line in
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -lS
WARNING: If your ftpd includes the
That's the same as the default except for the "S" at the end, which will log anonymous transfers to
Now send a HUP single to (
Step 8: Test it to make sure it's right!
Be sure to test it out from a remote site; upload a file and make sure you can't download or delete it. If you don't verify everything is correct, your server will most likely become the target of warez kiddies.