Setting up a secure FTP server

I can’t believe I haven’t written this up before as I’ve been using an ftp server long enough! There are several different FTP servers available, including ProFTPD, WU-FTPD, Pure-FTPd, and vsftpd.

There are advantages and disadvantages to each of them but I eventually chose vsftpd, mainly because I wanted users to be able to give each user FTP access to their home folders and didn’t want them to be able to access the rest of the file system – something that vsftpd supports and which is how I’ve configured it below.

Note – I used Raspbian (wheezy) running on a Raspberry Pi but these instructions should also work on Debian (tested using squeeze, and jessie) as well as Ubuntu.

Update Current Packages

Before downloading and installing anything we need to be running as root and it is a good idea to make sure that your system is up to date.

$ su


$ sudo -i

# apt-get update;apt-get upgrade
# apt-get update;apt-get upgrade
Get:1 jessie InRelease [15.0 kB]
Fetched 9130 kB in 39s (234 kB/s)
Reading package lists... Done
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Configure the Firewall

Next we need to allow incoming TCP connections to port 21 as this is the network port that the FTP protocol uses. In this case my subnet mask is and my network address is (basically all the machines on the network have IP addresses in the range to, if you use a different range of addresses you will need to modify the command accordingly.

# ufw allow from to any port 21 proto tcp
Rules updated

Then check the firewall status to make sure the rule has been applied. I’m using SSH to connect so there is also an existing rule (shown in blue) to allow incoming SSH connections on port 22.

# ufw status
Status: active
To                         Action      From
--                         ------      ----
22/tcp                     ALLOW
21/tcp                     ALLOW


Installing vsftpd is quite straight forward.

# apt-get install vsftpd
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Recommended packages:
  logrotate ssl-cert
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 139 kB of archives.
After this operation, 252 kB of additional disk space will be used.
Setting up vsftpd (3.0.2-17) ...
Processing triggers for systemd (215-17+deb8u2) ...

Just to make sure it worked check to see if there is an vsftpd process listening on port 21.

# netstat -npl|grep vsftpd
tcp6   0      0 :::21           :::*            LISTEN      1984/vsftpd     

Then stop the deamon while we configure it…

# /etc/init.d/vsftpd stop
Stopping vsftpd (via systemctl): vsftpd.service.


In most cases the only thing that is necessary to make the changes required to the configuration file is to uncomment the line, but in some cases you will need to change the default value.

One of the things I liked about vsftpd was the fact that user accounts can be prevented for viewing files outside their own home directories which prevents them from accessing files on the rest of the system, and I also configure the deamon to use a nondescript connection message as otherwise anyone that connects to the server will be able to see which version of FTP you are using.

By default vsftpd will use IPv6 but my own network still uses IPv4.

# nano /etc/vsftpd.conf
# Run standalone?  vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
# Uncomment this to allow local users to log in.

# Uncomment this to enable any form of FTP write command.

# You may restrict local users to their home directories.  See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.

# You may fully customise the login banner string:

When all the changes are made, the deamon can be restarted.

# /etc/init.d/vsftpd start
Starting vsftpd (via systemctl): vsftpd.service.


We can test it is working using the ftp client, this may already be installed but if it isn't it can be installed using 'apt-get install ftp'.

# ftp localhost
Connected to localhost.
220 Connected...
Name (localhost:root): pi
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls -alis
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1004     1004         4096 Nov 29 02:22 .
drwxr-xr-x    7 0        0            4096 Nov 29 02:22 ..
-rw-r--r--    1 1004     1004          220 Nov 29 02:22 .bash_logout
-rw-r--r--    1 1004     1004         3515 Nov 29 02:22 .bashrc
-rw-r--r--    1 1004     1004          675 Nov 29 02:22 .profile
226 Directory send OK.
ftp> quit
221 Goodbye.

Note - This example assumes that the local user's username is 'pi'.

Raspberry Pi is a trademark of the Raspberry Pi Foundation

This entry was posted in Debian, Linux, Networking, Raspbian, Ubuntu and tagged , , , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.