在网站安全运维中,许多站长和开发者往往将精力集中在 WAF、后台加固、插件漏洞等层面,却忽略了一个最容易被攻破的入口——SFTP/SSH。攻击者会长期扫描 TCP 22/2222 端口,一旦发现开放,便立即启动撞库与爆破工具。只要还在使用密码登录,哪怕密码再复杂,风险也始终存在。本文将以 Hostease 服务器为例,深入解析如何通过 SSH Key 认证与最小权限原则,彻底封死这条最常见的入侵路径。

SFTP 并非独立服务,而是 SSH 的子系统

很多运维人员认为“我开的是 SFTP,不是 SSH”,这是一个常见的误解。事实上,SFTP 是 SSH 的一个 subsystem。每一次 SFTP 连接,都会走完整的 SSH 握手、加密与认证流程。理解这四步,就能精准定位安全控制点:

  1. 加密协商:客户端与服务器协商加密算法,生成短期会话密钥(对称加密)。
  2. 服务器身份验证:服务器通过 host key 证明身份,客户端核对指纹,防止中间人攻击。
  3. 客户端认证:密码登录(不推荐)或公钥认证(推荐)。客户端用私钥签名,服务器用 authorized_keys 中的公钥验证。
  4. 通道建立:认证后进入 internal-sftp 或 shell 等子功能。

核心要点:会话密钥负责加密传输,公私钥负责证明身份。用密码替代 Key,本质上是将身份交给了最容易被泄露、复用、撞库的秘密。

️ Host Key 与 User Key 的区别:别让管理混乱成为漏洞

很多安全问题的根源在于混淆了 Host Key 和 User Key 的管理。理解两者的差异是加固的第一步:

  • Host Key(主机密钥):位于 /etc/ssh/ssh_host_*,用于让客户端确认“连的是正确的服务器”。服务器重装或轮换后,指纹变化需要更新流程。安全级别为 root-only,严禁外传。
  • User Key(用户密钥):由客户端本地生成(如 ssh-keygen),放置在服务器的 ~/.ssh/authorized_keys 中。撤销时只需删除对应行,立即生效。

⚠️ 实践建议

  • 记录指纹、备注归属人与用途。
  • 将 host key 和 user key 分开备份与变更记录。
  • 团队内明确“谁负责加 key、谁负责清理 key”。

为什么密码登录迟早会出事?

密码登录的问题不在于“强不强”,而在于攻击面太适配自动化

  • 撞库:泄露库 + 自动化脚本,成本极低。
  • 终端中毒:键盘记录/木马直接获取密码。
  • 社工钓鱼:一次误点就足够。
  • 复用与共享:现实环境中很难完全避免。

相比之下,公钥认证的优势十分明显:

  • 私钥不会在网络上传输。
  • 私钥文件可设置 passphrase(静态保护)。
  • 高权限账号可配合硬件密钥形态,更抗钓鱼。

在编程开发中,无论是使用 JavaScript 构建前端工具链,还是用 Python 编写自动化部署脚本,亦或是用 Go 开发高并发服务,SSH Key 认证都是安全连接服务器的标准实践。

⚙️ 生成更强的 SSH Key:推荐 ed25519

在发起连接的机器上执行(本地电脑、运维机或 CI runner):

  • 推荐(更现代、更快、更短)
    ssh-keygen -t ed25519 -a 100 -C "deploy@example.com"
  • 如果必须使用 RSA(建议 4096 位)
    ssh-keygen -t rsa -b 4096 -a 100 -C "legacy-rsa@example.com"

为什么要加 -a 100?它会提高密钥派生的计算轮数:即使私钥文件不幸泄露,离线猜 passphrase 的成本也更高。

实践建议

  • 尽量给私钥设置 passphrase。
  • 自动化场景若不得不免密,需将运行环境隔离好(权限、网络、凭证管理),并限定 key 的用途与来源 IP。

TypeScriptC++ 项目中,如果涉及远程部署或文件同步,建议将 SSH Key 管理纳入 CI/CD 流程,避免硬编码密钥。

[AFFILIATE_SLOT_1]

密钥轮换与审计:别等到“离职账号还在登录”才处理

建立固定节奏的密钥管理机制,尤其是多人协作的站点运维:

  • 每季度审计一次:清理离职、停用或过期 key。
  • 发现异常:立刻撤销 key(删除 authorized_keys 对应行)。
  • 指纹登记(方便审计/工单核对):
    ssh-keygen -lf /path/to/key.pub

Host Key 变更注意:服务器重装或轮换后,客户端可能需要清理旧指纹:
ssh-keygen -R hostname

日志与防护:SSH 加密虽强,但“登录后行为”更要管

1️⃣ 先把登录行为记录清楚

  • Debian/Ubuntu:/var/log/auth.log
  • RHEL/AlmaLinux:/var/log/secure
  • systemd:journalctl -u sshd

建议至少对这些行为做告警:

  • 短时间大量失败登录
  • 某个账号突然从陌生地区/IP 登录
  • authorized_keys 被改动
  • SFTP chroot/权限异常

2️⃣ 基础对抗:Fail2ban + 连接限制 + 防火墙

  • Fail2ban:失败 N 次自动封 IP。
  • MaxStartups:限制未认证连接,防止洪泛。
  • 防火墙/安全组:尽量限制来源 IP(对安全提升非常明显)。

3️⃣ “上传目录”的安全别忽略

很多入侵不是“撞开后立刻删库”,而是先上传后门、慢慢潜伏。更稳妥的做法是:

  • 上传目录做实时/准实时扫描(自建或接入安全体系均可)。
  • 配合文件完整性监控(异常变更可追踪)。

4️⃣ 备份要有“不可篡改副本”

  • 每日快照业务目录(尤其是 chroot/SFTP 根目录)。
  • 异地保存,最好是不可变策略(防止入侵后删除历史)。
[AFFILIATE_SLOT_2]

把 SFTP 加固放进“站点整体安全闭环”

只做 SSH Key 认证还不够,建议配合网站层的安全防护、代码与文件变更监控,并做好备份工作。将 SSH/SFTP 加固作为上线的第一步,成本很低,但能直接砍掉一大类“最常见入侵路径”。

无论你使用 Python 编写自动化运维脚本,还是用 JavaScript 构建前端部署流程,亦或是用 GoC++ 开发后端服务,SSH Key 认证都应成为默认的安全基线。从今天开始,关闭密码登录,全面拥抱公钥认证,让攻击者无机可乘。