跳转至

SSH 密钥使用简要说明

预计阅读时长 : 3 分钟

验证原理

简而言之:接收方(通常是服务器或远程系统)保存公钥,发送方(通常是客户端)使用对应私钥进行身份验证。

当使用密钥对进行 SSH 身份验证时,这个过程大致如下:

  • 当你尝试通过 SSH 连接到 VPS 时,客户端会向 VPS 发出连接请求。
  • VPS 会回应一个随机生成的挑战(随机数)。
  • 客户端使用它的私钥对这个挑战进行签名,并将签名的响应发送回 VPS。
  • VPS 使用之前存储的公钥来验证客户端发送的签名。
  • 如果签名验证成功,这意味着客户端确实拥有与公钥匹配的私钥,因此身份验证成功。
  • 一旦身份验证成功,客户端和服务器就会协商并建立一个加密的通道。
  • 之后,所有通过这个通道的通信都会被加密,以确保数据的隐私和完整性。
  • 一旦加密的会话被建立,你就可以在 VPS 上执行命令、传输文件或进行其他操作。

使用密钥对进行 SSH 身份验证比使用密码更安全,因为它不依赖于密码的复杂性或强度。只要私钥保持安全并且不被泄露,攻击者即使知道公钥也无法伪造身份。

在本地客户端生成密钥对

SSH 密钥对通常使用 ssh-keygen 命令,在客户端(即你的计算机、VPS 等设备上)生成。

Windows 设备使用 Powershell

Windows 设备上必须使用 Powershell 来完成后续的命令行操作,因为 Powershell 是全局生效,后续在 VS Code 中也可以使用。

这将生成两个文件:一个是私钥(一般为 ~/.ssh/id_rsa )和一个是公钥(一般为 ~/.ssh/id_rsa.pub )。

ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx username@hostname
The key's randomart image is:
+---[RSA 2048]----+
| .o . |
| . o o |
| . . |
| . |
| . S |
| + |
+----[SHA256]-----+

一般而言,私钥只在一台设备或者客户端使用表明身份,而公钥可以在多个服务器上分发用于验证。

向远程服务器添加公钥

将公钥上传或者添加到需要访问的服务器(例如 VPS)上的 ~/.ssh/authorized_keys 文件中,这可以通过 ssh-copy-id 命令或打开文件手动复制粘贴来完成。

ssh-copy-id -i ~/.ssh/id_rsa.pub user@remote_host

当你运行 ssh-copy-id 命令时,它会提示你输入远程服务器的密码(除非你已经设置了无密码登录)。完成身份验证后,它会将公钥添加到远程服务器的 ~/.ssh/authorized_keys 文件中。

请注意,为了使 ssh-copy-id 能够正常工作,远程服务器上需要已经安装了 SSH 服务,并且你需要有写入 ~/.ssh/authorized_keys 文件的权限。

一旦公钥被添加到 authorized_keys 文件,需要访问的设备就知道应该信任这个公钥。

向本地 SSH 代理添加私钥

在某些情况下,特别是当使用像 VS Code 这样的图形界面应用程序进行 SSH 连接时,必须使用 ssh-add 命令将私钥添加到 SSH 认证代理 (ssh-agent) 中,从而使得身份验证过程更为顺畅。

Windows 设备上需要启动 OpenSSH 代理服务
  1. 打开“服务”管理工具(可以在开始菜单搜索 "Services" 或 "服务")。
  2. 找到名为 “OpenSSH Authentication Agent” 的服务。
  3. 右键点击它,选择“属性”。
  4. 在“启动类型”中选择“自动”。
  5. 点击“应用”,然后点击“启动”以启动服务。
  6. 点击“确定”关闭窗口。
ssh-add

如果没有指定任何文件,ssh-add 默认会尝试添加 ~/.ssh/id_rsa~/.ssh/id_dsa~/.ssh/id_ecdsa~/.ssh/id_ed25519

也可以根据需要,添加指定的密钥文件,但一般一台设备统一使用默认生成的密钥即可。

ssh-add /path/to/private_key

本地存储远程服务器公钥列表

~/.ssh/known_hosts 文件是 SSH 客户端用来记录已知远程主机的公钥的文件。当你首次尝试连接到一个远程主机时,SSH 会询问你是否信任该主机和其公钥。如果你选择信任,远程主机的公钥会被添加到 known_hosts 文件中。在后续的连接中,SSH 客户端会检查远程主机的公钥是否与 known_hosts 文件中的公钥匹配,以此来验证远程主机的身份。

这种机制的目的是为了防止中间人攻击(Man-in-the-Middle, MITM)。如果攻击者尝试拦截你的 SSH 连接并伪装成远程主机,他们的公钥将不会与 known_hosts 文件中的公钥匹配,SSH 客户端会发出警告。

个性化配置本地服务端

~/.ssh/config 文件是 SSH 客户端的配置文件,用于定义与 SSH 连接相关的各种参数和设置。通过使用这个配置文件,用户可以简化 SSH 命令的执行,为不同的主机或域设置不同的参数,并优化连接策略。

1
2
3
4
5
6
7
Host myserver
   HostName example.com
   User yourusername
   Port 2222
   IdentityFile ~/.ssh/id_special_rsa
   ForwardAgent yes
   ProxyCommand ssh proxyhost -q -W %h:%p

在 Github 私有仓库上添加公钥

在 Github 上添加公钥的逻辑和在 VPS 上很相似,但操作步骤上存在着比较大的差异。

  1. 复制公钥的内容。
  2. 登录到你的 GitHub 账户。
  3. 点击右上角的用户头像,选择 "Settings"。
  4. 在左侧菜单中选择 "SSH and GPG keys"。
  5. 点击 "New SSH key" 按钮。
  6. 为密钥设置一个标题,并将公钥内容粘贴到 "Key" 区域。
  7. 点击 "Add SSH key" 保存。

参考文档