先确认:确实需要 FTP,而不是 SFTP
FTP 兼容性好,老系统、硬件设备和部分数据交换程序仍会使用它;但传统 FTP 的账号、密码和数据默认明文传输。若只是从个人电脑向云服务器传文件,且服务器已经开启 SSH,SFTP 往往更省事:它只用 SSH 端口,不需要额外维护被动端口段。本文适用于业务明确要求 FTP 协议,或需要兼容既有客户端的场景。
使用边界:普通 FTP 可用于受控网络中的兼容性测试。长期跨公网使用时,优先改用 SFTP;无法替换协议时,应进一步配置显式 FTPS,并限制来源 IP。
主动模式和被动模式,差别在第二条连接
FTP 登录、输入命令走 TCP 21,这只是控制连接。列目录、上传和下载还要建立数据连接。主动模式由服务器反向连接客户端,客户端位于家庭路由器或公司 NAT 后面时经常失败;被动模式由客户端再连接服务器的一个高位端口,更适合云服务器。

图 1|FTP 有控制连接和数据连接两条通道;云服务器场景通常使用被动模式。
本文将被动端口设为 TCP 40000—40100。这个范围足够小型站点和日常文件交换使用,也便于做最小化放行。并发量较大时可以扩大范围,但 vsftpd 配置、腾讯云访问控制和系统防火墙必须保持一致。
准备环境:不要再把 CentOS 7 当作新装首选
CentOS Linux 7 已于 2024 年 6 月 30 日结束维护。旧实例可以参考相同原理排查,但新建服务器更适合选择仍在支持周期内的 Ubuntu LTS、TencentOS Server 或 Rocky Linux。下面同时给出 apt 与 dnf 两套命令。
系统 包管理 / 防火墙 主配置文件
Ubuntu 22.04 / 24.04 LTS // apt/ ufw/ etc/vsftpd.conf
TencentOS Server / Rocky Linux 9 dnf / firewalld /etc/vsftpd/vsftpd.conf
CentOS 7(旧实例) yum / firewalld 不建议新部署,先安排系统升级
步骤一:安装并启动 vsftpd

图 2|安装 vsftpd,并设置为立即启动和开机自启。
状态显示 active (running) 只代表进程已启动,还不能说明公网客户端能够传文件。接下来要处理用户目录、被动模式和端口放行。
步骤二:创建 FTP 专用用户和可写目录
比起直接让用户写入 chroot 根目录,更稳妥的方式是把根目录交给 root,只建立一个可写的 upload 子目录。这样既能把用户限制在指定目录内,也不必依赖 allow_writeable_chroot=YES 来放宽检查。

图 3|chroot 根目录由 root 持有,只把 upload 子目录交给 ftpuser 写入。
路径说明:command -v nologin 会返回当前系统的实际路径。若系统使用 PAM 检查登录 Shell,需确保该路径存在于 /etc/shells,否则可能出现 530 Login incorrect。
步骤三:配置 vsftpd 被动模式
修改前先备份原文件。Ubuntu 编辑 /etc/vsftpd.conf;TencentOS Server 和 Rocky Linux 通常编辑 /etc/vsftpd/vsftpd.conf。图中的 203.0.113.10 是文档示例地址,必须替换成实例实际公网 IPv4。

图 4|被动模式最小配置。示例公网 IP 必须替换,配置行末不要追加注释。
配置文件细节:vsftpd.conf 的有效指令应单独占一行,并使用 option=value 格式。不要把中文说明或行尾注释一起粘贴到指令后面;需要说明时另起一行,以 # 开头。
pasv_address 决定服务器在 PASV 响应中告诉客户端去连接哪个地址。云服务器存在公网映射时,应填写客户端实际可达的公网地址。若实例公网 IP 会变化,可以使用稳定域名并配合 pasv_addr_resolve=YES,但要确认 DNS 更新机制可靠。
步骤四:放通腾讯云安全组和系统防火墙
端口需要在两层同时放行:CVM 使用安全组,轻量应用服务器使用实例防火墙;Linux 内部如果启用了 ufw 或 firewalld,还要放通同样的端口。任意一层遗漏,都会出现控制连接正常、数据连接失败的现象。

图 5|云平台访问控制与操作系统防火墙都要放行 TCP 21 和同一被动端口段。
规则 协议 / 端口 / 来源建议
FTP 控制连接 /TCP 21/管理员或业务客户端固定公网 IP / CIDR
FTP 被动数据连接/TCP 40000—40100/与控制连接保持相同来源范围
不要默认全网开放:0.0.0.0/0 代表所有 IPv4 地址。只有临时联调且无法确定客户端地址时才考虑短时间使用,验证完应立即收窄来源。腾讯云安全组为有状态访问控制,允许的入站连接会自动允许相应返回流量。
步骤五:重启、连接并完成一次真实传输
先检查配置是否能让服务正常重启,再确认 TCP 21 正在监听。随后用 FileZilla 或 WinSCP 从服务器外部连接;客户端选择 FTP、端口 21 和被动模式,填写公网 IP、ftpuser 与对应密码。只登录成功还不够,至少要完成一次上传、刷新目录和下载。
图 6|先看服务和监听端口,再从公网客户端完成一次上传与下载。
若尚未配置 TLS,客户端中的“普通 FTP”只适合联调或受控网络。连接验证通过后,生产环境应继续完成 FTPS,或评估直接迁移到 SFTP。
上线前的安全检查
☐ 匿名访问保持关闭,FTP 账号不与日常 SSH 管理账号混用。
☐ 安全组与轻量实例防火墙只允许必要来源,不长期使用 0.0.0.0/0。
☐ chroot 根目录不可写,上传内容只落在明确授权的子目录。
☐ 确认日志可用,并定期检查异常登录、爆破和大量失败连接。
☐ 敏感数据或长期公网传输使用 SFTP / FTPS,不以“修改 21 端口”代替加密和访问控制。
一份更实用的完成标准
FTP 部署完成,不应只看 systemctl 的绿色状态。更可靠的判断是:外部客户端能登录、能列目录、能在 upload 中上传文件、能把同一文件下载回来;同时,用户无法离开指定根目录,未授权来源也无法连接。达到这几项,服务才算真正可用。
附录:可复制命令与配置
正文中的操作步骤采用图片呈现。为方便实际执行,下面保留等价的纯文本命令。执行前请替换示例 IP,并再次确认系统与配置文件路径。
连接模型无需复制命令
控制连接使用 TCP 21;被动模式的数据连接由客户端发起,目标端口为服务端配置的被动端口范围。
复制:安装与启动
# Ubuntu 22.04 / 24.04 LTS
sudo apt update
sudo apt install -y vsftpd
sudo systemctl enable --now vsftpd
# TencentOS Server / Rocky Linux 9
sudo dnf install -y vsftpd
sudo systemctl enable --now vsftpd
# 查看服务状态
systemctl status vsftpd --no-pager
复制:用户与目录
NOLOGIN="$(command -v nologin)"
sudo useradd -d /srv/ftp/ftpuser -s "$NOLOGIN" ftpuser
sudo passwd ftpuser
# 若 nologin 不在 /etc/shells 中,将实际路径加入该文件
grep -qxF "$NOLOGIN" /etc/shells || echo "$NOLOGIN" | sudo tee -a /etc/shells
sudo mkdir -p /srv/ftp/ftpuser/upload
sudo chown root:root /srv/ftp/ftpuser
sudo chmod 755 /srv/ftp/ftpuser
sudo chown ftpuser:ftpuser /srv/ftp/ftpuser/upload
复制:vsftpd 配置
# Ubuntu:/etc/vsftpd.conf
# TencentOS / Rocky:/etc/vsftpd/vsftpd.conf
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES
local_root=/srv/ftp/ftpuser
userlist_enable=YES
userlist_deny=NO
userlist_file=/etc/vsftpd.allowed_users
listen=YES
listen_ipv6=NO
pasv_enable=YES
pasv_min_port=40000
pasv_max_port=40100
pasv_address=203.0.113.10
xferlog_enable=YES
# 建立允许登录的用户清单
echo ftpuser | sudo tee /etc/vsftpd.allowed_users
复制:操作系统防火墙
# Ubuntu / ufw:将示例地址换成客户端固定公网 IP
sudo ufw allow from 198.51.100.25 to any port 21 proto tcp
sudo ufw allow from 198.51.100.25 to any port 40000:40100 proto tcp
sudo ufw reload
# TencentOS / Rocky / firewalld
sudo firewall-cmd --permanent --add-port=21/tcp
sudo firewall-cmd --permanent --add-port=40000-40100/tcp
sudo firewall-cmd --reload
复制:验证与日志
sudo systemctl restart vsftpd
sudo systemctl status vsftpd --no-pager
sudo ss -lntp | grep ':21'
sudo journalctl -u vsftpd -n 50 --no-pager
# 可选:用 curl 验证被动模式(会提示输入密码)
curl --ftp-pasv -u ftpuser ftp://203.0.113.10/