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
- Use FTPS: Always encrypt connections with SSL/TLS
- Limit Access: Use userlist to restrict access
- Chroot Users: Confine users to their home directories
- Strong Passwords: Enforce strong password policies
- Monitor Logs: Regularly review FTP logs
- Fail2Ban: Install and configure Fail2Ban
- Regular Updates: Keep vsftpd updated
- Firewall: Restrict FTP access by IP when possible
- Disable Anonymous: Disable anonymous FTP unless necessary
- Backup: Regular backups of configuration and data
Resources
- Official Documentation: https://security.appspot.com/vsftpd.html
- Ubuntu vsftpd Guide: https://ubuntu.com/server/docs/service-ftp
- Configuration Reference: https://security.appspot.com/vsftpd/vsftpd_conf.html
- Alternative: Consider SFTP (SSH File Transfer Protocol) for better security