I recently had to set up a FTP server for some designers to upload their work (unfortunately they couldn’t use SFTP otherwise it would have been much simpler!). I’ve not had to set up vsftpd for a while, and when I last did it I didn’t much worry about needing to use encryption. So here are some notes on how to set up vsftpd with letsencrypt on ubuntu 14.04 / 16.04 so that only a specific user or two are permitted access.
First, install vsftpd:
apt install -y vsftpd
Next, you need to make sure you have installed letsencrypt. If not, you can do so using the instructions here – fortunately letsencrypt installation has got a lot easier since my last blog post about letsencrypt almost 2 years ago.
I’m assuming you are running this on the same server as the website, and you’re wanting to set it up as ftp on the same domain or similar subdomain as the website (eg ftp access direct to example.org, or via something like ftp.example.org). If not, you can do a manual install of the certificate but then you will need to redo this every 3 months.
Assuming you’re running the site on apache get the certificate like:
certbot --apache -d example.org,www.example.org
You should now have the necessary certificates in the /etc/letsencrypt/live/example.org/
folder, and your site should be accessible nicely via https.
Now, create a user for FTP using the useradd
command. If you want to just create a user that only has access to the server via FTP but not a regular account you can modify the PAM configuration file /etc/pam.d/vsftpd and comment out the following line:
# Not required to be allowed normal login to box #auth required pam_shells.so
This lets you keep nologin
as the shell so the user cannot login normally but can log in via vsftpd’s PAM layer.
Now open up /etc/vsftpd.conf
pam_service_name=vsftpd # Paths to your letsencrypt files rsa_cert_file=/etc/letsencrypt/live/example.org/fullchain.pem rsa_private_key_file=/etc/letsencrypt/live/example.org/privkey.pem ssl_enable=YES allow_anon_ssl=NO # Options to force all communications over SSL - why would you want to # allow clear these days? Comment them out if you don't want to force # SSL though force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO require_ssl_reuse=NO ssl_ciphers=HIGH
Because we’re running behind a firewall we want to specify which port range to open up for the connections (as well as port 21 for FTP of course):
pasv_min_port=40000 pasv_max_port=41000
If you want to make it even more secure by only allowing users listed in /etc/vsftpd.userlist to be able to log in, add some usernames in that file and then add the following to the /etc/vsftpd.conf
configuration file:
userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NO
You can test using the excellent lftp command:
lftp -u user,pass -e 'set ftp:ssl-force true' example.org/
If the cert is giving errors or is self-signed, you can do the following to connect ignoring them:
lftp -u user,pass -e 'set ssl:verify-certificate false; set ftp:ssl-force true' example.org/