· Kalpa Madhushan · documentation · 4 min read

Setting Up a Secure FTP Server with vsftpd on Ubuntu (Supports FTPS + Per-User Settings)

Learn how to securely set up an FTP server on Ubuntu using vsftpd, with FTPS encryption, per-user settings, chroot jail, and VirtualBox NAT support.

Learn how to securely set up an FTP server on Ubuntu using vsftpd, with FTPS encryption, per-user settings, chroot jail, and VirtualBox NAT support.

vsftpd (Very Secure FTP Daemon) is a fast, stable, and secure FTP server for Unix-like systems. It is widely used for its strong focus on security and performance. In this guide, we’ll walk you through how to configure vsftpd to support encrypted FTPS connections (both explicit and implicit), chroot jail environments, per-user settings, and firewall/NAT support for VirtualBox users.


✨ Features You’ll Enable With This Setup

  • FTPS (FTP over TLS/SSL)
  • Local users only (no anonymous access)
  • Explicit or implicit FTPS support
  • Secure file access via chroot jail
  • Per-user FTP settings (e.g., individual directories, write access)
  • Certificate-based encryption
  • Compatible with lftp and FileZilla
  • VirtualBox NAT-friendly with passive port forwarding

⚙️ Step 1: Install vsftpd

sudo apt update
sudo apt install vsftpd openssl

🔐 Step 2: Generate a Self-Signed SSL Certificate

sudo mkdir -p /etc/vsftpd/ssl/{certs,private}
sudo openssl req -x509 -newkey rsa:2048 \
  -keyout /etc/vsftpd/ssl/private/vsftpd.key \
  -out /etc/vsftpd/ssl/certs/vsftpd.crt \
  -days 365 -nodes -subj "/CN=vsftpd.local"
sudo chmod 640 /etc/vsftpd/ssl/private/vsftpd.key

📁 Step 3: Create a Dedicated FTP User (Example: kftp)

sudo adduser --home /home/kftp/ftp kftp
sudo chmod 750 /home/kftp/ftp

✏️ Step 4: Customize the vsftpd Configuration

Edit /etc/vsftpd.conf and update/append the following settings:

# Basic Server Settings
listen=YES                    # Listen on IPv4 only
listen_ipv6=NO                # Disable IPv6 listening
local_enable=YES              # Allow local users to log in
write_enable=NO               # Disable write access by default (per-user overrides available)
local_umask=077               # Set umask for file creation (077 = very restrictive)
file_open_mode=0640           # Set file permissions when created (0640 = owner read/write, group read)
connect_from_port_20=YES      # Use port 20 for active mode data transfers (standard)

# Logging Configuration
xferlog_enable=YES            # Enable transfer logging
xferlog_std_format=NO         # Use non-standard, more verbose log format
log_ftp_protocol=YES          # Log all FTP protocol commands (useful for debugging)

# Authentication Settings
pam_service_name=vsftpd       # PAM service name for authentication
userlist_enable=YES           # Enable user list feature
tcp_wrappers=YES              # Use TCP wrappers for access control

# SSL/TLS Configuration
ssl_enable=YES                # Enable SSL/TLS encryption
rsa_cert_file=/etc/vsftpd/ssl/certs/vsftpd.crt             # SSL certificate location
rsa_private_key_file=/etc/vsftpd/ssl/private/vsftpd.key    # SSL private key location
require_ssl_reuse=NO          # Don't require SSL session reuse (compatibility)
ssl_tlsv1=YES                 # Enable TLSv1 protocol
ssl_sslv3=YES                 # Enable SSLv3 protocol (consider disabling for better security)
force_local_logins_ssl=YES    # Force SSL/TLS for authentication
force_local_data_ssl=YES      # Force SSL/TLS for data transfers
ssl_ciphers=HIGH              # Use only high-security ciphers

# User Isolation (Chroot) Settings
chroot_local_user=YES         # Restrict users to their home directories
allow_writeable_chroot=YES    # Allow writable home directories (needed for uploads)
local_root=/home/kftp/ftp     # Default root directory for users

# Passive Mode Configuration (for NAT/firewall compatibility)
pasv_enable=YES               # Enable passive mode
pasv_min_port=40000           # Lower bound of passive port range
pasv_max_port=40100           # Upper bound of passive port range

# Advanced Configuration
user_config_dir=/etc/vsftpd/users    # Directory for per-user configuration files

# Optional: Implicit FTPS Configuration
# listen_port=990             # Use port 990 for implicit FTPS (uncomment to enable)

📂 Step 5: Create Per-User Configuration

sudo mkdir -p /etc/vsftpd/users

Create /etc/vsftpd/users/kftp with the following:

write_enable=YES
local_root=/home/kftp/ftp

🔒 Step 6: PAM Shell Access Bypass (Required for nologin shells)

Comment this line in /etc/pam.d/vsftpd:

# auth required pam_shells.so

🚫 Step 7: Deny SSH or System Users

Add them to both:

  • /etc/ftpusers
  • /etc/vsftpd.user_list

These files deny FTP access to listed users.


🔌 Step 8: Restart vsftpd

sudo systemctl restart vsftpd

🚀 Step 9: Test Using lftp

Explicit FTPS (Port 21)

lftp -u kftp,kftp -e "set ftp:ssl-force true; set ftp:ssl-protect-data true; set ssl:verify-certificate no; ls; bye" ftp://127.0.0.1

Implicit FTPS (Port 990)

Uncomment listen_port=990 in the config, then:

lftp -u kftp,kftp -e "set ssl:verify-certificate no; ls; bye" ftp://127.0.0.1:990

🔍 What’s the Difference? Explicit vs Implicit FTPS

FeatureExplicit FTPSImplicit FTPS
Port21990
TLS StartAfter connection (AUTH TLS)Immediately during connection
Standard Today✅ Modern & Preferred❌ Deprecated in some clients
FileZilla Support✅ Yes✅ Yes

📂 Test File Uploads & Downloads

You can use the following in lftp or FileZilla:

put filename.ext      # Upload
get filename.ext      # Download

🚪 FileZilla Setup

  1. Open FileZilla > Site Manager > New Site
  2. Host: 127.0.0.1, Port: 21
  3. Protocol: FTP
  4. Encryption: Require Explicit FTP over TLS
  5. Login: Normal | User: kftp | Password: kftp
  6. Accept certificate warning on first connect

🚀 VirtualBox NAT Port Forwarding (for Passive Mode)

If you’re using a VirtualBox NAT adapter:

  1. Add these to your VM’s Port Forwarding:

    • Port 21 (host to guest)
    • Ports 40000–40100 (passive data ports)
  2. CMD Script to Add Ports (Windows):

cd "C:\Program Files\Oracle\VirtualBox"
FOR /L %P IN (40000,1,40100) DO VBoxManage modifyvm "YourVMName" --natpf1 "ftp-pasv-%P,tcp,,%P,,%P"
VBoxManage modifyvm "YourVMName" --natpf1 "ftp-control,tcp,,21,,21"

You now have a robust, secure FTP server that supports FTPS, chrooted users, and per-user configurations, fully testable in both CLI and GUI clients.

Back to Blog

Related Posts

View All Posts »