在 Linux 中使用 ssh-keygen 生成 SSH 密钥

Secure Shell(SSH)是一种网络协议,用于在客户端与服务器之间建立安全连接。借助 SSH,你可以在远程机器上运行命令、创建隧道、转发端口等。

SSH 提供多种身份验证机制。最常见的两种认证方式是密码认证和公钥认证。与传统的密码认证相比,公钥认证更安全、也更方便。

本指南将介绍如何在 Linux 中使用 ssh-keygen 创建 SSH 密钥、应如何选择密钥类型,以及生成公钥后应将其安装到何处。

快速参考

CommandDescription
ssh-keygen -t ed25519Generate Ed25519 key pair
ssh-keygen -t rsa -b 4096Generate RSA key pair
ssh-copy-id user@hostCopy public key to server
ssh-add ~/.ssh/id_ed25519Add key to SSH agent
ssh-add -lList keys in agent
ssh-add -DRemove all keys from the agent
cat ~/.ssh/id_ed25519.pubDisplay public key

前提条件

在开始之前,请确保你已具备:

  1. 一台已安装 SSH 客户端的 Linux 系统(大多数发行版默认已包含)
  2. 一个用于安装公钥的位置,例如远程服务器、Git 托管服务或云服务商

检查已有的 SSH 密钥

在生成新的密钥对之前,请先检查系统中是否已存在 SSH 密钥:

ls -l ~/.ssh/id_*.pub

如果你看到类似 id_rsa.pub 或 id_ed25519.pub 的文件,说明你已经拥有 SSH 密钥。你可以直接使用已有密钥,也可以生成新的密钥。只有在选择相同文件名时,生成新密钥对才会覆盖旧密钥。

如果该命令返回 No such file or directory(无此文件或目录),说明你尚未拥有 SSH 密钥,可以继续生成新的密钥对。

生成 SSH 密钥对

ssh-keygen 命令用于创建新的 SSH 密钥对。你可以在多种密钥类型中进行选择:

  1. Ed25519(推荐)—— 现代、安全且速度快
  2. RSA —— 兼容性广泛,请使用 4096 位以保证安全

生成 Ed25519 密钥(推荐)

Ed25519 密钥更短、更快,并且被认为比 RSA 密钥更安全:

ssh-keygen -t ed25519 -C "your_email@example.com"

生成 RSA 密钥

如果你需要兼容不支持 Ed25519 的旧系统,请使用 4096 位的 RSA 密钥:

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

-C 参数用于添加一段注释(通常是你的邮箱),以便辨识该密钥。

密钥生成过程

运行命令后,系统会提示你指定密钥文件的保存位置:

Enter file in which to save the key (/home/username/.ssh/id_ed25519):

直接按 Enter 键接受默认位置,或指定自定义路径。

接下来,系统会提示你输入口令(passphrase):

Enter passphrase (empty for no passphrase):

口令为密钥增加了一层额外的安全保护。即使有人获取了你的私钥,仍需口令才能使用它。请注意,除非使用 SSH 代理,否则每次使用该密钥时都需要输入口令。

直接按 Enter 表示不设置口令;或输入一段安全的口令并再次确认。

命令输出大致如下:

Your identification has been saved in /home/username/.ssh/id_ed25519
Your public key has been saved in /home/username/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:AbCdEf1234567890AbCdEf1234567890AbCdEf12 your_email@example.com

该命令会创建两个文件:

  1. ~/.ssh/id_ed25519 —— 你的私钥(务必保密)
  2. ~/.ssh/id_ed25519.pub —— 你的公钥(可安全分享)

公钥应放置在哪里

生成密钥对只是完成了一半工作。公钥(id_ed25519.pub)必须安装到你希望登录的目标上,具体方式取决于目标类型。

你自己掌控的 Linux 服务器。使用 ssh-copy-id 将公钥安装到远程账户的 authorized_keys 文件中:

ssh-copy-id username@server_ip

系统只会让你输入一次远程用户密码。此后密钥就位,密码提示将不再出现。我们关于无密码 SSH 登录的指南对此有详细讲解。

GitHub、GitLab 或 Bitbucket。这些托管平台没有 shell 账户,因此 ssh-copy-id 不适用。请显示公钥,并将其输出粘贴到对应服务的 SSH 密钥设置中:

cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8k... your_email@domain.com

随后验证密钥能否正常连接该平台。以 GitHub 为例:

ssh -T git@github.com

云服务商。AWS、DigitalOcean 和 Hetzner 都允许你在控制面板中注册公钥,并在创建新实例时自动注入。启动服务器时,将公钥粘贴到服务商的控制台即可。

使用 SSH 代理

如果你为密钥设置了口令,每次连接都输入口令会非常繁琐。SSH 代理会将已解密的私钥保存在内存中,因此每个会话只需输入一次口令。

启动 SSH 代理:

eval "$(ssh-agent -s)"
Agent pid 12345

将私钥添加到代理中:

ssh-add ~/.ssh/id_ed25519

系统会提示你输入口令。输入之后,后续的 SSH 连接将使用缓存中的密钥,不再重复询问口令。

要列出代理中当前已加载的密钥:

ssh-add -l

管理 SSH 密钥

查看公钥

要显示你的公钥(便于添加到 GitHub 等服务):

cat ~/.ssh/id_ed25519.pub

列出所有密钥

要查看 SSH 目录中的所有密钥文件:

ls -la ~/.ssh/

从代理中移除密钥

要从 SSH 代理中移除某个特定密钥:

ssh-add -d ~/.ssh/id_ed25519

要移除代理中的全部密钥:

ssh-add -D

删除密钥对

要永久删除密钥对,需同时删除私钥和公钥文件:

rm ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub

故障排查

权限被拒绝(publickey)

如果你看到该错误,请检查以下内容:

  1. 确认公钥已写入远程服务器的 ~/.ssh/authorized_keys:
    cat ~/.ssh/authorized_keys
  2. 检查远程服务器的权限设置:
    chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

SSH 代理未运行

如果你遇到与代理相关的错误,请用以下命令启动它:

eval "$(ssh-agent -s)"

使用了错误的密钥

要指定连接所使用的密钥:

ssh -i ~/.ssh/my_custom_key username@server_ip

如需永久配置,可在 ~/.ssh/config 中添加一条记录:

Host myserver
    HostName server_ip
    User username
    IdentityFile ~/.ssh/my_custom_key

随后使用以下命令连接:

ssh myserver

总结

一对密钥可用于所有接受它的目标,因此与其重复生成,不如一次生成高质量的密钥并妥善保管好私钥。请使用强密钥类型(Ed25519),并为其设置口令加以保护。

若想让 SSH 连接更有条理,可参考我们关于使用 SSH 配置文件的指南。你也可以修改默认的 SSH 端口以提升安全性。如果某把密钥突然失效,上文的故障排查步骤通常能帮你定位原因。

如果你有任何疑问或建议,欢迎在下方留言。