Vsftpd (Very Secure FTP Daemon) 是 Linux/Unix 平台上最流行的 FTP 伺服器軟體之一,以安全、高效、穩定著稱。配合 MySQL 存儲虛擬用戶帳號,可實現:用戶認證與系統帳號完全隔離、集中管理、支援海量用戶、易於整合 Web 管理介面。本文基於 RedHat Linux 9 環境,詳細記錄從源碼編譯安裝 Vsftpd 到建立 MySQL 虛擬用戶認證的全過程。
# 確保 nobody 用戶存在(預設通常已存在)
useradd nobody
# 確保空目錄存在,供 vsftpd chroot 使用
mkdir -p /usr/share/empty
# 建立匿名 FTP 目錄與系統用戶(非虛擬用戶)
mkdir -p /var/ftp
useradd -d /var/ftp ftp
chown root.root /var/ftp
chmod og-w /var/ftp
yum install -y gcc make openssl-devel libdb-devel pam-devel mysql-devel
cd /usr/local/src
wget https://security.appspot.com/downloads/vsftpd-3.0.5.tar.gz # 以較新版本為例
tar zxvf vsftpd-3.0.5.tar.gz
cd vsftpd-3.0.5
# 編輯 builddefs.h 啟用 MySQL 支援(關鍵步驟)
# 找到 #undef VSF_BUILD_MYSQL 改為 #define VSF_BUILD_MYSQL
# 同理啟用 VSF_BUILD_PAM, VSF_BUILD_SSL 等
make
make install
注意:若 make install 未自動複製二進制與手冊頁,需手動執行:
cp vsftpd /usr/local/sbin/
cp vsftpd.conf.5 /usr/local/share/man/man5/
cp vsftpd.8 /usr/local/share/man/man8/
mkdir -p /etc/vsftpd
cp vsftpd.conf /etc/vsftpd/vsftpd.conf
cp RedHat/vsftpd.pam /etc/pam.d/vsftpd # PAM 認證配置模板
CREATE DATABASE vsftpd DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE vsftpd;
CREATE TABLE `users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(64) NOT NULL UNIQUE,
`password` VARCHAR(128) NOT NULL, -- 存儲加密後的密碼
`homedir` VARCHAR(255) NOT NULL DEFAULT '/home/vsftpd/',
`enable` TINYINT(1) NOT NULL DEFAULT 1,
`quota_files` INT UNSIGNED DEFAULT 0,
`quota_size` BIGINT UNSIGNED DEFAULT 0,
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 插入測試用戶,密碼使用 PASSWORD() 或應用層加密(如 MD5、SHA256)
INSERT INTO `users` (`username`, `password`, `homedir`) VALUES
('testuser', PASSWORD('secret123'), '/home/vsftpd/testuser/');
CREATE USER 'vsftpd'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT SELECT ON vsftpd.users TO 'vsftpd'@'localhost';
FLUSH PRIVILEGES;
yum install -y pam_mysql
# 或源碼編譯:下載 pam_mysql 源碼,./configure --with-mysql=/usr/bin/mysql_config && make && make install
#%PAM-1.0
auth required pam_mysql.so user=vsftpd passwd=StrongPassword123! host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=2 sqllog=0
account required pam_mysql.so user=vsftpd passwd=StrongPassword123! host=localhost db=vsftpd table=users usercolumn=username passwdcolumn=password crypt=2 sqllog=0
# crypt=2 表示使用 MySQL PASSWORD() 加密,若用 MD5 請改為 crypt=3 並調整存儲方式
# 基礎運行模式
listen=YES
background=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
# 虛擬用戶核心設置
guest_enable=YES
guest_username=vsftpd # 映射的系統用戶,需提前建立:useradd -d /home/vsftpd -s /sbin/nologin vsftpd
virtual_use_local_privs=YES
user_sub_token=$USER
local_root=/home/vsftpd/$USER # 每個虛擬用戶獨立家目錄
# 安全加固
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
allow_writeable_chroot=YES # 允許 chroot 目錄可寫(需 3.0+ 版本)
# PASV 模式配置(防火牆/NAT 環境必須)
pasv_enable=YES
pasv_min_port=50000
pasv_max_port=50100
pasv_address=你的公網IP或域名
# 日誌與效能
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd_xfer.log
idle_session_timeout=300
data_connection_timeout=120
# PAM 服務名稱
pam_service_name=vsftpd
mkdir -p /home/vsftpd/testuser
chown -R vsftpd:vsftpd /home/vsftpd
chmod 755 /home/vsftpd /home/vsftpd/testuser
# 建立 chroot_list 空檔案(若無特殊用戶需解除 chroot)
touch /etc/vsftpd/chroot_list
cat > /etc/systemd/system/vsftpd.service <<'EOF'
[Unit]
Description=Vsftpd FTP Server
After=network.target mysqld.service
Requires=mysqld.service
[Service]
Type=forking
ExecStart=/usr/local/sbin/vsftpd /etc/vsftpd/vsftpd.conf
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/var/run/vsftpd.pid
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable vsftpd
systemctl start vsftpd
firewall-cmd --permanent --add-port=21/tcp
firewall-cmd --permanent --add-port=50000-50100/tcp
firewall-cmd --reload
ftp localhost,輸入虛擬用戶帳密,嘗試 ls、put、get、mkdir。tail -f /var/log/vsftpd.log /var/log/secure 觀察認證過程。500 OOPS: cannot locate user entry → 系統用戶 vsftpd 未建立或 /etc/passwd 無該用戶。530 Login incorrect → PAM 配置錯誤、MySQL 連線失敗、密碼加密方式不匹配。500 OOPS: vsftpd: refusing to run with writable root inside chroot() → 家目錄權限過寬,需 chmod a-w /home/vsftpd/user 或開啟 allow_writeable_chroot=YES。pam_limits.so 或應用層定時掃描 quota_size 欄位限制上傳。ssl_enable=YES、憑證路徑,強制 FTPS。vsftpd.users 表,實現用戶自助註冊、修改密碼、查看流量。Vsftpd + MySQL 虛擬用戶方案以「輕量、安全、易擴展」成為中小型 FTP 服務的首選架構。本文涵蓋了從源碼編譯、PAM 整合、權限模型到生產級調優的完整鏈路。實際部署時,請根據業務安全等級決定是否啟用 SSL、配置審計日誌、對接單點登入 (SSO),打造企業級文件傳輸平台。