Skip to content

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

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

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_2 directive 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, omit ssl_tlsv1_2=YES and 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_1 directive 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 -- disabling ssl_tlsv1 and ssl_sslv2/ssl_sslv3 is still effective. vsftpd does not have a dedicated ssl_tlsv1_3 directive; 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

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