FTP (File Transfer Protocol) is used to transfer files between systems over a network. vsftpd (Very Secure FTP Daemon) is the standard FTP server on RHEL/CentOS systems. Port: 21 (control), 20 (data).
FTP Server Profile
Package: vsftpd
Daemon: vsftpd
Config file: /etc/vsftpd/vsftpd.conf
Anonymous dir: /var/ftp/pub
Port: 21 (control), 20 (data in active mode)
Log file: /var/log/vsftpd.log
Install and Start vsftpd
# yum install vsftpd* -y
# systemctl start vsftpd
# systemctl enable vsftpd
# systemctl status vsftpd
Configure Anonymous FTP Access
# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES # allow anonymous login
anon_upload_enable=YES # allow anonymous uploads
anon_mkdir_write_enable=YES # allow anonymous mkdir
anon_root=/var/ftp/pub # anonymous root directory
# Set directory permissions:
# chmod 777 /var/ftp/pub
# SELinux boolean for anonymous write:
# setsebool -P allow_ftpd_anon_write 1
# systemctl restart vsftpd
Configure Authenticated User FTP
# vim /etc/vsftpd/vsftpd.conf
local_enable=YES # allow local users to log in
write_enable=YES # allow write operations
local_umask=022 # default umask for uploaded files
# Chroot users to their home directory (security):
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list # users exempt from chroot
# systemctl restart vsftpd
Passive Mode Configuration
Passive mode is required when clients are behind NAT/firewalls. The server opens a high-numbered port for data.
# vim /etc/vsftpd/vsftpd.conf
pasv_enable=YES
pasv_min_port=10000
pasv_max_port=10100
pasv_address=192.168.1.100 # server's public IP
# Open passive port range in firewall:
# firewall-cmd --permanent --add-port=10000-10100/tcp
# firewall-cmd --reload
Secure FTP with TLS (FTPS)
# Generate SSL certificate:
# openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/vsftpd/vsftpd.key \
-out /etc/vsftpd/vsftpd.crt
# vim /etc/vsftpd/vsftpd.conf
ssl_enable=YES
rsa_cert_file=/etc/vsftpd/vsftpd.crt
rsa_private_key_file=/etc/vsftpd/vsftpd.key
force_local_data_ssl=YES
force_local_logins_ssl=YES
# systemctl restart vsftpd
Allow/Deny Users
# Block specific users (/etc/vsftpd/ftpusers — always denied):
# vim /etc/vsftpd/ftpusers
baduser1
baduser2
# User list control (/etc/vsftpd/user_list):
userlist_enable=YES
userlist_deny=YES # users IN list are DENIED
# userlist_deny=NO → users IN list are ALLOWED only
Firewall and SELinux for FTP
# RHEL 7 firewall:
# firewall-cmd --permanent --add-service=ftp
# firewall-cmd --reload
# RHEL 6 iptables:
# iptables -A INPUT -p tcp --dport 21 -j ACCEPT
# service iptables save
# SELinux booleans for FTP:
# getsebool -a | grep ftp
# setsebool -P ftp_home_dir 1 # allow access to home dirs
# setsebool -P allow_ftpd_anon_write 1 # allow anonymous write
# setsebool -P ftpd_full_access 1 # full access for authenticated users
FTP Troubleshooting
# Can't connect:
# 1. Check service: systemctl status vsftpd
# 2. Check port 21: ss -tulnp | grep 21
# 3. Check firewall: firewall-cmd --list-all
# 4. Check SELinux: sealert -a /var/log/audit/audit.log
# 5. Check logs: tail -f /var/log/vsftpd.log
# "500 OOPS: vsftpd: refusing to run with writable root inside chroot":
# Add to vsftpd.conf: allow_writeable_chroot=YES
# Test FTP from command line:
# ftp 192.168.1.100
ftp> user anonymous
ftp> ls
ftp> get filename
ftp> bye