|Tweets by @markusgattol||
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.
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:
In addition to these channels, there are several varieties of FTP as I will explain below.
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
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.
FTP active mode therefore transfers data in a counter intuitive way to
the TCP standard, as it selects port
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
Passive FTP works differently as is explained below
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 (
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:
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
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:
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:
Installing and Configuring vsftpd
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
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
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
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 (
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
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
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
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
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
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
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
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
Once we are comfortable with the answers we provided to those
questions, we can script the whole thing by adding the
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 :firstname.lastname@example.org 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
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/emailAddressemail@example.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/emailAddressfirstname.lastname@example.org 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/emailAddressemail@example.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
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
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.
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.
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
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
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
As with login, users can also be selectively jailed into their home
directories if needed. Therefore
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)
FTP Greeting Banner
Some say, setting
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.
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
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.