跳至主要内容

使用 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. 将以下文本输入文件,将 example.com 替换为您服务器的域名或 IP

     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

注意

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

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

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

如果您仍然被提示输入密码,则可能需要将该命令添加到您的 ~/.zshrc 文件(或 bash 的 ~/.bashrc 文件)中。