SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-07

SSH密钥管理基础:Ed25519、权限与撤销

了解SSH密钥如何工作,以及为什么每台设备应使用一个Ed25519密钥,掌握sshd要求的文件权限、SSH配置Host块和设备丢失后的密钥撤销方法。

SSH 密钥的工作原理

SSH 密钥由一对文件组成:私钥保存在您的设备上,公钥复制到您要登录的每台服务器上。建立连接时,服务器使用公钥发送质询,只有匹配的私钥才能响应。私钥不会离开您的设备,因此不会有秘密信息通过网络传输;即使服务器遭到入侵,攻击者也无法从服务器上窃取有用的私钥。这就是密钥优于密码的原因。妥善管理 SSH 密钥主要包括四个习惯:每台设备使用一个密钥、设置 sshd 要求的文件权限、使用 ~/.ssh/config 文件避免反复输入选项,以及在笔记本电脑丢失当天知道如何删除密钥。

本指南以 Ubuntu 24.04 为例介绍这四个习惯,但其中几乎所有内容都适用于任何 Linux 服务器和任何近期版本的 OpenSSH。

开始前先说明一个术语,以免造成实际错误。公钥不是机密信息。您可以将公钥粘贴到工单中、通过电子邮件发送,或直接公开发布,其他人无法仅凭公钥登录。私钥才是机密信息。任何人只要复制了该文件,并且知道该文件的口令(如果设置了口令),对于您的服务器而言,就等同于您本人。

创建密钥:ed25519 是正确的默认选择

在您自己的计算机上运行,不要在服务器上运行:

ssh-keygen -t ed25519 -C "laptop"

-t ed25519 用于选择密钥类型。Ed25519 是现代默认选择:密钥短、速度快,并且自 2014 年以来发布的所有 OpenSSH 版本都支持它。只有在必须连接不理解 ed25519 的旧设备时,才使用 ssh-keygen -t rsa -b 4096-C "laptop" 用于设置注释。注释不参与任何加密操作,但两年后您可以通过它在服务器的 authorized_keys 文件中识别此密钥,因此请将密钥所在的设备名称写入注释。

ssh-keygen 用于指定密钥的保存位置。接受默认值 ~/.ssh/id_ed25519。随后系统会要求设置密码短语。请设置一个;下面的密码短语部分会说明为什么它不会增加您日常使用的负担。最终会得到两个文件:~/.ssh/id_ed25519 是私钥,~/.ssh/id_ed25519.pub 是公钥。查看公钥内容:

cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptop

它只有一行:密钥类型、密钥材料和注释。这一行就是最终写入服务器的内容。

每台设备使用一个密钥,而不是每台服务器使用一个密钥

大家首先都会问:是否每台服务器都需要一个新密钥?不需要。为每台用于输入命令的设备创建一个密钥,然后将该公钥放到这台设备需要访问的每台服务器上。密钥用于标识设备。每台服务器上的 authorized_keys 文件列出了允许访问的设备。

这种模型可以扩展,而其他做法会以可预见的方式失效。每台服务器使用一个密钥,意味着一台需要访问 20 台服务器的笔记本电脑要保存 20 个私钥,而且你最终会分不清每个私钥对应哪台服务器。所有设备共享一个密钥则更糟:笔记本电脑被盗后,你无法在不阻止台式机访问的情况下撤销笔记本电脑的访问权限,因为两台设备持有同一个私钥。因此,你必须在所有服务器上更换该密钥,并立即将新密钥分发到每台设备。

每台设备使用一个密钥时,笔记本电脑丢失只需在每台服务器上删除一行:从 authorized_keys 中删除笔记本电脑对应的行,其他设备仍可正常工作。使用 -C 设置的注释可以帮助你快速找到这一行。

这一模型的基本规则是:私钥在设备上创建,并随设备失效。切勿将私钥复制到第二台机器,也不要将私钥上传到服务器。新设备需要访问权限时,应在该设备上生成新密钥。

在服务器上放置公钥

最简单的方法是使用 ssh-copy-id。它随 OpenSSH 一起发布:

ssh-copy-id matt@10.0.0.10

该命令会使用当前仍可用的登录方式(通常是密码)登录,将您的公钥追加到服务器上的 ~/.ssh/authorized_keys。如果目录或文件不存在,它还会创建目录和文件,并设置正确的权限。打开一个新的 SSH 会话进行测试:服务器应允许您登录,而无需输入账户密码。如果您的密钥设置了密码短语,本机可能会改为要求您输入密码短语;该提示来自本机,不是服务器密码。

如果已禁用密码登录,ssh-copy-id 将无法登录,因此您需要手动添加这一行。通过仍可用的会话或服务提供商的 Web 控制台登录,然后在服务器上运行:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptop" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

将真实的公钥粘贴到引号内。公钥必须是来自 id_ed25519.pub 的完整单行内容。authorized_keys 每行放置一个公钥,整个文件就是访问控制数据库:添加设备就是追加一行,撤销设备就是删除一行。在新服务器上,此步骤应放在新 VPS 的前 10 分钟内,并且紧接在关闭密码登录之前。

导致密钥登录失败的权限

这是密钥登录失败最常见的原因,而且客户端通常不会显示任何错误。Ubuntu 24.04 默认以 StrictModes yes 运行 sshd,因此不会使用其他用户可以修改的 authorized_keys 文件。如果该文件、~/.ssh 目录或您的主目录可由除您之外的任何用户写入,sshd 就会忽略您的密钥,转而要求输入密码,客户端不会说明原因。(Ubuntu 的 OpenSSH 只容忍一种特殊情况:文件可由您自己的私有组写入,且该组中没有其他用户。不要依赖这种行为;请使用下面的权限模式。)原因只会出现在服务器日志中:

sudo grep 'Authentication refused' /var/log/auth.log

在未安装 rsyslog 的最小化镜像中,不存在 auth.log;同一行日志位于 journal 中:sudo journalctl -u ssh | grep 'Authentication refused'

Authentication refused: bad ownership or modes for file /home/matt/.ssh/authorized_keys

修复方法是修改两项权限并检查所有权。请以受影响的用户身份在服务器上执行:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R matt:matt ~/.ssh

需要记住的规则是:.ssh 目录使用 700,其中的所有内容使用 600。您自己的计算机也适用相同的数字,因为客户端同样会检查权限。其他用户可读取的私钥会导致 ssh 直接拒绝该密钥;这次客户端会明确显示错误:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/matt/.ssh/id_ed25519' are too open.

chmod 600 ~/.ssh/id_ed25519 可以修复此问题。

~/.ssh/config:无需反复输入选项

本机上的 ~/.ssh/config 文件可以为每台服务器设置简短名称,并保存您经常输入的选项。使用 600 权限创建该文件,并为每台服务器添加一个 Host 块:

Host web1
    HostName 10.0.0.10
    User matt
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

Host db1
    HostName 10.0.0.11
    User matt
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

现在,ssh web1 会替代 ssh -p 22 matt@10.0.0.10;由于 scprsyncgit 都会读取此文件,因此同一个简短名称可在这些命令中使用。HostName 是实际地址,User 可避免您输入账户名,IdentityFile 则固定要提供的密钥。

IdentitiesOnly yes 值得单独说明,因为它可以解决一个容易混淆的故障。当您的 agent 中保存了多个密钥时,客户端会逐个提供这些密钥,服务器会将每次提供都计为一次失败尝试。加载的密钥过多时,在尝试正确密钥之前,您就会收到 Received disconnect: Too many authentication failuresIdentitiesOnly yes 会让客户端只提供 IdentityFile 中指定的密钥,因此不会发生此故障。

密码短语和 ssh-agent

密码短语会加密磁盘上的私钥文件。没有密码短语时,任何复制该文件的人都可以立即使用它;有密码短语时,被盗的文件必须先猜中密码短语才能使用。对于笔记本电脑上的密钥,这正是所需的保护措施,因为笔记本电脑可能被盗,其备份也可能泄露。

密码短语在实际使用中不会增加操作负担,原因是 ssh-agent。agent 会将解密后的密钥保存在内存中,因此您每次登录会话只需输入一次密码短语,之后的每次连接都会立即完成。大多数桌面 Linux 发行版和 macOS 已经会为您运行 agent。使用以下命令将密钥加载到 agent 中:

ssh-add ~/.ssh/id_ed25519

ssh-add -l 会列出 agent 当前保存的密钥。需要注意的是,agent 转发(ssh -A)允许远程服务器在您连接期间使用您的 agent 继续进行身份验证。因此,只应对您完全信任的服务器启用此功能,并默认关闭。

轮换和撤销:丢失笔记本电脑演练

撤销普通 SSH 密钥只需从每台配置了该密钥的服务器上的 authorized_keys 中删除对应行。不需要通知证书颁发机构,也不必等待过期日期。该行删除后,使用此密钥的新登录会立即失败。

现在就进行演练,不要等到紧急情况发生。选择一台服务器,打开 ~/.ssh/authorized_keys,根据注释找到该密钥。使用编辑器删除对应行,或按注释将其过滤掉:

grep -v ' laptop$' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys

然后,从刚刚撤销密钥的设备确认登录已失败,再从另一台设备确认登录仍然有效。请注意:删除密钥不会终止已经建立的会话,因为密钥只在登录时检查。如果撤销的是被盗设备的密钥,还应检查服务器上的 who,并终止所有无法识别的会话。

轮换执行的是相同操作,但顺序不同:在设备上生成新密钥,使用 ssh-copy-id 安装该密钥,确认新密钥可以登录,然后删除旧密钥所在的行。设备交接、密钥可能已泄露,或成员离开团队时,都应执行轮换。在两台服务器之间手动操作没有问题;但在二十台服务器之间操作时,应使用自动化工具。管理多台 Linux 服务器介绍了如何将相同的 authorized_keys 状态推送到整个服务器集群。

不要这样做

  • 不要在所有设备之间共用同一个私钥。这样一来,单台设备被盗后,您无法只撤销该设备的访问权限,除非在所有设备上更换密钥。
  • 不要将私钥提交到 git repository,即使该 repository 是私有的也不行。自动扫描器会监控公开 repository,并在推送后的几分钟内尝试使用泄露的密钥;如果之后将 repository 公开,其完整历史记录也会泄露。
  • 不要将笔记本电脑的私钥上传到服务器,让该服务器借此访问另一台服务器。应直接在服务器上生成单独的密钥,并且只在确实需要的位置授权该密钥。
  • 不要将私钥粘贴到聊天、电子邮件或工单中。公钥,即 .pub 文件,才是唯一需要共享的一部分。

当密钥能够稳定完成登录后,下一步应关闭密码认证。这样,针对服务器的持续密码猜测就完全无法成功。对应的 drop-in 配置位于VPS 上的 SSH 加固

FAQ

SSH 密钥在不发送密码的情况下如何工作?

服务器会将您的公钥保存到 ~/.ssh/authorized_keys。登录时,服务器发送一个质询;您的客户端使用私钥对质询签名,服务器再使用公钥验证签名。私钥不会离开您的设备,因此传输过程中没有可拦截的内容,服务器上也没有可重复使用的密钥可供窃取。服务器被入侵后,泄露的只有公钥,而公钥无法用于登录任何地方。

是否应为所有服务器使用同一个 SSH 密钥?

可以在多台服务器上使用同一个密钥,前提是该密钥始终保存在一台设备上。规则是每台设备使用一个密钥,而不是每台服务器使用一个密钥:将笔记本电脑的公钥放到笔记本电脑需要访问的每台服务器上,台式机则使用自己的密钥。这样可以简化吊销操作,因为设备丢失时,只需从每台服务器中删除一行可识别的记录,其他设备仍可正常工作。

.ssh 目录和 authorized_keys 应设置什么权限?

~/.ssh 上设置 700,在 authorized_keys 上设置 600,并对每个私钥设置 600;这些文件和目录的所有者应为使用它们的账户。sshd 默认以 StrictModes yes 运行,因此,如果文件或主目录可被除您之外的任何人写入,sshd 会静默忽略您的密钥,服务器认证日志或日志中唯一的记录是 Authentication refused: bad ownership or modes

如何从服务器中删除 SSH 密钥?

在该密钥获授权的账户中,从 ~/.ssh/authorized_keys 删除对应的密钥行。根据注释查找正确的行,即密钥内容后面的标签。如果使用该密钥的新登录会立即失败,但已经建立的会话仍会保持打开状态;因此,如果设备被盗,也应结束该设备的所有活动会话。对复制过该密钥的每台服务器重复此操作。

SSH 密钥是否需要设置口令短语?

对于笔记本电脑或台式机上的密钥,需要。口令短语会加密密钥文件,因此被盗或泄露的副本单独无法使用;而 ssh-agent 表示每个会话只需输入一次,而不必在每次连接时输入。服务器上用于无人值守自动化的密钥通常不设置口令短语,因为没有人员输入口令;应通过限制目标账户可执行的操作来保护这些密钥。