Skip to main content

FTP Server (vsftpd) on Ubuntu

Trademark Notice

This guide covers vsftpd (Very Secure FTP Daemon), an open-source FTP server. All product names are used for educational purposes only.

Complete guide to installing and configuring vsftpd FTP server on Ubuntu.

Installation

# Update package list
sudo apt update

# Install vsftpd
sudo apt install -y vsftpd

# Check status
sudo systemctl status vsftpd

# Enable at boot
sudo systemctl enable vsftpd

# Check version
vsftpd -v

Basic Configuration

Backup Original Config

# Backup configuration
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup

Anonymous FTP (Read-Only)

# Edit configuration
sudo nano /etc/vsftpd.conf
# Anonymous FTP
anonymous_enable=YES
no_anon_password=YES
anon_root=/srv/ftp

# Anonymous users can only download
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO

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

# Misc
listen=YES
listen_ipv6=NO
pam_service_name=vsftpd
# Create FTP directory
sudo mkdir -p /srv/ftp/pub
sudo chown nobody:nogroup /srv/ftp
sudo chmod 755 /srv/ftp

# Add test files
echo "Welcome to FTP Server" | sudo tee /srv/ftp/pub/README.txt

# Restart vsftpd
sudo systemctl restart vsftpd

# Open firewall
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp

Local User FTP

Basic Configuration

# Edit configuration
sudo nano /etc/vsftpd.conf
# Disable anonymous access
anonymous_enable=NO

# Enable local users
local_enable=YES
write_enable=YES
local_umask=022

# Chroot users to home directory
chroot_local_user=YES
allow_writeable_chroot=YES

# User list
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

# Security
seccomp_sandbox=NO

# Passive mode
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=50000

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

# Connection settings
max_clients=50
max_per_ip=2

# Timeouts
idle_session_timeout=600
data_connection_timeout=120

# Banner
ftpd_banner=Welcome to FTP Server

Create FTP Users

# Create FTP user
sudo useradd -m -s /bin/bash ftpuser
sudo passwd ftpuser

# Add to allowed list
echo "ftpuser" | sudo tee -a /etc/vsftpd.userlist

# Create upload directory
sudo mkdir -p /home/ftpuser/ftp/upload
sudo chown -R ftpuser:ftpuser /home/ftpuser/ftp
sudo chmod 755 /home/ftpuser/ftp
sudo chmod 755 /home/ftpuser/ftp/upload

# Restart vsftpd
sudo systemctl restart vsftpd

Open Firewall for Passive Mode

# Allow FTP ports
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 40000:50000/tcp

# Check status
sudo ufw status

Secure FTP with SSL/TLS (FTPS)

Generate SSL Certificate

# Generate self-signed certificate
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/vsftpd.key \
-out /etc/ssl/certs/vsftpd.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=ftp.example.com"

# Set permissions
sudo chmod 600 /etc/ssl/private/vsftpd.key
sudo chmod 644 /etc/ssl/certs/vsftpd.crt

Configure SSL/TLS

# Edit configuration
sudo nano /etc/vsftpd.conf
# SSL/TLS Configuration
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

# SSL settings
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

# Certificates
rsa_cert_file=/etc/ssl/certs/vsftpd.crt
rsa_private_key_file=/etc/ssl/private/vsftpd.key

# SSL options
require_ssl_reuse=NO
ssl_ciphers=HIGH
# Restart vsftpd
sudo systemctl restart vsftpd

Virtual Users with MySQL

Install Required Packages

# Install packages
sudo apt install -y vsftpd libpam-mysql mysql-server

Create Database

# Login to MySQL
sudo mysql
-- Create database
CREATE DATABASE vsftpd;

-- Create table
USE vsftpd;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
homedir VARCHAR(255) NOT NULL,
active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Create MySQL user
CREATE USER 'vsftpd'@'localhost' IDENTIFIED BY 'vsftpd_password';
GRANT SELECT ON vsftpd.* TO 'vsftpd'@'localhost';
FLUSH PRIVILEGES;

EXIT;

Add Virtual FTP User

# Create virtual user home directory
sudo mkdir -p /var/ftp/vuser1
sudo chown ftp:ftp /var/ftp/vuser1

# Add user to database
sudo mysql vsftpd
-- Add virtual user (password: password123)
INSERT INTO users (username, password, homedir)
VALUES ('vuser1', PASSWORD('password123'), '/var/ftp/vuser1');

Configure PAM

# Create PAM file
sudo nano /etc/pam.d/vsftpd_virtual
auth required pam_mysql.so user=vsftpd passwd=vsftpd_password host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=vsftpd_password host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=2

Configure vsftpd for Virtual Users

# Edit configuration
sudo nano /etc/vsftpd.conf
# Virtual users
guest_enable=YES
guest_username=ftp
pam_service_name=vsftpd_virtual
user_sub_token=$USER
local_root=/var/ftp/$USER

# Virtual user config directory
user_config_dir=/etc/vsftpd/user_conf

# Chroot
chroot_local_user=YES
allow_writeable_chroot=YES
# Create user config directory
sudo mkdir -p /etc/vsftpd/user_conf

# Create per-user config
sudo nano /etc/vsftpd/user_conf/vuser1
# Per-user settings
local_root=/var/ftp/vuser1
write_enable=YES
download_enable=YES
# Restart vsftpd
sudo systemctl restart vsftpd

Monitoring and Logging

View FTP Logs

# View transfer log
sudo tail -f /var/log/vsftpd.log

# View system log
sudo tail -f /var/log/syslog | grep vsftpd

# Current connections
sudo netstat -tnpa | grep vsftpd
sudo ss -tnpa | grep vsftpd

# Active FTP sessions
ps aux | grep vsftpd

Detailed Logging

# Edit configuration for verbose logging
sudo nano /etc/vsftpd.conf
# Detailed logging
log_ftp_protocol=YES
debug_ssl=YES
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log

Performance Tuning

# Edit configuration
sudo nano /etc/vsftpd.conf
# Connection limits
max_clients=200
max_per_ip=5

# Transfer settings
async_abor_enable=YES
ascii_upload_enable=NO
ascii_download_enable=NO

# Timeouts
accept_timeout=60
connect_timeout=60
idle_session_timeout=300
data_connection_timeout=120

# Performance
use_sendfile=YES
tcp_wrappers=YES

Security Hardening

Limit User Access

# Create chroot jail for users
sudo mkdir -p /home/ftpusers/{user1,user2}
sudo chown root:root /home/ftpusers
sudo chmod 755 /home/ftpusers

# Create upload directories
sudo mkdir -p /home/ftpusers/user1/upload
sudo chown user1:user1 /home/ftpusers/user1/upload

IP-Based Access Control

# Install TCP Wrappers
sudo apt install -y tcpd

# Allow specific IPs
sudo nano /etc/hosts.allow
vsftpd: 192.168.1.0/24
vsftpd: 10.0.0.0/8
# Deny all others
sudo nano /etc/hosts.deny
vsftpd: ALL

Fail2Ban for FTP

# Install Fail2Ban
sudo apt install -y fail2ban

# Create vsftpd filter
sudo nano /etc/fail2ban/filter.d/vsftpd.conf
[Definition]
failregex = FAIL LOGIN: Client "<HOST>"
ignoreregex =
# Configure jail
sudo nano /etc/fail2ban/jail.local
[vsftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
logpath = /var/log/vsftpd.log
maxretry = 3
bantime = 3600
findtime = 600
# Restart Fail2Ban
sudo systemctl restart fail2ban

# Check status
sudo fail2ban-client status vsftpd

Backup Configuration

# Backup vsftpd configuration
sudo tar -czf vsftpd-backup-$(date +%Y%m%d).tar.gz \
/etc/vsftpd.conf \
/etc/vsftpd/ \
/etc/pam.d/vsftpd*

# Backup FTP data
sudo tar -czf ftp-data-backup-$(date +%Y%m%d).tar.gz /srv/ftp /var/ftp

Troubleshooting

Test FTP Connection

# Test with FTP client
ftp localhost

# Test with lftp
sudo apt install -y lftp
lftp -u username localhost

# Test FTPS
lftp -u username -e "set ftp:ssl-force true" localhost

Common Issues

500 OOPS: vsftpd: refusing to run with writable root

# Solution: Make chroot directory non-writable
sudo chmod 555 /home/ftpuser
# Or enable allow_writeable_chroot

425 Security: Bad IP connecting

# Solution: Disable require_ssl_reuse
echo "require_ssl_reuse=NO" | sudo tee -a /etc/vsftpd.conf
sudo systemctl restart vsftpd

Connection refused

# Check if vsftpd is running
sudo systemctl status vsftpd

# Check firewall
sudo ufw status

# Check listening ports
sudo netstat -tlnp | grep :21

Debug Mode

# Run vsftpd in debug mode
sudo vsftpd -olisten=NO /etc/vsftpd.conf

# Check logs
sudo tail -f /var/log/vsftpd.log
sudo tail -f /var/log/syslog

FTP Client Usage

Command Line FTP

# Connect to FTP server
ftp hostname

# Common FTP commands
ftp> ls # List files
ftp> cd directory # Change directory
ftp> get file # Download file
ftp> put file # Upload file
ftp> mget *.txt # Download multiple files
ftp> mput *.jpg # Upload multiple files
ftp> binary # Binary mode
ftp> ascii # ASCII mode
ftp> passive # Passive mode
ftp> quit # Exit

LFTP (Advanced Client)

# Install lftp
sudo apt install -y lftp

# Connect
lftp -u username ftp://hostname

# Mirror directory
lftp -c "open -u username,password ftp://hostname; mirror -R /local/dir /remote/dir"

# Parallel downloads
lftp -c "open -u username,password ftp://hostname; pget -n 4 largefile.zip"

Best Practices

  1. Use FTPS: Always encrypt connections with SSL/TLS
  2. Limit Access: Use userlist to restrict access
  3. Chroot Users: Confine users to their home directories
  4. Strong Passwords: Enforce strong password policies
  5. Monitor Logs: Regularly review FTP logs
  6. Fail2Ban: Install and configure Fail2Ban
  7. Regular Updates: Keep vsftpd updated
  8. Firewall: Restrict FTP access by IP when possible
  9. Disable Anonymous: Disable anonymous FTP unless necessary
  10. Backup: Regular backups of configuration and data

Resources