Skip to content

vsftpd

FTP sends usernames and passwords in clear text unless TLS is turned on, and it's often set up with anonymous access. If the README doesn't require FTP, sudo apt purge vsftpd. If it does, the config is /etc/vsftpd.conf; restart with sudo systemctl restart vsftpd.

The settings

Setting Value Why
anonymous_enable NO No login without an account
local_enable YES Real accounts can log in
write_enable YES only if the README says users upload
chroot_local_user YES Users are confined to their home directory; without it, cd /etc works
allow_writeable_chroot NO (or make the home directory root-owned and use a writable subdirectory) A writable chroot root is a known escape
ssl_enable YES TLS on
rsa_cert_file, rsa_private_key_file /etc/ssl/private/vsftpd.pem (a certificate you generate) The server's TLS identity
force_local_logins_ssl, force_local_data_ssl YES Plain FTP is refused; only FTPS
ssl_tlsv1_2 YES, ssl_tlsv1 NO, ssl_sslv2 NO, ssl_sslv3 NO as listed Only modern TLS
xferlog_enable, log_ftp_protocol YES Transfers and commands are logged to /var/log/vsftpd.log
max_login_fails 3 Drops the connection after three bad passwords
userlist_enable YES, userlist_deny NO, userlist_file=/etc/vsftpd.user_list with the README's FTP users listed Only listed accounts may log in
pasv_min_port, pasv_max_port e.g. 40000 and 40100 A known passive range you can open in the firewall

Apply

The server needs a certificate before TLS can be turned on. Make a self-signed one and keep it root-only:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem -subj "/CN=$(hostname)"
sudo chmod 600 /etc/ssl/private/vsftpd.pem

Then sudo nano /etc/vsftpd.conf. The file is key=value with no spaces, and vsftpd refuses to start if a key appears twice, so for each row of the table search with Ctrl+W first: if the key is there, change its value; if it isn't, add it at the end. The first few:

anonymous_enable=NO
local_enable=YES
chroot_local_user=YES
ssl_enable=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem

Work through the rest of the table, then:

sudo systemctl restart vsftpd
systemctl status vsftpd | head -n 5

If the status shows failed, journalctl -u vsftpd -n 5 names the bad line (usually a duplicate key or a YES/NO typed in lower case).

Verify

grep -E '^(anonymous_enable|ssl_enable|force_local_logins_ssl|chroot_local_user|rsa_cert_file)' /etc/vsftpd.conf
stat -c '%a' /etc/ssl/private/vsftpd.pem      # 600
systemctl is-active vsftpd

Example

vsftpd.conf has anonymous_enable=YES, anon_upload_enable=YES, no ssl_enable. Anyone can upload files without a password in clear text. Set the block above, generate the certificate, restart. ls /srv/ftp shows what anonymous users already uploaded: a .tar.gz of tools. Delete it.

Try it

  1. Enable anonymous access, connect with ftp localhost as anonymous, then disable it and connect again.
  2. Turn on ssl_enable and connect with a client that doesn't do TLS; read the refusal.

Build it

A vsftpd-check.sh that greps the settings on this page and prints the certificate's permissions.

Next

Samba