How to configure vsftpd to use SSL/TLS (FTPS) on CentOS/Ubuntu

By | December 7, 2014

Securing FTP

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.

Install 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
              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

# CentOS/Fedora

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.


The following lines will tell vsftpd to use TLS when applicable, which is more secure than its predecessor SSL.


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
Connected to
220 (vsFTPd 2.2.2)
Name ( pal
530 Non-anonymous sessions must use encryption.
Login failed.

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 --user pal:pal
-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
" error.

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:// ...

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.

Additional Notes

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.

About Silver Moon

A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected].

Leave a Reply

Your email address will not be published. Required fields are marked *