VPS SSH 加固:禁用密码和 root 登录
在 VPS 上加固 SSH:先确认密钥认证,再用 Ubuntu 24.04 的 drop-in 配置禁用密码和 root 登录,并配合 Fail2ban 与 VPN。
为什么 SSH 是首先需要加固的服务
SSH 用于控制服务器,因此是攻击者首先尝试突破的入口。VPS 上线后,扫描器就会开始在 22 端口尝试猜测用户名和密码。几分钟内,您就能在日志中看到这些尝试。加固 SSH 的重点是移除攻击者可以猜测的认证方式:完全禁用密码登录,禁用 root 登录,只允许使用加密密钥登录。完成这些设置后,持续的密码尝试就无法成功,因为系统中不存在可供猜测的密码。
这里假设您已经可以使用 SSH。如果您能够登录,就可以对其进行加固。请按顺序执行这些步骤,并保持当前会话打开,直到新的会话确认可用。这样,即使配置出错,也不会把您锁在服务器之外。
第 1 步:先确认密钥认证正常
密钥认证使用密钥对替代密码:私钥保留在您的计算机上,公钥放置在服务器上。服务器可以证明您持有私钥,而私钥始终不会离开您的计算机。禁用密码前,请先确认密钥认证正常,否则您可能会被锁在服务器之外。
在您自己的计算机上,如果还没有密钥,请创建一个:
ssh-keygen -t ed25519将公钥复制到服务器:
ssh-copy-id user@your-server然后新建一个 SSH 会话。如果无需输入密码即可登录,说明密钥认证正常,您可以安全地关闭密码认证。如果系统显示 Permission denied (publickey) 并阻止您登录,该错误可能对应五种不同的故障;ssh -v 的输出会在您进行其他更改前告诉您具体是哪一种。如果您不熟悉密钥,或使用多台计算机,SSH 密钥管理基础会介绍完整模型:每台设备使用一个密钥、sshd 要求的权限,以及笔记本电脑丢失时如何撤销密钥。
第 2 步:使用 drop-in 文件强化 sshd
不要直接编辑 /etc/ssh/sshd_config。Ubuntu 24.04 会从 /etc/ssh/sshd_config.d/ 读取 drop-in 文件。在该目录中创建一个小文件更清晰,可在软件包升级后保留;如果出现问题,也容易删除。文件名很重要:sshd 对每个设置只保留首次读取到的值,而 Ubuntu 云镜像会在该目录中提供 50-cloud-init.conf,其中包含 PasswordAuthentication yes。将文件命名为 00-,使其排序在该文件之前并优先生效;使用 99- 文件则会静默失效。创建文件:
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf将以下内容写入:
# Key-only login: no passwords to guess.
PasswordAuthentication no
KbdInteractiveAuthentication no
# No direct root login. Log in as your user, then use sudo.
PermitRootLogin no每一行都会关闭一条攻击路径。PasswordAuthentication no 是关键设置:禁用密码后,暴力破解攻击就没有可破解的密码。KbdInteractiveAuthentication no 会关闭第二条基于密码的路径。PermitRootLogin no 表示攻击者必须知道您的用户名并持有您的密钥,而不能只针对每台服务器上都存在的那个账户 root。
步骤 3:测试配置,然后重新加载
应用配置前先检查是否存在错误,避免拼写错误导致服务中断:
sudo sshd -t如果没有输出,说明配置有效。重新加载 SSH:
sudo systemctl reload ssh然后检查 sshd 实际使用的设置,以便发现被其他文件覆盖的 drop-in 配置:
sudo sshd -T | grep -Ei 'passwordauthentication|permitrootlogin'两条命令都应输出 no。现在不要关闭当前会话,而是从另一个终端新建一个会话。如果使用密钥成功登录,说明配置完成。如果存在问题,原会话仍保持打开状态,可以用来修复问题。这个并行会话是安全保障,因此不要跳过。
第 4 步:可选的非标准端口
将 SSH 从 22 端口迁移到 2222 等端口,并不会真正提高安全性,因为有针对性的攻击者会扫描所有端口。这样做可以减少日志噪声,因为大多数自动化扫描器只尝试 22 端口。如果需要这样配置,请先将 Port 2222 添加到 drop-in 文件,并先在防火墙中放行新端口,然后运行 sudo systemctl daemon-reload && sudo systemctl restart ssh.socket,再使用 ssh -p 2222 连接。在 Ubuntu 24.04 中,ssh.socket 负责监听端口,因此单独运行 reload ssh 仍会让 sshd 监听 22 端口;只有重启 socket 才会应用新端口。将此配置视为整理措施,而不是安全防护。
第 5 步:叠加其他防御措施
强化后的 SSH 密钥是基础,还需要在此基础上增加两层防御。
Fail2ban 会监控日志,并封禁持续认证失败的地址,从而减少扫描噪声并尽早将其排除。它与仅使用密钥的身份验证方式十分匹配:参见 在 Ubuntu 上配置 Fail2ban 以阻止 SSH 攻击。
更强的做法是完全不让 SSH 暴露在公网中。如果将 SSH 放在 WireGuard VPN 后面,并将端口 22 的访问限制在该隧道内,那么 VPN 外部的任何人都无法连接到 SSH。此时暴力猜测不再只是困难,而是根本无法进行。上述配置都以底层已设置默认拒绝规则的防火墙为前提,参见在 VPS 上配置 UFW。
SSH 只是更大检查清单中的一项:新 VPS 的前 10 分钟会按顺序列出这些步骤,在 Ubuntu 上启用自动安全更新则会在之后持续为服务器安装补丁。锁好 SSH 入口并不能保护其后的服务。因此,如果同一台 VPS 运行密码库,对 Vaultwarden 进行加固检查可以覆盖密钥身份验证无法保护的两项内容:管理员令牌和备份文件。
FAQ
如何在 Ubuntu 24.04 上禁用 SSH 密码登录?
在 /etc/ssh/sshd_config.d/00-hardening.conf 创建 drop-in 文件。00 前缀会使它排在 50-cloud-init.conf 之前,否则 PasswordAuthentication yes 中的值会生效,因为 sshd 会保留它读取到的第一个值。文件中写入 PasswordAuthentication no 和 KbdInteractiveAuthentication no,运行 sudo sshd -t 检查配置,然后运行 sudo systemctl reload ssh。在依赖新会话之前,先确认密钥登录正常。编辑 drop-in 文件而不是 sshd_config,可以避免包升级覆盖配置,也便于撤销更改。
是否应禁用通过 SSH 登录 root?
应当禁用。设置 PermitRootLogin no,禁止任何人直接以 root 登录。使用普通用户登录,再通过 sudo 执行管理任务。每台 Linux 服务器上都存在 root 账户,因此保留该登录入口会让攻击者获得一个已知的目标用户名。禁用 root 登录后,攻击者必须知道您的账户名,并持有您的密钥。
更改 SSH 端口能否提高服务器安全性?
效果不明显。将 SSH 移出端口 22,可以避开只扫描 22 端口的简单扫描器,从而减少日志噪声;但真正的攻击者会扫描所有端口,仍然可以找到新端口。真正能阻止入侵的是仅使用密钥进行身份验证。如果更改端口,请先在防火墙中放行新端口,然后运行 sudo systemctl daemon-reload && sudo systemctl restart ssh.socket;在 Ubuntu 24.04 上,监听器由 socket 管理,直接 reload 会使 sshd 继续监听端口 22。
使用 SSH 密钥后,是否还需要 Fail2ban?
Fail2ban 不是必需的,但仍然有用。仅使用密钥进行身份验证时,密码猜测无法成功,因此阻止攻击者的不是 Fail2ban。它会限制单个地址的重复失败请求速率,减少日志中的扫描器噪声,并提前阻止反复发起攻击的来源;缓慢的分布式攻击仍可能低于其封禁阈值。可以在密钥身份验证之上运行 Fail2ban,最好还通过 VPN 保护 SSH。
如果被锁在 SSH 外,如何恢复访问?
使用服务提供商的 Web 控制台。它通过不经过 SSH 的串行连接或 VNC 连接访问服务器。您可以从控制台登录,修复 sshd drop-in 文件,然后 reload 服务。这正是为什么应在关闭第一个会话前,先在第二个终端中测试新的 SSH 配置;也正是为什么在关闭密码登录前,必须先确认密钥身份验证已经正常工作。