Vsftpd is a widely used ftp server, and if you are setting it up on your server for transferring files, then be aware of the security issues that come along. The ftp protocol has weak security inherent to its design. It transfers all data in plain text (unencrypted), and on public/unsecure network this is something too risky.
To fix the issue we have FTPS. It secures FTP communication by encrypting it with SSL/TLS. And this post shows how to setup SSL encryption with vsftpd.
Vsftpd is available in the default repositories of all major distros including debian,ubuntu, centos and fedora and can be installed without any hassles. There is only one configuration file named vsftpd.conf that resides in the /etc directory.
# ubuntu/debian $ sudo apt-get install vsftpd # centos/fedora # sudo yum install vsftpd
The remaining is to configure vsftpd to use ssl encryption for the ftp communication. It is just a 2 step process.
Generate a SSL certificate
The first step is to create an ssl certificate and key file that vsftpd is going to use for the encryption. The configuration parameter "rsa_cert_file" shall hold the path to the certificate file. It does have a default value that can be found in the man page.
$ man vsftpd.conf | grep rsa_cert_file -A 5 rsa_cert_file This option specifies the location of the RSA certificate to use for SSL encrypted connections. Default: /usr/share/ssl/certs/vsftpd.pem
Its different across Ubuntu and CentOS. We can store it at any location we like.
Create an ssl certificate with the openssl command. We are putting the certificate and key together in a single file.
# openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
Answer the questions that follow and in a few seconds the certificate file should be ready. THe output would look something like this
# openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem Generating a 1024 bit RSA private key .............++++++ ....++++++ writing new private key to '/etc/ssl/private/vsftpd.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:US State or Province Name (full name) :NY Locality Name (eg, city) [Default City]: Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) : Common Name (eg, your name or your server's hostname) : Email Address :
Configure Vsftpd for SSL
The next task is to configure vsftpd to use this ssl certificate for encryption. The vsftpd.conf file can be found at the following location
# Ubuntu/Debian /etc/vsftpd.conf # CentOS/Fedora /etc/vsftpd/vsftpd.conf
Open the vsftpd.conf file, and edit as shown below
The following will tell vsftpd the location of the certificate/key file to use.
Add the following options to turn on SSL. It will enable SSL and force encryption for data transfers as well as logins.
ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES
The following lines will tell vsftpd to use TLS when applicable, which is more secure than its predecessor SSL.
ssl_tlsv1=YES ssl_sslv2=YES ssl_sslv3=YES
All the necessary configuration directives have been added. Save the file and restart vsftpd
# service vsftpd restart # or # sudo /etc/init.d/vsftpd restart
Test SSL on vsftpd
Now that our setup is complete, its time to test it.
First try to connect using the plain ftp command and it should fail asking for encryption.
$ ftp 192.168.1.5 Connected to 192.168.1.5. 220 (vsFTPd 2.2.2) Name (192.168.1.5:enlightened): pal 530 Non-anonymous sessions must use encryption. Login failed. ftp>
Next verify that SSL encryption is working fine. Gui ftp clients like FileZilla can use FTPS, but for convenience sake, we shall resort to the command line tool called curl, and here is the very simple command that should connect to the FTPS server and list the files
$ curl --ftp-ssl --insecure --ftp-port 192.168.1.2:6003 --user pal:pal ftp://192.168.1.5 -rw-r--r-- 1 0 0 0 Jan 03 06:10 abcd.txt -rw-r--r-- 1 0 0 0 Jan 03 06:10 cdefg.txt
Those files are in the home directory of user pal on the ftp server. Make sure that you do have some files in the server home to get them listed and verify. Otherwise curl would just return blank.
Here is quick explanation of the curl options we used.
ftp-ssl : Tells curl to use ftps insecure : Tells curl not to use any ssl certificate to authenticate and just connect right away. ftp-port : Tells curl that we are in ACTIVE mode. In ACTIVE mode the client has to tell the server the hostname and port number to connect back to. If you have configured passive mode ftp, then do not use this. user : Specifies the username and password joined with a colon. The last thing is the ftp url.
If you do not specify the ftp-port on ACTIVE mode ftp connections you would get "No route to host
If you get "bind() failed, we ran out of ports!" error then simply change the port number.
You can also use a url like this
$ curl ftps://192.168.1.5 ...
But then curl would try to connect to port 990 and unless you have configured vsftpd to serve on that port, it wont work.
If curl fails to connect to vsftpd or list the files properly, use the verbose (-v) option and see further details on what went wrong and then fix it.
FTPS secures FTP by adding SSL encryption to the communication channel. Another recommended way to establish secure connections is by using SFTP (SSH File Transfer Protocol). The popular OpenSSH package that provides the ssh service, provides SFTP too along side without the need of any additional setup or configuration. However not all FTP clients and web development tools support SFTP.