如何在 Windows 11 版 WSL2 中自动启动 ssh 代理并添加我的密钥

如何在 Windows 11 版 WSL2 中自动启动 ssh 代理并添加我的密钥
OS: Windows 11 Version 10.0.22621 Build 22621
WSL version: 1.2.5.0 (WSL 2)
Linux distro: Ubuntu 22.04.2 LTS

我在 Windows 11 上的 Windows 终端窗口中运行 WSL2,并且经常通过 ssh 密钥身份验证连接到远程服务器。为此,每次打开新的 Windows 终端窗口(甚至只是现有终端中的新选项卡)时,我都需要执行

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/my_key

(这是没有密码的密钥)。这很快就会过时。每次我在 Windows 终端中启动 WSL2 会话时,有没有办法可以自动启动 ssh 代理并将我的密钥添加到其中?

答案1

基于密钥文件上没有密码的更好的替代方案(比原始答案)

你问过@u1686_grawity 的评论

如果没有密码,您是否需要代理,而不是让 ssh 客户端直接从文件加载它?

@u1686_grawity 提出了一个很好的观点,那就是大多数 SSH 客户端都会允许您直接指定密钥文件,而无需代理。

我经常通过 ssh 密钥认证连接到远程服务器。

您不一定要提到如何连接,但如果使用 stockssh命令,那么您只需在命令行上指定密钥文件即可:

ssh -i ~/.ssh/my_key <username>@site

ssh-agent在这种情况下,你根本不需要跑步。

即使您不使用ssh-proper,大多数基于 OpenSSH 的 SSH 工具也将使用相同的~/.ssh/config,这意味着您甚至可以跳过指定身份文件名。例如,~/.ssh/config使用以下命令创建一个:

Host <whatever_you_want_to_call_it>
  Hostname <hostname_or_ip>
  User <optional_username_if_different>
  IntentityFile ~/.ssh/my_key

然后,您只需简单地执行ssh <whatever_you_want_to_call_it>,其他所有内容都会从配置中提取。其他工具(如sftp和 )scp也将发挥相同的作用。

旧答案(同样有效,但需要密钥密码):

@Kolkhis 的答案当然可行,但如果您运行多个 shell(例如,在 Tmux 或 Windows Terminal 下),它将ssh-agent为每个 shell 调用一个新的运行实例。就您而言,这还不算太糟,因为您的密钥没有密码(当然,我也会提醒您不要这样做)。但是,对于有密码的密钥,您必须在运行每个 shell 时再次输入密码。它还会耗费额外的(尽管很小)启动时间和内存。

我建议keychain公用事业由 Daniel Robbins(也是 Gentoo Linux 的创建者)编写。这个小工具会检查是否存在正在ssh-agent运行的代理,如果存在,它会设置适当的环境变量来指向该代理。否则,在第一次启动时,它当然会启动一个新的代理。

它在大多数发行版的默认存储库中可用,包括 Ubuntu:

sudo apt install keychain

然后将以下内容添加到您的~/.bashrc

eval $(keychain --eval my_key)

IIRC,你甚至不需要指定密钥的路径,除非它不是在默认情况下~/.ssh/

答案2

其他人提出的解决方案.bashrc会在每次打开新终端窗口时生成一个新代理。我想在不借助第三方工具的情况下解决这个问题。所以这是我的第一次尝试:

〜/ .bash_配置文件:

ssh_pid=$(pidof ssh-agent)

if [ "$ssh_pid" = "" ]; then
        eval "$(ssh-agent -s)"
fi

不幸的是,在 WSL 上每个新的终端窗口都会产生一个新的环境,所以据我所知,没有办法为所有终端设置环境。

我注意到之前指向的套接字文件SSH_AUTH_SOCK仍然存在,并且代理仍在运行。这很好,表明我们只需要修复环境。

这是最终的解决方案,它保留原始环境并在每次打开新终端时恢复它:

〜/ .bash_配置文件:

ssh_pid=$(pidof ssh-agent)

# If the agent is not running, start it, and save the environment to a file
if [ "$ssh_pid" = "" ]; then
        ssh_env="$(ssh-agent -s)"
        echo "$ssh_env" | head -n 2 | tee ~/.ssh_agent_env > /dev/null
fi

# Load the environment from the file
if [ -f ~/.ssh_agent_env ]; then
        eval "$(cat ~/.ssh_agent_env)"
fi

这将创建一个文件 ( ~/.ssh_agent_env) 来存储环境,并在每次启动新终端时使用它来重置变量。这可确保只有一个代理实例正在运行。

还要注意,此代码不会输出任何内容 - 它是完全静默的。

答案3

您只需将这两行添加到您的.bashrc文件中即可。

打开 WSL2 的一个实例,并将以下内容放在末尾~/.bashrc。您可以使用任何文本编辑器来执行此操作 - vi/vim、ed、nano 等。

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/my_key

或者,如果您有~/.bash_aliases文件,您可以将其添加到那里。

完成后,您可以使用命令exec bash -l重新加载 bash,一切就绪了。

相关内容