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
基于密钥文件上没有密码的更好的替代方案(比原始答案)
如果没有密码,您是否需要代理,而不是让 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,一切就绪了。