
Introduction
This guide explains how to set up vsftpd (Very Secure File Transfer Protocol Daemon), which allows users to upload files via FTPS (also known as FTP-SSL and FTP Secure). This guide is written for the Vultr One-Click LAMP server on Ubuntu 18.04 using a free Let's Encrypt SSL/TLS certificate. With minor modifications, you can adapt this guide to any server distribution with vsftpd in their repository, and use Apache or Nginx.
Prerequisites
- A One-Click LAMP server configured with a Fully Qualified Domain Name (FQDN).
- A free Let's Encrypt certificate pointing to your domain name.
- A non-root user with sudo privileges.
1. Install vsftpd
Update the local package index.
$ sudo apt updateInstall the vsftpd daemon.
$ sudo apt install vsftpd2. Configure the Firewall
UFW, or Uncomplicated Firewall, is installed by default on Ubuntu systems. If it is enabled, open the necessary ports: 20 and 21 for FTP, 40000-50000 for passive FTP, and 990 for TLS.
$ sudo ufw allow 20/tcp
$ sudo ufw allow 21/tcp
$ sudo ufw allow 40000:50000/tcp
$ sudo ufw allow 990/tcp
$ sudo ufw statusIf the firewall is enabled, the rules should look like this:
Output
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
20/tcp ALLOW Anywhere
21/tcp ALLOW Anywhere
40000:50000/tcp ALLOW Anywhere
990/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
20/tcp (v6) ALLOW Anywhere (v6)
21/tcp (v6) ALLOW Anywhere (v6)
40000:50000/tcp (v6) ALLOW Anywhere (v6)
990/tcp (v6) ALLOW Anywhere (v6)3. Configure FTP Access
Create a dedicated user to log in to FTP, and use a strong password.
$ sudo adduser ftpaccessFor increased security, block this user from logging in via SSH.
$ sudo nano /etc/ssh/sshd_configAdd the following line to the bottom of the file.
DenyUsers ftpaccessSave and exit the file.
Restart SSH to enforce the changes.
$ sudo service sshd restartSet the home directory to the folder above the default webroot. vsftpd restricts the user's access to their specific home directory using chroot jails and requires that the directory be not writable by the user. For Apache, the default webroot is /var/www/html.
$ sudo usermod -d /var/www ftpaccessSet the ownership of the webroot to the FTP user.
$ sudo chown ftpaccess:ftpaccess /var/www/htmlVerify the permissions of the directory.
$ sudo ls -la /var/www/html
4. Configure vsftpd
Open the configuration file for
vsftpd.$ sudo nano /etc/vsftpd.confEnsure anonymous FTP access is disabled and local users can log in.
# # Allow anonymous FTP? (Disabled by default). anonymous_enable=NO # # Uncomment this to allow local users to log in. local_enable=YES #Uncomment these lines to allow the FTP user to upload files, and prevent them from accessing any files outside of their home directory.
write_enable=YES local_umask=022 chroot_local_user=YESAdd
force_dot_files=YESin the file to show hidden files such as.htaccess.force_dot_files=YESSet the range of ports available for passive FTP. Make sure these values match the firewall settings added in Step 2.
pasv_min_port=40000 pasv_max_port=50000Restrict FTP access to users specified in
/etc/vsftpd.userlist.userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NOSave and exit the file.
Edit
/etc/vsftpd.userlist.$ sudo nano /etc/vsftpd.userlistAdd the ftpaccess user to the file.
ftpaccessSave and exit the file.
Restart
vsftpdto load the changes.$ sudo systemctl restart vsftpd
You should be able to log in with any FTP client as the ftpaccess user, but the server is un-encrypted. Continue with Step 5 to set up encryption.
5. Encrypt Transactions
By default, FTP does not encrypt credentials or data in transit. Follow these steps to use the server's Let's Encrypt certificate to secure the connection. You can follow our guide to obtain a Let's Encrypt certificate for a LAMP server if you need to install one first.
Edit the
vsftpdconfiguration file.$ sudo nano /etc/vsftpd.confFind the two lines beginning with
rsa_and comment them out by adding#at the beginning.#rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem #rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.keyAdd the following lines. Adjust the pathname to match the location of the server's certificate files.
rsa_cert_file=/etc/letsencrypt/live/example.com/fullchain.pem rsa_private_key_file=/etc/letsencrypt/live/example.com/privkey.pemAdd this line to allow clients that can't connect over TLS to use SSL.
ssl_enable=YESDeny anonymous connections and force a secure connection by adding the following lines.
allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YESSpecify which protocols to use. For security, allow TLS and block older versions of SSL.
ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NOAdd the following to use strong encryption methods.
ssl_ciphers=HIGHDo not require the reuse of SSL sessions. Setting this to yes may interfere with many FTP clients.
require_ssl_reuse=NOAdd the ports used for passive FTP.
pasv_min_port=40000 pasv_max_port=50000Save and exit the file.
Restart the server.
$ sudo systemctl restart vsftpd
7. Verify Encrypted FTP
A good verification test is to attempt a connection with the default command-line ftp client, which will fail because it doesn't support encryption.
Connect using command-line
ftpfrom a different machine.$ ftp example.comEnter the username when prompted and ensure access is denied.
530 Non-anonymous sessions must use encryption. ftp: Login failed.With a client that supports FTPS, such as FileZilla or Cyberduck, connect to the server and check the connection log. You should find entries similar to this:
Status: Connection established, waiting for welcome message... Status: Initializing TLS... Status: Verifying certificate... Status: TLS connection established.
Conclusion
You can now securely connect to your server via FTPS and upload files to your website directory.