跳至主要内容

使用 SSH 代理转发

为了简化部署到服务器,你可以设置 SSH 代理转发以安全地使用本地 SSH 密钥。

SSH 代理转发可用于简化部署到服务器。它允许你使用本地 SSH 密钥,而不是将密钥(无密码!)放在服务器上。

如果你已经设置了 SSH 密钥与 GitHub 交互,你可能熟悉 ssh-agent。这是一个在后台运行的程序,它将你的密钥加载到内存中,这样你就不必在每次需要使用密钥时输入密码。巧妙的是,你可以选择让服务器访问你的本地 ssh-agent,就像它们已经在服务器上运行一样。这有点像要求朋友输入他们的密码,以便你可以使用他们的电脑。

查看 Steve Friedl 的技术提示指南,以获得有关 SSH 代理转发的更详细的说明。

设置 SSH 代理转发

确保你的 SSH 密钥已设置并正常工作。如果你尚未执行此操作,可以使用 我们的生成 SSH 密钥指南

你可以通过在终端中输入 ssh -T [email protected] 来测试你的本地密钥是否有效

$ ssh -T [email protected]
# Attempt to SSH in to github
> Hi USERNAME! You've successfully authenticated, but GitHub does not provide
> shell access.

我们有一个良好的开端。让我们设置 SSH 以允许代理转发到你的服务器。

  1. 使用你最喜欢的文本编辑器,打开位于 ~/.ssh/config 的文件。如果此文件不存在,你可以通过在终端中输入 touch ~/.ssh/config 来创建它。

  2. 在文件中输入以下文本,用服务器的域名或 IP 替换 example.com

     Host example.com
       ForwardAgent yes
    

警告:你可能会倾向于使用通配符,例如 Host *,以便将此设置应用于所有 SSH 连接。这并不是一个好主意,因为你将与你 SSH 到的每个服务器共享你的本地 SSH 密钥。它们无法直接访问密钥,但它们可以在建立连接时以你的身份使用它们。你只应添加你信任且打算用于代理转发的服务器。

测试 SSH 代理转发

要测试代理转发是否适用于你的服务器,你可以 SSH 到你的服务器并再次运行 ssh -T [email protected]。如果一切正常,你将获得与本地相同的提示。

如果你不确定是否正在使用本地密钥,你还可以检查服务器上的 SSH_AUTH_SOCK 变量

$ echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
> /tmp/ssh-4hNGMk8AZX/agent.79453

如果未设置变量,则表示代理转发不起作用

$ echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
> [No output]
$ ssh -T [email protected]
# Try to SSH to github
> Permission denied (publickey).

解决 SSH 代理转发问题

以下是解决 SSH 代理转发问题时需要注意的一些事项。

你必须使用 SSH URL 来签出代码

SSH 转发仅适用于 SSH URL,不适用于 HTTP(s) URL。检查服务器上的 .git/config 文件并确保 URL 是以下所示的 SSH 样式 URL

[remote "origin"]
  url = [email protected]:YOUR_ACCOUNT/YOUR_PROJECT.git
  fetch = +refs/heads/*:refs/remotes/origin/*

你的 SSH 密钥必须在本地工作

在你可以通过代理转发使密钥工作之前,它们必须首先在本地工作。我们的生成 SSH 密钥指南可以帮助你本地设置 SSH 密钥。

你的系统必须允许 SSH 代理转发

有时,系统配置不允许 SSH 代理转发。你可以通过在终端中输入以下命令来检查是否正在使用系统配置文件

$ ssh -v URL
# Connect to the specified URL with verbose debug output
> OpenSSH_8.1p1, LibreSSL 2.7.3
> debug1: Reading configuration data /Users/YOU/.ssh/config
> debug1: Applying options for example.com
> debug1: Reading configuration data /etc/ssh_config
> debug1: Applying options for *
$ exit
# Returns to your local command prompt

在上面的示例中,首先加载文件 ~/.ssh/config,然后读取 /etc/ssh_config。我们可以检查该文件以查看它是否通过运行以下命令覆盖了我们的选项

$ cat /etc/ssh_config
# Print out the /etc/ssh_config file
> Host *
>   SendEnv LANG LC_*
>   ForwardAgent no

在此示例中,我们的 /etc/ssh_config 文件明确指定 ForwardAgent no,这是阻止代理转发的途径。从文件中删除此行应再次使代理转发正常工作。

服务器必须允许 SSH 代理在入站连接上转发

代理转发也可能在服务器上被阻止。你可以通过 SSH 登录服务器并运行 sshd_config 来检查是否允许代理转发。此命令的输出应表明已设置 AllowAgentForwarding

本地 ssh-agent 必须正在运行

在大多数计算机上,操作系统会自动为你启动 ssh-agent。但是,在 Windows 上,你需要手动执行此操作。我们有 关于如何在你每次打开 Git Bash 时启动 ssh-agent 的指南

要验证 ssh-agent 是否在你的计算机上运行,请在终端中键入以下命令

$ echo "$SSH_AUTH_SOCK"
# Print out the SSH_AUTH_SOCK variable
> /tmp/launch-kNSlgU/Listeners

你的密钥必须对 ssh-agent 可用

你可以通过运行以下命令来检查你的密钥是否对 ssh-agent 可见

ssh-add -L

如果命令显示没有可用的身份,则需要添加你的密钥

ssh-add YOUR-KEY

在 macOS 上,ssh-agent 会在重启期间重新启动后“忘记”此密钥。但你可以使用此命令将你的 SSH 密钥导入钥匙串

ssh-add --apple-use-keychain YOUR-KEY

注意:当你将 SSH 密钥添加到 ssh-agent 时,--apple-use-keychain 选项会为你将密码存储在钥匙串中。如果你选择不为你的密钥添加密码,请在不使用 --apple-use-keychain 选项的情况下运行该命令。

--apple-use-keychain 选项位于 Apple 的标准版 ssh-add 中。在早于 Monterey (12.0) 的 macOS 版本中,--apple-use-keychain--apple-load-keychain 标志分别使用语法 -K-A

如果你没有安装 Apple 的标准版 ssh-add,你可能会收到错误。有关更多信息,请参阅“错误:ssh-add:非法选项 -- apple-use-keychain”。

如果你继续收到密码提示,你可能需要将命令添加到你的 ~/.zshrc 文件(或你的 ~/.bashrc 文件,用于 bash)。