Install vsftpd FTP Server on VPS

Install vsftpd FTP Server on VPS

July 2026 · 7 min read

vsftpd (Very Secure FTP Daemon) is a lightweight, secure, and easy-to-configure FTP server for Ubuntu and Debian VPS systems. While SFTP (FTP over SSH) has gained popularity in recent years, FTP/FTPS remains necessary in certain scenarios: legacy applications that require FTP connectivity, shared hosting environments that don't permit SSH access, or non-technical users who prefer graphical FTP clients. This guide walks through setting up vsftpd securely with chroot jails, passive mode, and TLS encryption to safeguard file transfers on your VPS.

Install vsftpd

sudo apt update
sudo apt install vsftpd -y

# Enable vsftpd to start automatically
sudo systemctl enable vsftpd
sudo systemctl start vsftpd

Configure vsftpd

The main configuration file is /etc/vsftpd.conf. Back up the original first:

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
sudo nano /etc/vsftpd.conf

Find and edit (or add) these directives:

# Allow local users to login
local_enable=YES
write_enable=YES

# Chroot jail - confine users to their home directory
chroot_local_user=YES
chroot_list_enable=NO

# Disable anonymous login for security
anonymous_enable=NO

# Passive mode
pasv_enable=YES
pasv_address=YOUR.VPS.IP.ADDRESS
pasv_min_port=40000
pasv_max_port=40100

# FTPS (FTP over TLS/SSL)
ssl_enable=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_tlsv1_2=YES
ssl_tlsv1_3=YES
require_ssl_reuse=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

# Logging
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
log_ftp_protocol=YES

# Performance
max_clients=200
max_per_ip=4

Replace YOUR.VPS.IP.ADDRESS with your VPS's public IP address (e.g., 192.0.2.10) or a domain name that resolves to it.

Generate Self-Signed SSL Certificate for FTPS

For testing or internal use, you can generate a self-signed certificate:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/vsftpd.pem \
  -out /etc/ssl/private/vsftpd.pem

# Set correct permissions
sudo chmod 600 /etc/ssl/private/vsftpd.pem

For production, obtain a signed certificate from a trusted CA (such as Let's Encrypt or a commercial provider), then edit the config to point to the certificate and private key files separately.

Create FTP User Account

Create a system user with a home directory for FTP access:

# Create user named ftpuser
sudo useradd -m -d /home/ftpuser -s /usr/sbin/nologin ftpuser

# Set a password
sudo passwd ftpuser

# Configure home directory as chroot jail
sudo chmod 555 /home/ftpuser
sudo mkdir -p /home/ftpuser/upload
sudo chmod 755 /home/ftpuser/upload
sudo chown ftpuser:ftpuser /home/ftpuser/upload

This user can access files only within /home/ftpuser and its writable subdirectories like upload/.

Open Firewall Ports

FTP uses port 21 for control connections and the port range 40000–40100 for passive data transfers:

# Using ufw
sudo ufw allow 21/tcp
sudo ufw allow 40000:40100/tcp

# Or with iptables
sudo iptables -A INPUT -p tcp --dport 21 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 40000:40100 -j ACCEPT
Tip: After editing vsftpd.conf, restart the service for changes to take effect: sudo systemctl restart vsftpd. Verify syntax with sudo vsftpd -olisten=NO /etc/vsftpd.conf (no output means OK).

Verify That vsftpd Is Working Correctly

# Check service status
sudo systemctl status vsftpd

# Verify port 21 is listening
sudo ss -tlnp | grep :21

# Test connection from another machine using ftp client
ftp YOUR.VPS.IP.ADDRESS
# Enter username and password

# Or use lftp in one command
lftp -u ftpuser,PASSWORD YOUR.VPS.IP.ADDRESS

# View connection logs
sudo tail -20 /var/log/vsftpd.log
Tip: If connection fails, check /var/log/vsftpd.log or system syslog. Common issues are firewall rules, incorrect home directory permissions, or a misconfigured passive_address.

Common Issues & Troubleshooting

Error: "500 OOPS: vsftpd: refusing to run with writable root inside chroot()"

vsftpd does not allow write permissions on the home directory when using chroot. Set directory permission to 555 or 755 (no write bit):

sudo chmod 555 /home/ftpuser

Error: "530 Login incorrect" even with correct credentials

Verify the user's login shell is set to nologin or false:

grep ftpuser /etc/passwd
# Should end with /usr/sbin/nologin or /bin/false

# If not, fix it:
sudo usermod -s /usr/sbin/nologin ftpuser

Error: "Passive mode connection timeout" or wrong IP in PASV response

Check that pasv_address in vsftpd.conf points to the correct public IP or domain that clients can reach. If behind a load balancer or NAT:

sudo nano /etc/vsftpd.conf
# Find pasv_address= and set it to the public IP or domain
# pasv_address=1.2.3.4

sudo systemctl restart vsftpd

FTPS client rejects self-signed certificate

When using self-signed certificates, FTP clients warn about certificate validation. In the ftp CLI, use set ssl:verify-certificate no. In graphical clients (e.g., FileZilla), click "Always trust this host".

Permission denied when uploading files

Ensure writable directories (like upload/) have correct ownership and permissions:

sudo chown ftpuser:ftpuser /home/ftpuser/upload
sudo chmod 755 /home/ftpuser/upload

Frequently Asked Questions

Why use FTP when SFTP is available?

SFTP is more secure and widely preferred today, but FTP remains necessary in several cases: legacy applications hardcoded for FTP, shared hosting restrictions that prohibit SSH, or non-technical users who need simple graphical FTP client support.

What is the purpose of chroot jail?

Chroot jail restricts an FTP user to see and access files only within their home directory. If the FTP server is compromised, an attacker cannot access /etc, /root, or other users' /home directories—a critical containment strategy.

Should I use FTP or FTPS?

Always use FTPS on a production VPS. Plain FTP transmits credentials in cleartext over the network. SFTP is equally secure and often preferred, but if the application requires FTP, FTPS is the next-best option.