How To: Set up a FTP Server in Linux

A mate of mine who shall remain nameless [cough]Shetboy[/cough] wanted to send me a 30MB file the other day, so at 30MB it’s not going to fit through email without splitting the file up and sending multiple emails with a section-per-mail, and we didn’t want to use dropsend either, so I ended up spending the best part of a day researching and setting up a FTP server on my box so he could just connect and upload the file. Here’s how I did it:

1.) Get yourself a FTP server

pro-FTPd seems to be the server of choice when I was researching, so I went with that and a copy of the docs (note that I’m not going to be using mysql for the user authentication, so I don’t need to get proftpd-mysql as well):

Shell

1

sudo apt-getinstall proftpd-basic proftpd-doc

When installing, it’ll pop up a window asking if you want a Standalone installation of FTPD, I did, and you probably do too, so just hit Next | Next | Finish or whatever to complete the installation.

2.) Get yourself a GUI to configure the server

This is optional, and you might just want to get elbow-deep in the config files, but I decided to use a GUI to configure most things, and then just tweak the resulting config file:

Shell

1

sudo apt-getinstall gadmin-tools

With that done (in Gnome, at least) you’ll have a set of GUI tools for configuring things, including proFTPd in your Applications | System Tools menu.

3.) Configure the FTP Server

This is the fun bit…

– Open GADMIN-PROFTPD and it’ll moan it doesn’t have a valid configuration file and ask you if you’d like to create a standard installation configuration, why yes, yes you would.
– As I’m not using mysql for authentication, and I don’t want to have to use real users of my system to connect, I’m going to use virtual users. To do so, just check the Enable virtual users checkbox.
– I don’t want my FTP running on the standard port (21), so I’ve moved the ftp service to run on port 2121
– I’m behind a router, so I need to tell proFTPd what my external IP is, for this guide, lets just say it’s 1.2.3.4. Enter whatever your external IP is (whatismyip.com comes in useful here) and don’t forget to change the NAT Router setting to On to enable it.
– We’re going to be using additional ports (i.e. passive FTP), so we need to leave the range of 49152 to 65534 alone, and we’re going to port-forward these from our router to our internal server IP later.

You should end up with something looking pretty much like this (bar entering YOUR external IP, not just 1.2.3.4):

4.) Set up your Virtual Users and Groups

If we want to use actual system users (i.e. user accounts which exist to log in to our machine) we can, but it’s a bit safer to use virtual users, and do you really want to create additional accounts on your machine when you don’t have to? Thought not. So to create our virtual users we use a script called ftpasswd which comes with proFTPd.

The ftpasswd tool creates your user and group files in your present working directory, if we move to where we want them to be created first, we don’t have to move them later.

The name field is the username you want to use to log in to your ftp server.

/home/ftpuploads is a directory I’ve created to store all the FTP files we’re going to serve, and is the location files will be uploaded to. You’ll need to create this directory, or another directory and then set them to be owned by the nobody group and user by using sudo chown nobody /home/ftpuploads and sudo chgrp nobody /etc/ftpuploads commands.

–shell=/dev/null disables any FTP users from starting their own shell session where they could potentially cause mischief.

–uid=xxxx and –gid=xxxx – A virtual user must have a UserID and GroupID. You don’t have to use 5000 for them, just any unused User and Group IDs will do – and I picked 5000 out of the air as they’re both free on my box.

After hitting enter you’ll be prompted for the user’s desired password and confirmation of the password, then a file called ftpd.passwd will be written in your current directory.

Next we need to create the group access file using ftpasswd again as follows:

Shell

1

sudo ftpasswd--group--name=ftpd--gid=5000--member=ftpmonkey

The group name can be anything you want, and make sure you put the same gid value as you used when creating your user(s) above. If you’ve got multiple users you want to be able to connect to your FTP server, just add on additional –member=someuser –member=anotheruser switches when creating the group.

If you want to add additional users later on, just create a new user using ftpasswd as we’ve done above but specify a different, unique UID for the user, then edit the ftpd.group file and tack on the users you’ve just created. For example, you’d modify the ftpd.group file so that:

1

ftpd:x:5000:ftpmonkey

became:

1

ftpd:x:5000:ftpmonkey,someuser,anotheruser

Note: You may need to add write permissions to ftpd.passwd and ftpd.conf via sudo chmod 644 ./ftpd.passwd and sudo chmod 644 ./ftpd.group if you want to manually edit them.

Finally, don’t forget to add in your new users as allowed to login to the FTP server from the proftpd.conf file by finding the section at the bottom that looks like (angle brackets changed to square brackets in the below text to avoid HTML woes):

1

2

3

4

[Limit LOGIN]

AllowUser ftpmonkey

DenyALL

[/Limit]

and changing it to something like:

1

2

3

4

5

6

[Limit LOGIN]

AllowUser ftpmonkey

AllowUser someuser

AllowUser anotheruser

DenyALL

[/Limit]

5.) Tweak the config

We used GADMIN-PROFTPD to create our initial configuration (which is stored in /etc/proftpd/proftpd.conf), now we’re going to tweak it a little to use our created passwd and group files. To do this, add in the following lines to the top of your proftpd.conf file (making sure you don’t have the same directives twice! i.e. if there’s another AuthUserFile directive somewhere, remove it etc.):

1

2

3

4

5

6

7

8

9

10

DenyFilter\*.*/

# Use this to jail all users in their homes

DefaultRoot~

ServerType standalone

DefaultServer on

Umask022022

# Authentication using AuthUserFile

AuthUserFile/etc/proftpd/ftpd.passwd

# AuthOrder to use mod_auth_file.c only, no local user allowed

AuthOrder mod_auth_file.c

Once you’ve done this, strip out the Anonymous section from the bottom of the file – we don’t want anonymous logins, and GADMIN-PROFTPD uses a cludgy, incorrect way to try to add in users as anonymous users anyway.

7.) Open it up to the world

If you can connect from inside your local network, and you want users to be able to access the FTP server from anywhere, we need to do a bit of port-forwarding to allow the server to be accessed from the outside world. Port forwarding is a big topic, and I’m not going to cover it in depth here – if you need help try portforward.com, but what we’re going to do is forward port 2121 to the local IP of our FTP server (in my case the FTP server’s just running on my laptop at local IP 192.168.1.101), and then port forward the range of ports 49152 to 65534 for our actual FTP traffic.

I tried doing this initially with the DD-WRT firmware on my router, but the router config had got a bit mangled and wouldn’t work properly. As I’d been meaning to move to the Tomato firmware anyway, I just threw that on the router and things started working properly in no-time, so just be aware that your router and not your FTP configuration can be the weak link when things aren’t working sometimes.

If you get a login box then your port-forwards are fine. If you can’t login you need to stop the FTP server and go look at the Virtual Users part again then restart the FTP server. If you can access and login, but can’t upload or download, you need to look at your ftpuploads directory and maybe change the permissions on them (try sudo chgrp 5000 /home/ftpuploads -R, for example).

Last thing, try using FileZilla or something to upload some files to your FTP server – if it works, you’ve done it. Congrats!

Oh, and the mate who wanted to FTP me a 30MB file? He’d misread the file size – it was actually 3MB… ls -alh ftw!

Final note: If you’re running DD-WRT on your router, and want to change to the Tomato firmware, don’t forget to telnet into the router and get the password hash first!