Last updated: 2026-02-11
vsftpd TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for vsftpd (Very Secure FTP Daemon), a lightweight and security-focused FTP server for Linux. vsftpd supports both explicit FTPS (STARTTLS on port 21) and implicit FTPS (direct TLS on port 990).
Prerequisites
- vsftpd 3.0.3 or later
- OpenSSL 1.1.1 or later
- A valid SSL/TLS certificate
Certificate Setup
vsftpd expects PEM-formatted certificate files:
chmod 600 /etc/vsftpd/ssl/privkey.pem
chown root:root /etc/vsftpd/ssl/privkey.pem
Enable TLS
Add the following settings to /etc/vsftpd/vsftpd.conf (or /etc/vsftpd.conf depending on your distribution).
Basic TLS Settings
ssl_enable=YES
rsa_cert_file=/etc/vsftpd/ssl/fullchain.pem
rsa_private_key_file=/etc/vsftpd/ssl/privkey.pem
Require TLS for All Connections
Force both anonymous and local users to use encrypted connections:
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
- force_local_logins_ssl=YES requires TLS for the control channel (login credentials).
- force_local_data_ssl=YES requires TLS for the data channel (file transfers).
Protocol Versions
Disable older protocols and require TLS 1.2 or later:
ssl_tlsv1=NO
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1_2=YES
Version note: The
ssl_tlsv1_2directive requires vsftpd 3.0.4+ (or a distribution-patched 3.0.3 such as RHEL 8). On an unpatched vsftpd 3.0.3 (e.g. Debian 11), this directive is unrecognized and vsftpd will refuse to start. In that case, omitssl_tlsv1_2=YESand rely on disabling older protocols (ssl_tlsv1=NO,ssl_sslv2=NO,ssl_sslv3=NO) — TLS 1.2 will be used by default.The
ssl_tlsv1_1directive is available in vsftpd 3.0.4+ and some distribution-patched builds of 3.0.3. If your build does not recognize it, omit it -- disablingssl_tlsv1andssl_sslv2/ssl_sslv3is still effective. vsftpd does not have a dedicatedssl_tlsv1_3directive; TLS 1.3 is available automatically when using OpenSSL 1.1.1+.
Cipher Suites
Configure strong cipher suites for TLS 1.2. TLS 1.3 cipher suites are managed by OpenSSL automatically and cannot be overridden via ssl_ciphers:
ssl_ciphers=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
Additional Security Settings
require_ssl_reuse=NO
strict_ssl_read_eof=YES
- require_ssl_reuse=NO allows data connections without TLS session reuse. Some FTP clients do not support session reuse, and enabling this can cause transfer failures. Set to
YESif all your clients support it. - strict_ssl_read_eof=YES requires proper TLS shutdown, preventing truncation attacks.
Implicit FTPS
By default, vsftpd uses explicit FTPS (STARTTLS on port 21). To use implicit FTPS (TLS from the start on port 990):
implicit_ssl=YES
listen_port=990
Note that implicit and explicit FTPS cannot run on the same listener. To support both, you need two vsftpd instances with separate configuration files.
Passive Mode
Configure passive mode ports for FTPS data connections. Your firewall must allow these ports:
pasv_enable=YES
pasv_min_port=49152
pasv_max_port=65534
pasv_address=your.public.ip.address
Complete Configuration
# General settings
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES
allow_writeable_chroot=YES
# TLS settings
ssl_enable=YES
rsa_cert_file=/etc/vsftpd/ssl/fullchain.pem
rsa_private_key_file=/etc/vsftpd/ssl/privkey.pem
# Require TLS
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
# Protocol versions
ssl_tlsv1=NO
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1_2=YES # requires vsftpd 3.0.4+; omit on unpatched 3.0.3 (Debian 11)
# Cipher suites
ssl_ciphers=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
# Session settings
require_ssl_reuse=NO
strict_ssl_read_eof=YES
# Passive mode
pasv_enable=YES
pasv_min_port=49152
pasv_max_port=65534
Verification
Restart vsftpd:
systemctl restart vsftpd
Test with OpenSSL (explicit FTPS):
openssl s_client -connect ftp.example.com:21 -starttls ftp
Test with OpenSSL (implicit FTPS):
openssl s_client -connect ftp.example.com:990
Test with lftp:
lftp -u username -e "set ftp:ssl-force true; set ssl:verify-certificate yes; ls; quit" ftp.example.com
Test with curl:
curl --ftp-ssl --user username:password ftps://ftp.example.com/
Check the vsftpd log for connection details:
journalctl -u vsftpd