auf.suno
Connector, investor, futurist, geek, software developer, innovator, sportsman, libertarian, business enabler, cosmopolitan, autodidact, funny finch, tech evangelist,
purist, agnostic, Kärnten fan, foodie, artist, globetrotter, social liberal but fiscal conservative, Schöngeist... elegantiorum litterarum amans oder studiosus...

This is the website of Markus Gattol. It is composed, driven and secured/encrypted exclusively by Open Source Software. The speciality of this website
is that it is seamlessly integrating into my daily working environment (Python + MongoDB + Linux + SSH + GIT + ZeroMQ) which therefore means it
becomes a fully fledged and automatized publishing and communication platform. It will be under construction until 2014.

Open Source / Free Software, because freedom is in everyone's language...
Frihed Svoboda Libertà Vrijheid เสรีภาพ Liberté Freiheit Cê̤ṳ-iù Ελευθερία Свобода חרות Bebas Libertada 自由
auf.suno
Website Sections
Home
FAQs
About Me
Tweets by @markusgattol
Very Secure File Transport Protocol Daemon
Status: Done except for the "Virtual Users..." section.
Last changed: Saturday 2015-01-10 18:32 UTC
Abstract:

The FTP (File Transfer Protocol) is used as one of the most common means of copying files between computers over the Internet. Most web based download sites use the built in FTP capabilities of web browsers and therefore most server oriented operating systems usually include an FTP server application as part of the software suite. Linux is no exception. With this page I will show how to convert a DebianGNU/Linux box into an FTP server using the vsftpd (Very Secure FTP Daemon) package which is included with the standard Debian distribution i.e. no need to compile anything ourselves which saves time and makes things work even for the inexperienced users.
Table of Contents
Overview
FTP Types
The File Transfer Protocol And Firewalls
Installing and Configuring vsftpd
Standalone or (x)inetd
Starting / Stoping and Status Test of vsftpd
Configuring vsftpd
Virtual Users with vsftp

The initially installed configuration for vsftpd provides full download access for anonymous users. I am going to cover some of the basic configuration parameters and identify some settings to improve security for authorized access only. We will then also see how easy it is to create a highly secure FTP environment with vsftpd — vsftpd can operate in a chroot jail and now supports TLS/SSL encryption.

Overview

FTP and therefore vsftpd relies on a pair of TCP (Transmission Control Protocol) ports to get the job done. It operates in two connection channels:

  1. FTP Control Channel, TCP Port 21: All commands we send and the ftp server's responses to those commands will go over the control connection, but any data sent back (such as ls directory lists or actual file data in either direction) will go over the data connection i.e. TCP Port 20.
  2. FTP Data Channel, TCP Port 20: This port is used for all subsequent data transfers between the client and server.

In addition to these channels, there are several varieties of FTP as I will explain below.

FTP Types

From a networking perspective, the two main types of FTP are active FTP and passive FTP. In active FTP mode, the FTP server initiates a data transfer connection back to the client. For passive FTP mode, the connection is initiated from the FTP client. From a user management perspective there are also two types of FTP — regular FTP in which files are transferred using the username and password of a regular user on the FTP server, and anonymous FTP in which general access is provided to the FTP server using a well known universal login method. So we have

  • active FTP (the server takes an active part in communications)
  • passive FTP (the server takes an passive part in communications)

  • regular FTP (communications happens based on a systems users password and user name)
  • anonymous FTP (general access is provided to the FTP server and its services without he need for special authentication)
  • virtual FTP users (last but not least, there is another method which is sort of regular FTP from a users point of view but more like anonymous FTP from a FTP's system administrators point of view)

Except for the virtual FTP users scenario, setting up and configuring vsftpd is a straight forward task as I will show. Dealing with virtual FTP users on the other hand involves not just only vsftpd but also a database (e.g. PostgreSQL, MySQL, etc.) and its auxiliary tools. Therefore I am going to cover virtual FTP users in a dedicated subsection further down.

We are now going to discuss the four basic cases (active/passive FTP and regular/anonymous FTP) that we are dealing with anytime we use some FTP client like ncftp or lftp for example (I recommend the latter one).

Active / Passive FTP

vsftpd runs in passive FTP mode per default i.e. pasv_enable=YES. It can be switched into active mode by setting pasv_enable=NO. The sequence of events for active FTP is as follows

  1. Our client (e.g. ncftp) connects to the FTP server by establishing an FTP control connection to port 21 on the server. Our commands such as ls and get are sent over this connection. The client itself uses a so-called high port i.e. > 1023 (port 5001 for example).
  2. Whenever the client requests data over the control connection, the server initiates data transfer connections back to the client. The source port of these data transfer connections is always port 20 on the server, and the destination port is a high port (> 1023) on the client — not the same however that was used during step 1 however (port 5002 for example).
  3. Thus the ls listing that we asked for on the server comes back over the port 20 on the server to a high port connection on the client. No use of port 21 on the server is made to send back the results of the ls command on the server.

FTP active mode therefore transfers data in a counter intuitive way to the TCP standard, as it selects port 20 as its source port on the server (not a random high port greater than 1023) and connects back to the client on a random high port that has been pre-negotiated on the port 21 control connection.

Active FTP may fail in cases where the client is protected from the Internet via NAT (Network Address Translation) or a firewall. If our client is behind a firewall, then step 2 (in the diagram below) will most probably fail.

Our client is listening on port 5002, waiting for the server to connect to it but the server will fail to connect to the client's port as it is behind the firewall — it cannot be determined which port to open on firewall as its randomly generated during step 1. Another obstacle is with NAT as it is also impossible to determine the port of the incoming data transfer connection in advance.

Passive FTP works differently as is explained below

  1. Our client connects to the FTP server by establishing an FTP control connection to port 21 of the server. Our commands such as ls and get are sent over that connection. Again the client used a high port. So, this step is the same for active as well as passive FTP mode.
  2. Whenever the client requests data over the control connection, the client initiates the data transfer connections to the server. The source port of these data transfer connections is always a high port on the client (e.g. 5002) with a destination port on the server which also happens to be a high port (e.g. 6342).

Passive FTP should be viewed as the server never making an active attempt to connect to the client for FTP data transfers. Because the client always initiates the required connections, passive FTP works better for clients protected by a firewall — many firewalls generally allow outgoing connections.

As Windows defaults to active FTP, and Linux defaults to passive FTP mode, most of us probably have to accommodate both forms when deciding upon a security policy for our FTP servers. However, since this is out of scope for this article, I am not going to detail it... one just has to configure his firewall and the like correctly to allow for both (active and passive) forms of FTP connections.

Regular / Anonymous FTP

Regular FTP: By default, the vsftpd package allows regular users (existing accounts on our Debian box) to copy files to and from their home directories with an FTP client using their usernames and passwords as their login credentials. This is a very pleasant and easy to use and set up method to allow registered users to up/download files to/from a server — this is how vsftpd is used for the most part.

vsftpd also has the option of allowing this type of access to only a group of Linux users, enabling system administrators to restrict the addition of new files to authorized personnel only.

The disadvantage of regular FTP is that it is not suitable for general mass distribution of data as everyone either has to get a unique user account on the server or has to use a shared username and password. As we will see below, anonymous FTP allows us to avoid this difficulty. Also, regular FTP is not quite suitable for huge amounts of registered users. Therefore, vsftpd can be set up for virtual users i.e. users that can also up and download and have login credentials to the server but which do not have a user account on our server.


Anonymous FTP: Anonymous FTP is the choice of websites that need to exchange files with numerous unknown remote users. Common uses include downloading software and data like mp3s and uploading diagnostic information for a technical support engineer's attention and the like.

Unlike regular FTP, where we login with a preconfigured Linux username and password, anonymous FTP requires only a username of anonymous and our email address for the password if at all — some setups allow anyone to establish an ftp connection without requiring any user specific information.

Once logged into a vsftp server, we automatically have access to only the default anonymous FTP directory (/var/ftp, as default with vsftp) and all its subdirectories.

The File Transfer Protocol And Firewalls

FTP frequently fails when the data has to pass through a firewall, because firewalls are designed to limit data flows to predictable ports and FTP uses a wide range of unpredictable TCP ports. We have a choice of methods to overcome this as I will explain. However, before I start, let us shortly recap what we know so far:

  • In general, Unix systems and therefore also DebianGNU/Linux use passive FTP per default.
  • Windows uses active FTP per default.
  • With active FTP, the client first initiates the control connection and only after that, the server initiates the data transfer connection back to the client.
  • With passive FTP, both, the control connection as well as the data transfer connection is initiated by the client.

Client Protected By A Firewall Problem

Typically firewalls do not allow any incoming connections at all, which frequently blocks active FTP from functioning — therefore users on Windows might face problems with active FTP (see above).

With this type of FTP failure, the active FTP connection appears to work when the client initiates an outbound connection to the server on port 21. The connection then appears to hang, however, as soon as we use the ls, dir, or get commands. The reason is that the firewall is blocking the return connection from the server to the client (from port 20 on the server to a high port on the client).

If a firewall allows all outbound connections to the Internet, then passive FTP clients behind a firewall will usually work correctly as the clients initiate all the FTP connections — therefore, users of some Unix flavor should generally not have such problems. The following table shows how a firewall needs to be configured on the client respectively the client's LAN (Local Area Network) gateway in order to allow for active respectively passive FTP to function properly:

Method Source Address Source Port Destination Address Destination Port Connection Type Who initiates
Control Channel1 FTP client respectively LAN Gateway high port FTP server 21 New Client
FTP server 21 FTP client respectively LAN Gateway high port Established
Active FTP2 FTP server 20 FTP client respectively LAN Gateway high port New Server
FTP client respectively LAN Gateway high port FTP server 20 Established
Passive FTP2 FTP client respectively LAN Gateway high port FTP server high port New Client
FTP server high port FTP client respectively LAN Gateway high port Established

Server Protected By A Firewall Problem

Typically firewalls do not let any connections come in at all. When a an incorrectly configured firewall protects an FTP server, the FTP connection from the client does not appear to work at all for both active and passive FTP. The following table shows how a firewall needs to be configured on the server side in order to allow for active respectively passive FTP to function properly:

Method Source Address Source Port Destination Address Destination Port Connection Type Who initiates
Control Channel3 FTP client respectively LAN Gateway high port FTP server 21 New Client
FTP server 21 FTP client respectively LAN Gateway high port Established
Active FTP4 FTP server 20 FTP client respectively LAN Gateway high port New Server
FTP client respectively LAN Gateway high port FTP server 20 Established
Passive FTP4 FTP client respectively LAN Gateway high port FTP server high port New Client
FTP server high port FTP client respectively LAN Gateway high port Established

Installing and Configuring vsftpd

Just issuing aptitude install vsftpd does the trick. One might of course also use apt-get, synaptic etc. to get the job done. I have already installed it on my workstation as can be seen (the dpl is just one of my aliases in my .bashrc).

sa@wks:~$ type dpl
dpl is aliased to `dpkg -l'
sa@wks:~$ dpl vsf* | grep ^ii
ii  vsftpd         2.0.6-1.1      The Very Secure FTP Daemon
sa@wks:~$

Standalone or (x)inetd

vsftpd can be launched via a super-server such as inetd or xinetd. Alternatively, vsftpd can be launched in standalone mode, in which case vsftpd itself will listen on the network. I recommend the latter mode simply because it is easier to use and wanted in most cases when there are frequent activities with FTP going on. Standalone mode is activated by setting listen=YES in /etc/vsftpd.conf. Direct execution of the vsftpd binary will then launch the FTP service and make a computer running vsftpd ready for immediate client connections.

Starting / Stoping and Status Test of vsftpd

Actually, there is no need for us to do anything since, during installation, all the setup of vsftpd is done automatically — the sysvinit process takes care of starting and stopping vsftpd

sa@wks:~$ find /etc/rc* -name *vsftp*
/etc/rc0.d/K20vsftpd
/etc/rc1.d/K20vsftpd
/etc/rc2.d/S20vsftpd
/etc/rc3.d/S20vsftpd
/etc/rc4.d/S20vsftpd
/etc/rc5.d/S20vsftpd
/etc/rc6.d/K20vsftpd
sa@wks:~$

Should anyone need to start/stop vsftpd manually then

 1  sa@wks:~$ su
 2  Password:
 3  wks:/home/sa# cd /etc/init.d/
 4  wks:/etc/init.d# vsftpd start
 5  500 OOPS: vsftpd: cannot open config file:start
 6  wks:/etc/init.d# ./vsftpd start
 7  Starting FTP server: vsftpd.
 8  wks:/etc/init.d# ps aux | grep vsftp
 9  root     20698  0.0  0.0   3724   948 ?        S    19:12   0:00 /usr/sbin/vsftpd
10  root     20700  0.0  0.0   2172   672 pts/3    S+   19:12   0:00 grep vsftp
11  wks:/etc/init.d# netstat -ple | egrep -m2 ^Proto\|:ftp
12  Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
13  tcp        0      0 *:ftp                   *:*                     LISTEN      root       2940584     20698/vsftpd
14  wks:/home/sa# netstat -plen | egrep -m2 ^Proto\|vsftp
15  Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
16  tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN      0          2940584     20698/vsftpd
17  wks:/etc/init.d# exit
18  exit
19  sa@wks:~$

for example line 6 does the trick. Other than start, stop and restart may be used. The funny thing I showed on purpose in line 4 is because it seems many people seem to stumble over it. What line 4 actually does is to feed the parameter start to the vsftpd binary as we can see

sa@wks:~$ su
Password:
wks:/home/sa# file `which vsftpd`
/usr/sbin/vsftpd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped
wks:/home/sa# exit
exit
sa@wks:~$

Of course, that is not working as line 5 shows. Rather than harassing the vsftpd binary we should feed the start parameter to the init script for vsftpd as line 6 shows. All it took was ./ in order to the get the path right. Lines 8 to 19 are just showing that vsftpd is now running and listening on the tcp port (port 21 as line 16 shows). Also, the PIDs (Process Identifiers) in lines 9 and 13 respectively 16 match just as they should.

Configuring vsftpd

Without a configuration file, vsftpd uses its compiled-in default settings. As soon as vsftpd notices a configuration file, its contents are used to configure vsftpd. vsftpd reads the contents of its configuration file (/etc/vsftpd.conf) only when it starts — therefore we will have to restart vsftpd each time we edit the file in order for the changes to take effect.

Default (Anonymous FTP)

As we already know from above, this mode does not require special login credentials for those who either want to download or upload data from/to our FTP server. We can enable or disable both — (download respectively upload for anonymous users that is) or just one of them.

Download for Anonymous Users

By default, /etc/vsftpd.conf uses a number of default settings:

 1  sa@wks:~$ grep -v \# /etc/vsftpd.conf
 2  listen=YES
 3  anonymous_enable=YES
 4  dirmessage_enable=YES
 5  xferlog_enable=YES
 6  connect_from_port_20=YES
 7  secure_chroot_dir=/var/run/vsftpd
 8  pam_service_name=vsftpd
 9  rsa_cert_file=/etc/ssl/certs/vsftpd.pem
10  sa@wks:~$

Lines 2 to 9 show a pristine /etc/vsftpd.conf that comes with installing vsftpd on Debian. I am not going to explain the meaning of lines 2 to 9 since it is perfectly documented in the configuration file itself. One should go read the comments now if not already done so.


There is anon_root (see manual file) which, if not set otherwise, defaults to /var/ftp i.e. this is the directory where we put all the stuff that we would allow people to download. We could however set anon_root=/data/ftp_distribute or anything else and then put our data (movies, source code, pictures, mp3s, etc.) to /data/ftp_distribute so others could download it in anonymous FTP mode.

Upload for Anonymous Users

Nothing I would recommend to do. While configuring vsftpd for anonymous download is perfectly fine for mass distribution of data, enabling it for anonymous upload might cause problems.

For example, allowing anonymous users the ability to upload files to the FTP server has the potential to allow users of pirate software to abuse our system for further distribution or simply pump our data partition full of data until there is no more space left which, in the worst case (server has not been configured with a separate partition for the FTP up/download area) might cause the whole system to halt.


If someone still wants to go for it, setting a few parameters might be a good idea:

anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_max_rate=1048576
max_clients=10
max_per_ip=2\

plus of course, put the up/download area onto a dedicated partition. Those who are uncertain about the rate for anon_max_rate and its numeric option (1048576) might go here and return afterward.

The value I set for anon_max_rate above is 1 Mibit/sec... the maths is as follows 2^20 bit/sec = 1048576 bit/sec = 1 Mibit/sec. Or to put it into numbers one can easier understand, most folks in Central Europe as of now (July 2008) have a bandwidth @home which is around (download) 15-30 Mibit/sec in urban areas like for example Vienna and around 5Mibit/sec in rural areas like for example Turrach where my parents live and where I am sitting right now and typing these lines... only sun, stunning nature, funny animals and super-friendly people and well, /me, the WWW and thus the community at my fingertips ;-]

Login for known Users only

As an example, if we wanted to disallow anonymous FTP and only allow login for users which have an account on the machine where vsftpd is running, then we might change the standard configuration file to look as what can be seen below.

What is new here are lines 4, 5, 9 and 13. Line 3 has been changed to NO — this is important since just uncommenting it has the same effect as setting it to YES. Again, the meaning is perfectly well explained in the configuration file itself respectively the manual file for vsftpd (man 5 vsftpd.conf).

 1  notroot@rd0:~$ grep -v \# /etc/vsftpd.conf
 2  listen=YES
 3  anonymous_enable=NO
 4  local_enable=YES
 5  write_enable=YES
 6  dirmessage_enable=YES
 7  xferlog_enable=YES
 8  connect_from_port_20=YES
 9  chroot_local_user=YES
10  secure_chroot_dir=/var/run/vsftpd
11  pam_service_name=vsftpd
12  rsa_cert_file=/etc/ssl/certs/vsftpd.pem
13  listen_port=28432
14  notroot@rd0:~$

Assuming that we had created a user account for the user greg with adduser (one should use adduser instead of useradd; useradd is a low-level tool), we are now able to log into this machine using the user credentials of greg (this time vsftpd is not listening on standard port 21 but on port 28432 as set in line 13 above).

  • With ncftp it might look like this ncftp -u greg -p <greg's_password> -P 28432 <ip_address_of_server_where_vsftpd_is_running>
  • Using lftp it looks like this lftp -u greg,<greg's_password> -p 28432 <ip_address_of_server_where_vsftpd_is_running>

This setup is often used when someone needs to get going quickly but wants to limit login to just a few, well-known, users and also be moderately safe (moving listening port to a high port). However, still there is no encryption with both of the now mentioned examples. The next example setup for vsftpd will demonstrate how to introduce encryption (for the FTP Control Channel, TCP Port 21 as well as for the FTP Data Channel, TCP Port 20).

vsftpd with SSL Encryption

One should only enable TLS/SSL if he really needs it. If we only intend to cater for anonymous users on our server, then enabling encryption is overkill and one is better of with anonymous FTP as described above.


The FTP protocol (RFC959) has a number of security drawbacks, one of which is, FTP logins and data transfers are not encrypted. However, we can activate SSL (Secure Sockets Layer) respectively TLS (Transport Layer Security) encryption (RFC2228) with vsftpd in order to make vsftpd a lot more secure. Using TLS/SSL encryption with FTP is also known as FTPS (FTP/SSL). Data is then encrypted in the command channel, the data channel, or most often both. FTPS is a name used to encompass a number of ways in which FTP software can perform secure file transfers. Each way involves the use of a SSL/TLS layer below the standard FTP protocol to encrypt the control and/or data channels. FTPS should not be confused with either SFTP (SSH File Transfer Protocol), or FTP over SSH. Also, SCP (Secure Copy) is a different kind of thing and has nothing to do with FTPS.


In order to make use of FTPS, an FPTS enabled FTP client is needed as well. I recommend lftp. In fact, lftp is the FTP client which I use exclusively now simply because of its amazing feature set, stability and the fact that it is a mature piece of software.

Because FTP is a port-hopping protocol (i.e. data channels use a random port chosen during the communication; see above), many firewalls have the ability to understand the FTP protocol and allow the secondary data connections. However if the control connection is encrypted using TLS/SSL the firewall is not able to get the port numbers of the data connections from the control connection (since it is encrypted and the firewall cannot decrypt it). Therefore in many firewalled networks clear FTP connections will work while FTPS connections will either completely fail or require the use of passive FTP mode.

Testing for SSL/TLS Support

The release of vsftpd version 2 brought some major updates which of the most notable is the inclusion of TLS/SSL encryption for securing authentication and data transfers between FTP clients and an FTP server. To enable the TLS/SSL security controls, the vsftpd version must have been compiled with its support. To find out if our version has been compiled with SSL support, we execute the following command

1  sa@wks:~$ su
2  Password:
3  wks:/home/sa# ldd `which vsftpd` | grep ssl
4          libssl.so.0.9.8 => /usr/lib/i686/cmov/libssl.so.0.9.8 (0xb7e9c000)
5  wks:/home/sa# exit
6  exit
7  sa@wks:~$

If the command displays the libssl shared object as it does in line 4 above, then our version is ready to support TLS/SSL. If libssl is not in the output then our version of vsftpd does not support encryption. In that case, we will either have to recompile the source code ourselves or go knock on the colleagues DD's door ;-]

Creating the Certificate/Key for Encryption

What we are going to introduce is called a PKI (Public Key Infrastructure). It is an arrangement that binds public keys with respective user identities by means of a certificate authority. The user identity must be unique for each certificate authority i.e. no other FTP server can have the same certificate.

Before vsftpd is able to do any encryption, it requires the generation of a private key and a digital certificate. During the key generation process we will be asked several questions with regards to server name, organizational name, country code etc. All values which are individual to any environment and therefore anyone has to provide his individual data. (I am going to use some phony input for demonstration purposes in the following example).

1  sa@wks:~$ su
2  Password:
3  wks:/home/sa# mkdir -p /etc/pki/tls/certs && cd /etc/pki/tls/certs/

There is nothing special about lines 1 to 3. We only create a new directory (if not already in place) and change into it.


Next we are going to create a so-called self-signed certificate i.e. not one signed by some CA (Certification Authority) but just by ourselves. If we needed one signed by some CA (e.g. VeriSign) then that would work too of course5. For those of us which are using the server for a legitimate business and want to provide a level of security assurance to their customers its certainly a very good idea to use a key that has been signed by a CA.

First we need to decide whether or not we want to encrypt our key. Doing so means that the key is protected by a passphrase. On the plus side, adding a passphrase to a key makes it more secure, so the key is less likely to be useful to someone who steals it. The downside, however, is that we would have to either store the passphrase in a file or type it manually every time we want to start our ftp, web or ldap, etc. server. It violates my normally paranoid nature to say it, but mostly I prefer unencrypted keys (except for high-security environments that I deal with), so I do not have to manually type a passphrase each time a secure daemon is started. However, using an encrypted key it is not terribly difficult to decrypt it should we later tire of typing a passphrase.


We will now create a file called mycert.pem which will contain both the private key and the public certificate based on it. We will also create a file called mycertkey.pem which will contain the key on its own — just in case we might need it later on. The certificate will be valid for 730 days, and the key (thanks to the -nodes option) is unencrypted.

openssl req -x509 -nodes -days 730 -newkey rsa:1024 -keyout /etc/pki/tls/certs/mycertkey.pem -out /etc/pki/tls/certs/mycert.pem

Using this command-line invocation (see openssl req -h for more information), we will have to answer a lot of questions:

  • Country Name
  • State
  • City
  • etc.
  • The tricky question is Common Name. We need to answer it with the hostname or CNAME by which people will address the server. This is very important. If our web server's real hostname is mybox.mydomain.com but people will be using www.mydomain.com to address the box, then we have to use the latter name to answer the Common Name question.

Once we are comfortable with the answers we provided to those questions, we can script the whole thing by adding the -subj option as can be seen below. I have included some information about location into the example that follows, but the only thing that we really need to include for the certificate to be usable is the hostname respectively CNAME.

openssl req -x509 -nodes -days 730 -subj '/C=US/ST=Oregon/L=Portland/CN=www.foo.com' -newkey rsa:1024 -keyout /etc/pki/tls/certs/mycertkey.pem -out /etc/pki/tls/certs/mycert.pem

Now, let us put the afore mentioned right into practice, step by step:

 4  wks:/etc/pki/tls/certs# ls -la
 5  total 8
 6  drwxr-xr-x 2 root root 4096 2008-06-30 12:53 .
 7  drwxr-xr-x 3 root root 4096 2008-06-30 12:53 ..
 8  wks:/etc/pki/tls/certs# openssl req -x509 -nodes -days 730 -newkey rsa:1024 -keyout /etc/pki/tls/certs/mycertkey.pem -out /etc/pki/tls/certs/mycert.pem
 9  Generating a 1024 bit RSA private key
10 .................++++++
11 ................................++++++
12  writing new private key to '/etc/pki/tls/certs/mycertkey.pem'
13  -----
14  You are about to be asked to enter information that will be incorporated
15  into your certificate request.
16  What you are about to enter is what is called a Distinguished Name or a DN.
17  There are quite a few fields but you can leave some blank
18  For some fields there will be a default value,
19  If you enter '.', the field will be left blank.
20  -----
21  Country Name (2 letter code) [AU]:US
22  State or Province Name (full name) [Some-State]:Oregon
23  Locality Name (eg, city) []:Portland
24  Organization Name (eg, company) [Internet Widgits Pty Ltd]:Foo Ltd
25  Organizational Unit Name (eg, section) []:Foo IT Department
26  Common Name (eg, YOUR name) []:www.foo.com
27  Email Address []:wizard@foo.com
28  wks:/etc/pki/tls/certs# ls -la
29  total 16
30  drwxr-xr-x 2 root root 4096 2008-06-30 23:41 .
31  drwxr-xr-x 3 root root 4096 2008-06-30 12:53 ..
32  -rw-r--r-- 1 root root  887 2008-06-30 23:41 mycertkey.pem
33  -rw-r--r-- 1 root root 1326 2008-06-30 23:41 mycert.pem
34  wks:/etc/pki/tls/certs# file mycert*
35  mycertkey.pem: PEM RSA private key
36  mycert.pem:    PEM certificate

As lines 4 to 36 show, it all went well and by plan as explained above. Lines 35 and 36 show that what we just did was successful i.e. we got a certificate and its key.


Now the contents of the /etc/pki/tls/certs/mycert.pem file should be checked to ensure it has a private key and digital certificate. If any of the identifying details in the X509 change or has been entered incorrectly, we can easily regenerate new keys until the details are correct.

37  wks:/etc/pki/tls/certs# openssl verify mycert.pem
38  mycert.pem: /C=US/ST=Oregon/L=Portland/O=Foo Ltd/OU=Foo IT Department/CN=www.foo.com/emailAddress=wizard@foo.com
39  error 18 at 0 depth lookup:self signed certificate
40  OK

The error in line 39 actually is no error but only a reminder that this is a self signed certificate i.e. not signed by a CA like for example VeriSign. Another way to review the certificate we just created is shown in lines 41 to 66.

41  wks:/etc/pki/tls/certs# openssl x509 -in /etc/pki/tls/certs/mycert.pem -noout -text
42  Certificate:
43      Data:
44          Version: 3 (0x2)
45          Serial Number:
46              df:9d:95:76:71:01:35:39
47          Signature Algorithm: sha1WithRSAEncryption
48          Issuer: C=US, ST=Oregon, L=Portland, O=Foo Ltd, OU=Foo IT Department, CN=www.foo.com/emailAddress=wizard@foo.com
49          Validity
50              Not Before: Jun 30 21:41:27 2008 GMT
51              Not After : Jun 30 21:41:27 2010 GMT
52          Subject: C=US, ST=Oregon, L=Portland, O=Foo Ltd, OU=Foo IT Department, CN=www.foo.com/emailAddress=wizard@foo.com
53
54  [skipping a lot of lines...]
55
56              X509v3 Basic Constraints:
57                  CA:TRUE
58      Signature Algorithm: sha1WithRSAEncryption
59          b9:cf:b5:a8:ea:68:d6:e4:60:e3:8d:43:06:8e:65:fc:46:1e:
60          50:2e:f8:d3:c2:6c:09:ff:b5:a0:c4:a2:b0:70:b6:d9:dd:51:
61          a4:4b:4c:e7:6f:7a:d9:43:f2:26:c8:41:c5:78:bd:f6:19:50:
62          f6:36:cd:f6:38:d8:c9:e3:2f:0f:78:e3:47:5d:0a:8e:94:02:
63          73:ec:7d:25:0d:5a:66:d4:a1:68:07:e2:20:88:41:15:76:0d:
64          3a:41:2c:61:14:a8:f7:38:b0:3a:fc:94:a4:5a:8b:93:5a:7c:
65          dc:fe:29:1d:25:d4:77:94:7d:c0:e6:0c:aa:7e:7c:52:1b:b7:
66          82:e3

The mycert.pem file should also be secured so only root has access to the file. This does not affect the server if it is running as a non privileged account, as the keys are loaded before dropping into non privileged mode.

67  wks:/etc/pki/tls/certs# ls -l | grep mycert
68  -rw-r--r-- 1 root root  887 2008-06-30 23:41 mycertkey.pem
69  -rw-r--r-- 1 root root 1326 2008-06-30 23:41 mycert.pem
70  wks:/etc/pki/tls/certs# chmod 600 mycert*
71  wks:/etc/pki/tls/certs# ls -l | grep mycert
72  -rw------- 1 root root  887 2008-06-30 23:41 mycertkey.pem
73  -rw------- 1 root root 1326 2008-06-30 23:41 mycert.pem
74  wks:/etc/pki/tls/certs#

Finally, we are going to enable SSL/TLS with vsftpd by editing /etc/vsftpd.conf again. Following setup is just a recommendation of mine... it may be adapted to fit ones personal needs and likings (again, the manual file and comments in /etc/vsftpd.conf are very detailed to no need for me to explain the settings below).

ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=YES

ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

rsa_cert_file=/etc/pki/tls/certs/mycert.pem

Now vsftpd need be restarted in order for the changes to take effect.


For SSL/TLS encryption to be fully implemented, the FTP client application also needs to support secure connections. I already pointed out above that lftp is an excellent FTP client which supports transport layer encryption as we just installed it. Also there are many other clients that support it e.g.

  • The Linux based gFTP client is enabled for TLS/SSL connections, however it initially rejects self-signed server certificates. This can be fixed by disabling the Verify SSL Peer setting in options. When making connections, be sure to select the FTPS (FTP/SSL) protocol.
  • The Windows based SmartFTP client is also enabled for TLS/SSL connections. The FTP server firstly needs to be configured as a Favourite Site, then the properties need to adjusted to use the FTP over SSL Explicit protocol.

We are done setting up and configuring vsftpd for SSL/TLS encryption!

Further Improvements to Security

This subsection discusses a few things that can be done in addition in order to make the FTP environment, set up with vsftpd, even more secure.

Login Permit/Deny

Normally users which have an account on the local system can log in using their login credentials (username and password) and access their files. As a security measure, not all system accounts should be allowed to do this.

Any user account that is listed in /etc/vsftpd.ftpuser will not be granted login access through vsftpd at all. This file is normally used for system accounts like root, bin etc. and users we do not want to allow login via FTP. By the way, putting the user anonymous in /etc/vsftpd.ftpuser does nothing. Anonymous access must be disabled explicitly with anonymous_enable=NO as explained above.

blacklisting
Since per default, userlist_deny=YES is set, in order to create a selective list for user accounts which are denied access to the FTP server we need to set userlist_enable=YES and userlist_file=/etc/vsftpd/user_list. In short, now any user listed in /etc/vsftpd/user_list is NOT allowed to log in via FTP. Generally, this is known as blacklisting.
whitelisting
On the other hand, if we alter userlist_deny=YES to userlist_deny=NO and leave alone userlist_enable=YES and userlist_file=/etc/vsftpd/user_list, then we are going to do whitelisting i.e. any user listed in the file /etc/vsftpd/user_list is now allowed to log in via FTP — those not listed are not allowed to log in. So userlist_deny sort of toggles the deny/permit behavior.

Finally, if we want to stop all local users from being able to log in in just one go (no need to selectively put usernames into a file), then setting local_enable=NO and write_enable=NO does the trick.

Change Root

Users with a local user account normally have the ability to browse the complete file system as though they were logged onto the terminal or accessing the computer via SSH. To disable this behavior, they can be change rooted i.e. jailed into their home directories (chroot_local_user=YES). This means they will be locked inside their own home directories and can not view or access the rest of the file system when they are logged in via ftp.


As with login, users can also be selectively jailed into their home directories if needed. Therefore chroot_list_enable=YES and chroot_list_file=/etc/vsftpd/chroot_list need be enabled and populated with user account names. Again, blacklisting and whitelisting is possible:

  • If chroot_list_enable=YES, then /etc/vsftpd.chroot_list contains a selective list of users that are jailed to their home directories.
  • If chroot_local_user=YES is also set, then the entries in the /etc/vsftpd.chroot_list are users that are not jailed i.e. the opposite effect.
Moving Port 21 to a High Port

This is trivial really but as with SSH, has enormous effects e.g. stopping automated brute force attacks over the Internet completely since those tend to only test standard ports. In order to move the vsftpd listening port to a high port (> 1023) listen_port=28432 does the trick.

FTP Greeting Banner

Some say, setting ftpd_banner=Welcome to blabla... hides things like vsftpd version number etc. and therefore boosts security. Well, yes and no. I would not be impressed since figuring out that kind of information is really no rocket science for skilled folks but then it does no harm either setting an FTP banner message.

Using SCP respectively SFTP as an Alternative

hm... yes, but we have gathered to set up an FTP environment so talking about SCP (Secure Copy) and SFTP (SSH File Transfer Protocol) might not really help since those two are not capable of a lot of things our current vsftpd environment offers and vice versa. Another jungle, with different animals that is... ;-]

Using encryption i.e. FTPS (FTP/SSL)

Yes, very good. See above.

TCP Wrapper

An excellent way to secure TCP (Transmission Control Protocol), UDP (User Datagram Protocol) and ICMP (Internet Control Message Protocol) based services. See here.

Virtual Users with vsftp

WRITEME

Not sure I will ever add it. Only if I really need it myself...

1. Allow outgoing control connections to server.

2. Allow the client to establish data channels to remote server.

3. Allow incoming control connections to server.

4. Allow server to establish data channel to remote client.

5. I have a dedicated section onto some other page that explicitly talks about the whole SSL, CA, certificate etc. shebang.

Creative Commons License
The content of this site is licensed under Creative Commons Attribution-Share Alike 3.0 License.