FTP/SFTP安全,禁止明文FTP
很多服务器安全基线里会有一条:402.FTP/SFTP安全,禁止明文FTP,全部使用sftp密钥认证。
这条要求并不复杂,核心就是两件事:把不加密的FTP服务停掉,让文件传输走基于SSH的SFTP,并且登录时用密钥而非密码。
本文按零基础可操作的方式,带你完成从检查、关闭、配置到验证的全过程。
为什么安全基线要禁止明文FTP
传统FTP服务(比如vsftpd、Pure-FTP)默认使用明文传输,账号和密码在网络上直接可见,攻击者抓包就能拿到。
一旦密码泄露,服务器文件和数据就可能被随意读取或篡改。
SFTP不是FTP的加密版,它直接走SSH协议,传输全程加密。
启用密钥认证后,即使服务端密码被猜中,没有私钥也无法登录,安全性明显更高。
动手前的检查清单
开始改动前,先确认你具备以下条件:
- 有服务器的
root或sudo权限。 - 服务器已安装OpenSSH服务(Linux一般自带,可通过
ssh -V确认)。 - 准备一个SSH客户端,Windows推荐WinSCP或FileZilla,macOS/Linux直接用终端
sftp命令即可。 - 如果使用宝塔面板,请先做好快照,或至少记录原FTP端口和账号,方便回退。
不建议在业务高峰期操作,建议先在测试机验证流程。
逐步切换:停止FTP,启用SFTP密钥认证
第一步:停止并禁用FTP服务
先看服务器装了哪个FTP服务:
systemctl status vsftpd
systemctl status pure-ftpd
如果服务存在,执行停止并禁止开机自启:
systemctl stop vsftpd
systemctl disable vsftpd
systemctl stop pure-ftpd
systemctl disable pure-ftpd
宝塔用户可以在后台“软件商店”找到对应FTP服务,直接停止并设置为“不启动”。
同时建议在安全组/防火墙里放行规则中删除21端口,彻底断开明文FTP入口。
第二步:确认SSH自带SFTP功能
绝大多数Linux发行版自带SFTP子系统,只需确认sshd配置中没有被禁用。
编辑SSH配置文件:
vim /etc/ssh/sshd_config
找到或添加下面这一行,确保存在且未被注释:
Subsystem sftp internal-sftp
如果原本是 /usr/lib/openssh/sftp-server,也可以保留,不过推荐用 internal-sftp,权限控制更灵活。
第三步:生成SSH密钥对并部署公钥
在本地电脑(非服务器)上生成密钥对:
ssh-keygen -t ed25519 -C "your_email@example.com"
一路回车即可,生成后默认在 ~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)。
生产环境建议给私钥设置口令,防止私钥文件被拷贝后直接使用。
将公钥上传到服务器并写入目标用户的 authorized_keys:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_server_ip
如果没有 ssh-copy-id,可手动操作:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA... 你的公钥内容" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
先不要急着关闭密码登录,先用密钥方式测试能正常连接:
ssh -i ~/.ssh/id_ed25519 user@your_server_ip
登录成功后再进行下一步。
第四步:在sshd_config中强制密钥认证
为了满足“全部使用sftp密钥认证”,需要关闭密码认证。
编辑 /etc/ssh/sshd_config,找到并修改以下参数:
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
同时,如果你只想限制SFTP用户,不想让普通SSH登录也受太大影响,可以在文件末尾追加一个Match组,单独指定规则,这里不做展开。
重点是上面的三个配置可以统一关闭密码登录,让所有SSH接入(包括SFTP)都只能用密钥。
保存后重载SSH服务:
systemctl restart sshd
注意:修改sshd_config时请保留原文件备份(如 sshd_config.bak)。
最容易踩的坑
- 密钥权限不对:服务器的
~/.ssh目录必须是700,authorized_keys必须是600,~目录不能对组和其他用户有写权限,否则SSH会拒绝使用密钥。 - 关闭密码登录太心急:建议先保持密码登录,测试好密钥连接,确认万无一失后再关,避免把自己锁在门外。
- 防火墙/SELinux拦截:如果SFTP连不上,检查云安全组是否放行22端口,以及SELinux是否需要调整:
setsebool -P ssh_sysadm_login 1(按需)。 - 宝塔面板的FTP残留:宝塔的FTP和SSH是独立管理的,即使关闭了FTP,SSH仍然可以通过SFTP方式连接,无需重启面板。
连接验证与排错
在WinSCP或FileZilla中,协议选择“SFTP”(SSH File Transfer Protocol),端口填22,用户名填服务器用户,登录方式选“密钥”,加载私钥文件。
如果用的是命令行:
sftp -i ~/.ssh/id_ed25519 user@your_server_ip
能进入SFTP交互界面即说明密钥认证成功。
再验证明文FTP是否真的关闭:在本地执行 telnet your_server_ip 21 或 nc -vz your_server_ip 21,应提示连接超时或拒绝连接。
同时查看SSH日志,确认没有密码登录成功记录:
grep "Accepted password" /var/log/secure
如果没有任何输出,说明密码认证已经全面禁止。
完成以上步骤后,你的服务器就满足了“禁止明文FTP,全部使用sftp密钥认证”的安全基线要求。
如果后续需要调整或回退,只需恢复sshd_config备份并重新启用FTP服务即可。
遇到异常时,优先检查密钥权限和防火墙,这两个地方最容易出问题。