Linux 上用 vsftpd 搭 FTP:本地用户 + 被动模式 + 防火墙

Linux 上搭 FTP 最常用 vsftpd(Very Secure FTP Daemon)——轻量、稳定、配置简单。但先说前提:FTP 是明文协议,2024 年再上生产环境只推荐 SFTP 或 FTPS。搭 FTP 通常是维护老系统 / 内网数据交换用。

安装

Ubuntu / Debian

sudo apt update
sudo apt install vsftpd

CentOS / Rocky

sudo yum install vsftpd

启动:

sudo systemctl enable --now vsftpd
sudo systemctl status vsftpd

关键配置

编辑 /etc/vsftpd.conf

# 禁用匿名(生产必须)
anonymous_enable=NO

# 允许本地用户登录
local_enable=YES

# 允许写入
write_enable=YES

# 限制用户只能在自己家目录
chroot_local_user=YES
allow_writeable_chroot=YES

# 被动模式端口范围(关键)
pasv_enable=YES
pasv_min_port=30000
pasv_max_port=31000

# UTF-8 文件名
utf8_filesystem=YES

# 日志
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log

# 默认监听 21,可改
listen_port=21

改完重启:

sudo systemctl restart vsftpd

为什么需要被动模式端口范围

FTP 协议有两种模式:

  • 主动模式(Active):客户端告诉服务器”你连回我的 xxx 端口”——服务器主动发起数据连接。大多数客户端在 NAT 后面,这条路走不通
  • 被动模式(Passive):服务器打开一个端口告诉客户端”你连过来”——现代默认

被动模式服务器需要有一段可用端口范围(例子里是 30000-31000)。防火墙必须放行这段:

sudo ufw allow 21/tcp
sudo ufw allow 20/tcp            # 主动模式(可选)
sudo ufw allow 30000:31000/tcp
sudo ufw reload

云服务器(阿里云、腾讯云、AWS)安全组里也要放行这段。经常有人本地防火墙开了、云安全组没开,一样连不上。

创建 FTP 用户

方式 1:普通本地用户

sudo adduser ftpuser
sudo passwd ftpuser

# 家目录权限
sudo mkdir -p /home/ftpuser/ftp
sudo chown -R ftpuser:ftpuser /home/ftpuser/ftp
sudo chmod 755 /home/ftpuser

方式 2:不允许 shell 登录(更安全)

sudo adduser --shell /usr/sbin/nologin ftpuser

然后 /etc/shells 里加:

/usr/sbin/nologin

不然 vsftpd 会拒绝这类用户。

SELinux(CentOS / RHEL)

sudo setsebool -P ftp_home_dir on
sudo setsebool -P ftpd_full_access on

不开 SELinux 布尔值就是”连上能列表、能创建但一写文件就 550”的经典状态。

测试

本机测:

ftp -p localhost      # -p 强制被动模式

或者用现代客户端 lftp

lftp -u ftpuser,PASSWORD ftp://localhost
> ls
> put test.txt
> bye

外部测:

lftp -u ftpuser,PASSWORD ftp://<服务器 IP>

加 TLS 变 FTPS(推荐)

明文 FTP 密码在网上裸奔。加 TLS:

# /etc/vsftpd.conf
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem

生成自签证书:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/vsftpd.pem \
  -out /etc/ssl/private/vsftpd.pem \
  -subj "/C=CN/O=Local/CN=ftp.example.com"
sudo chmod 600 /etc/ssl/private/vsftpd.pem

客户端连 FTPS(FileZilla 里选”要求显式的 FTP over TLS”)。

真正推荐:SFTP

其实根本不用装 vsftpd。Linux 只要装了 OpenSSH(99% 服务器都有),就自带 SFTP。

创建 chroot 用户:

sudo useradd --shell /usr/sbin/nologin sftpuser
sudo passwd sftpuser
sudo mkdir -p /home/sftpuser/upload
sudo chown root:root /home/sftpuser
sudo chown sftpuser:sftpuser /home/sftpuser/upload

/etc/ssh/sshd_config 末尾加:

Match User sftpuser
  ChrootDirectory /home/sftpuser
  ForceCommand internal-sftp
  AllowTcpForwarding no

重启 sshd:

sudo systemctl restart sshd

客户端用 FileZilla / WinSCP 选 SFTP 就能连——端口 22、加密传输、和 SSH 走一起、防火墙就一个端口。

没有特殊需求,SFTP 优先,FTP 一律不推荐

一句话总结

vsftpd 搭 FTP 的关键:本地用户 + 被动模式端口范围 + 防火墙放行。生产环境别用明文 FTP,改 SFTP 或者 FTPS。