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¶
- Enable anonymous access, connect with
ftp localhostasanonymous, then disable it and connect again. - Turn on
ssl_enableand 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.