vsftpd (Very Secure FTP Daemon) 以安全、輕量、高性能著稱,是 Linux 下首選的 FTP 服務器。本文提供從軟件安裝、核心配置、虛擬用戶體系構建、SSL/TLS 加密、防火牆/SELinux 配置、到自動化部署腳本的完整生產級部署指南。
# CentOS/RHEL 7/8/9, Rocky, AlmaLinux
yum install -y vsftpd db4-utils # db4-utils 提供 db_load
# Ubuntu/Debian
apt-get install -y vsftpd db-util
# 驗證安裝
rpm -ql vsftpd | head -20
vsftpd -v
/etc/vsftpd/vsftpd.conf 生產級模板# ===== 基礎運行 =====
listen=YES
listen_ipv6=NO
background=YES
# ===== 訪問控制 =====
anonymous_enable=NO # 禁用匿名
local_enable=YES # 啟用本地/虛擬用戶
write_enable=YES # 允許寫入
local_umask=022 # 默認文件權限 644
# ===== 安全核心:chroot 限制 =====
chroot_local_user=YES # 所有用戶 chroot 到家目錄
allow_writeable_chroot=YES # 允許 chroot 目錄可寫 (vsftpd 3.0+)
# chroot_list_enable=YES # 例外名單模式
# chroot_list_file=/etc/vsftpd/chroot_list
# ===== 匿名用戶權限 (已禁用,保留配置) =====
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
# ===== 日誌審計 =====
xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/vsftpd.log
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
log_ftp_protocol=YES # 記錄完整 FTP 協議交互 (調試用)
# ===== 連接參數 =====
connect_from_port_20=YES
idle_session_timeout=600
data_connection_timeout=120
accept_timeout=60
connect_timeout=60
# ===== 性能與並發 =====
max_clients=200
max_per_ip=20
local_max_rate=0 # 0=不限速,單位 B/s
# ===== PAM 認證 =====
pam_service_name=vsftpd
# ===== 用戶列表控制 (白名單模式) =====
userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd/allowed_users
# ===== TCP Wrappers =====
tcp_wrappers=YES
# ===== 虛擬用戶體系 (核心) =====
guest_enable=YES
guest_username=ftpuser # 映射的系統用戶
user_config_dir=/etc/vsftpd/user_conf
virtual_use_local_privs=YES # 關鍵:虛擬用戶使用本地用戶權限
# ===== 被動模式 (NAT/防火牆環境必配) =====
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
# pasv_address=YOUR_PUBLIC_IP # 公網 IP,留空自動檢測
# ===== SSL/TLS 加密 (強烈建議生產環境啟用) =====
ssl_enable=YES
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=YES
ssl_ciphers=HIGH
force_local_logins_ssl=YES # 強制本地用戶加密登錄
force_local_data_ssl=YES # 強制數據傳輸加密
allow_anon_ssl=NO
# 1. 創建映射系統用戶 (無 Shell、無家目錄、不可登錄)
useradd -r -s /sbin/nologin -M -d /var/ftp ftpuser
# 2. 創建基礎 FTP 根目錄
mkdir -p /var/ftp
chown ftpuser:ftpuser /var/ftp
chmod 755 /var/ftp
# 3. 創建虛擬用戶配置目錄
mkdir -p /etc/vsftpd/user_conf
chmod 755 /etc/vsftpd/user_conf
/etc/vsftpd/virtusers.txt# 格式:奇數行用戶名,偶數行密碼
webuser1
Passw0rd123!
webuser2
AnotherStr0ngPass
backupuser
BackupPass456@
db_load -T -t hash -f /etc/vsftpd/virtusers.txt /etc/vsftpd/virtusers.db
chmod 600 /etc/vsftpd/virtusers.db
chown root:root /etc/vsftpd/virtusers.db
# 安全:刪除明文文件
shred -u /etc/vsftpd/virtusers.txt
/etc/pam.d/vsftpd#%PAM-1.0
auth required pam_userdb.so db=/etc/vsftpd/virtusers
account required pam_userdb.so db=/etc/vsftpd/virtusers
session required pam_loginuid.so
# 如需密碼複雜度/過期策略,改用系統用戶認證 (pam_unix.so)
為每個虛擬用戶創建 /etc/vsftpd/user_conf/username:
# /etc/vsftpd/user_conf/webuser1
local_root=/var/www/html/site1
write_enable=YES
download_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
anon_world_readable_only=NO
local_max_rate=2097152 # 2MB/s 限速
# /etc/vsftpd/user_conf/backupuser
local_root=/backup/ftp
write_enable=NO
download_enable=YES
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
# 自簽名證書 (內網/測試用)
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/ssl/private/vsftpd.key \
-out /etc/ssl/certs/vsftpd.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=ftp.example.com"
# 生產環境請使用 Let's Encrypt 或商業證書
# certbot certonly --standalone -d ftp.example.com
# 然後指向 /etc/letsencrypt/live/ftp.example.com/fullchain.pem 等
firewall-cmd --permanent --add-service=ftp
firewall-cmd --permanent --add-port=40000-40100/tcp # 被動模式端口範圍
firewall-cmd --reload
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 40000:40100 -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
service iptables save
setsebool -P ftp_home_dir on
setsebool -P allow_ftpd_full_access on
setsebool -P ftpd_use_passive_mode on
setsebool -P ftpd_connect_db on # 如用數據庫認證
# 文件上下文 (非常重要!)
semanage fcontext -a -t public_content_rw_t "/var/ftp(/.*)?"
restorecon -Rv /var/ftp
# 虛擬用戶目錄同理
semanage fcontext -a -t public_content_rw_t "/var/www/html(/.*)?"
restorecon -Rv /var/www/html
systemctl enable --now vsftpd
systemctl status vsftpd
# 端口驗證
ss -ltnp | grep :21
ss -ltnp | grep -E ':4000[0-9]'
# 功能測試 (使用支援 FTPS 的客戶端:FileZilla, WinSCP, lftp)
lftp -u webuser1,Passw0rd123! ftps://localhost
# 或
ftp localhost
# 220 Welcome...
# USER webuser1
# 331 Please specify the password
# PASS ********
# 230 Login successful
# Remote system type is UNIX.
# ftp> ls
# ftp> put test.txt
# ftp> quit
- name: Install vsftpd
yum: name=vsftpd,db4-utils state=present
- name: Deploy vsftpd.conf
template: src=vsftpd.conf.j2 dest=/etc/vsftpd/vsftpd.conf
notify: restart vsftpd
- name: Create ftpuser
user: name=ftpuser system=yes shell=/sbin/nologin home=/var/ftp createhome=no
- name: Create virtual users DB
shell: |
db_load -T -t hash -f /etc/vsftpd/virtusers.txt /etc/vsftpd/virtusers.db
chmod 600 /etc/vsftpd/virtusers.db
args:
creates: /etc/vsftpd/virtusers.db
- name: Configure PAM
copy: src=pam_vsftpd dest=/etc/pam.d/vsftpd
- name: Configure firewall
firewalld: service=ftp permanent=yes state=enabled immediate=yes
firewalld: port=40000-40100/tcp permanent=yes state=enabled immediate=yes
- name: SELinux booleans
seboolean: name={{ item }} state=yes persistent=yes
loop:
- ftp_home_dir
- allow_ftpd_full_access
- ftpd_use_passive_mode
架構決策: 生產環境強制使用虛擬用戶 + SSL/TLS + chroot + 被動模式端口範圍。系統用戶僅作為權限映射載體 (
guest_username),不直接登錄 FTP。所有業務隔離在虛擬用戶層面,配合user_config_dir實現「一用戶一根目錄一權限」的精細管控。