Setting up an FTP Server

An FTP server can be a very useful way to transfer files too big for e-mail or instant messaging. The default ftpd that comes with FreeBSD isn't bad, but proftpd has many more features, so its my FTP server of choice right now. If you have a dynamic ip address it will be extremely useful to enable the no-ip service to allow access to wan clients.

Assuming that you've finished that we can setup the server.

cd /usr/ports/ftp/proftpd
make install clean

That was painless enough. Don't worry though, there's plenty of configuration to come.

vi /etc/rc.conf

Add the following line:

proftpd_enable="yes"

Now we need to set create proftpd.scoreboard; otherwise proftpd won't start.

touch /var/run/proftpd.scoreboard

With that done we will set up our ftp group.

pw groupadd -n ftp

We added the group ftp to the system. Now it's time for us to set up the directory structure for Mr. FTP.

mkdir /home/ftp
cd /home/ftp
mkdir in pub
chown nobody in
chmod 5777 in

All right. /home/ftp is the root of our FTP server, in is for incoming files, and pub is for files you want to be downloadable. Make sure that only root can write to pub so people can't overwrite your files in there. The chown and chmod on in will ensure that users cannot overwrite eachother's files. It's possible that's not all you want for your directory structure. For instance you may have a lot of files saved in an area you don't want to move to ftp's home, but want accessible on the server. You would handle such a case like so:

mkdir /home/ftp/pub/media
mount_nullfs /fat/media /home/ftp/pub/media

Now an ftp user would be able to download files from /fat/media (/fat is the mounted partition). You probably don't want to give write permissions to this directory though! Of course you will want to set up a corresponding entry in fstab to do this all of the time.

/fat/media /home/ftp/pub/media nullfs rw 0 0

Now it's time to configure the server itself.

vi /usr/local/etc/proftpd.conf

If you'd like to save yourself some typing, you may download my configuration here. I will go over what each of these pieces mean.

ServerName     "FTP"
ServerType     standalone
DefaultServer  on
DefaultRoot    /home/ftp

This is some very basic configuration. The first line of course is the server's name. Choose as you please. You will definately want standalone for the second line; otherwise you'll have to mess around with inetd. Default root will set the root of the ftp. What it will do is make /home/ftp the root of the server, so users won't be able to cd to /. I don't want users to be browsing any other files on my computer. On to the next section.

Umask          022
MaxInstances   30
User           nobody
Group          nogroup
AllowOverwrite off

This is some of the user configuration. This is straight out of the default config, so don't worry about it.

MasqueradeAddress   username.no-ip.info
Port                50000
AllowForeignAddress on
PassivePorts        50001 52000

This is configuration for outside access to the server. First, replace username with your no-ip username. Then you must choose a port range on which you will run the ftp server. Because many hosts block port 21, you'll probably want to choose another one, in the high port range. In my case, I need to then forward ports 50000-52000 to my computer. Naturally, you'll want to have a static ip address setup.

AllowOverwrite off
AllowRetrieveRestart on

Those lines will not allow overwriting of files, and will allow users to resume downloads.

ScoreboardFile /var/run/proftpd.scoreboard
SystemLog /var/log/proftpd.sys
TransferLog /var/log/proftpd.xfer
ServerLog /var/log/proftpd.serv

There's the scoreboard file we created earlier. The next three lines all have to do with logging. It is not necessary, but I definately recommend keeping logs for troubleshooting and monitoring of traffic.

<Limit SITE_CHMOD>
  DenyAll
</Limit>

We will deny users the ability to change permissions on the ftp.

<Limit LOGIN>
  DenyAll
  AllowUser ftpuser
</Limit>

This will limit all logins except for ftpuser (some user on your system). You can add as many of these AllowUser lines as necessary. Later on we'll allow anonymous logins.

<Limit ALL>
  DenyAll
</Limit>

What we are doing here is giving ourselves a clean slate to work with. We are denying all ftp commands, so were we to not add allow statements later on, a user could do nothing. This will make sure users aren't doing things we don't want them to do.

<Limit CDUP CWD LIST PWD>
  AllowAll
</Limit>

Now we are allowing users to cd, ls, and pwd.

<Directory /home/ftp/in>
  <Limit STOR STOU>
    Allowall
  </Limit>
</Directory>

This is for our uploads directory (/in). We are allowing users to 'put' files into this directory. However, we have overwriting and deleting blocked.

<Directory /home/ftp/pub>
  <Limit READ>
    AllowAll
  </Limit>
</Directory>

This is for our downloads directory (/pub), and all subdirectories. This will allow users to 'get' files from this directory. Of course they can't delete or write or do any other things we would not like.

We've set up a server for users so far, but if you are interested in an anonymous ftp here is the relevant configuration:

MaxClients 10

<Anonymous /home/ftp>
  <Limit LOGIN>
    AllowAll
  </Limit>

  User ftp
  Group ftp
  UserAlias anonymous ftp
  RequireValidShell off
</Anonymous>

Add all of that if you want anonymous logins, otherwise leave it out. Thus concludes our configuration. The file is read only so to save it:

:w!

If you are going to use the anonymous config, you'll probably want to remove any users from the LOGIN directive. Also, you'll need to configure an ftp user.

vipw

This will allow us to create the ftp user. The editing is done in the same fashion as vi. Either find the line for the ftp user and edit it to match mine, or add the following line:

ftp:*:14:14:ftp:0:0:Mr. FTP:*:*

We've basically made a user with no valid password, no valid home directory, and no valid shell. It won't be used for any purposes other than this ftp. Now that the configuration is done, let's get our server started.

/usr/local/etc/rc.d/proftpd.sh start

Now is the time for you to test your ftp to make sure everything is working. I suggest using ftp on the command line, but alternatively you may use gftp, which is conveniently located in our apps section. Test uploading and downloading. Once you're convinced things are working nicely, get someone outside of your lan to test for you. If you have trouble, be sure to take a look at the server logs.