在Windows上启动Git Bash时运行SSH代理

211

我正在使用Git Bash。我必须使用

eval `ssh-agent.exe`
ssh-add /my/ssh/location/
每次我启动新的Git Bash时,是否有一种方法可以永久设置SSH代理?或者Windows有管理SSH密钥的好方法吗?作为一个新手,请给我提供详细的教程,谢谢!

4
/my/ssh/location//c/Users/Foobar/.ssh/ 这样的路径是等价的吗? - Nick
一个类似的问题已经在 https://superuser.com/q/1238486/478378 上发布并已解决。以下要点包含在此 https://gist.github.com/jiggneshhgohel/afe96f0d57bdbf8beba305a73905402d 中。谢谢。 - Jignesh Gohel
对于遇到这个问题的人,如果你的 ssh -Tv git@server-host-name 可以工作,在我这个案例中,是由于 GIT_SSH 环境变量设置为 Tortoise Git 的 Putty Plink。删除 GIT_SSH 就解决了问题,TortoiseGit 仍然可以正常使用。 - Poutrathor
1
回应@Nick在上面点赞的评论问题:不,它不能是目录,必须是私钥文件,例如ssh-add ~/.ssh/my_private_key.pem - Ben
现在Windows中已经安装了OpenSSH,还有一个只需要启用的ssh-agent服务。安装Git以使用外部SSH进行安装。当我找到如何将其转发到WSL2时,我会写出完整的答案。 - Jan Hudec
11个回答

192

2013年:在 git bash 会话中,您可以将脚本添加到 ~/.profile~/.bashrc~ 通常设置为 %USERPROFILE%),以便该会话自动启动 ssh-agent
如果文件不存在,请创建它。

这是 GitHub 在“使用 SSH 密钥口令”中所描述的。

该文章的“在 Git for Windows 上自动启动 ssh-agent”部分有一个强大的脚本,用于检查代理是否正在运行。
下面只是一小段代码,请参考 GitHub 文章以获取完整解决方案。

# This is just a snippet. See the article above.
if ! agent_is_running; then
    agent_start
    ssh-add
elif ! agent_has_keys; then
    ssh-add
fi

其他资源:

"在Windows命令行中运行git时让ssh-agent工作"有一个类似的脚本,但我主要会参考上面的GitHub文章,它更加健壮和更新。


hardsetting评论中添加(2018):

如果你想第一次需要密码时输入密码,而不是在打开shell时输入密码,我认为最干净的方法是:

这样你甚至不用记得运行ssh-add


Tao评论中添加(2022):

值得注意的是,为什么这个脚本在Windows上特别有意义,而不是像其他答案中由@JigneshGohel指出的更标准的linuxey脚本:

通过完全不依赖SSH_AGENT_PID,这个脚本可以在不同的msys和cygwin环境中使用。
代理可以在msys2中启动,并且仍然可以在git bash中使用,因为SSH_AUTH_SOCK路径可以在任何一个环境中到达。
一个环境中的PID无法在另一个环境中查询,因此基于PID的方法会在每次切换时重置/创建新的ssh-agent进程。


@Gordon,这个GitHub链接的哪一部分发生了变化?它的内容仍然存在,并且似乎仍然与这个答案相关。 - VonC
1
@Andy2K11 如果你想在第一次需要输入密钥短语时输入它,而不是在打开shell时输入,对我来说最干净的方法是从.bash_profile中删除ssh-add,就像你提到的那样,并将“AddKeysToAgent yes”添加到你的.ssh/config文件中(参见此答案:https://superuser.com/a/1114257/523133)。 这样你甚至不必记得运行ssh-add。 - hardsetting
1
值得注意的是,为什么这个脚本在Windows中特别有意义,而不是像@JigneshGohel在另一个答案中提到的更标准的Linux脚本:通过根本不依赖于SSH_AGENT_PID,这个脚本可以在不同的msys和cygwin环境中工作。代理可以在msys2中启动,并且仍然可以在git bash中使用,因为SSH_AUTH_SOCK路径可以在任一环境中访问。一个环境中的PID无法在另一个环境中查询,因此基于PID的方法会在每次切换时重置/创建新的ssh-agent进程。 - Tao
@Tao 謝謝您的反饋。我已將您的評論包含在答案中,以增加其可見性。 - VonC
我在Windows 11上收到了“agent_start:命令未找到”的错误提示。 - Nermin
显示剩余3条评论

36

P.S:这些说明是针对在Windows 10 Linux子系统中打开的Bash shell,并且不涉及将在Windows上生成的SSH密钥与“Bash on Ubuntu on Windows”链接的问题。

1)通过在.bashrc中添加以下内容来更新它:

# Set up ssh-agent
SSH_ENV="$HOME/.ssh/environment"

function start_agent {
    echo "Initializing new SSH agent..."
    touch $SSH_ENV
    chmod 600 "${SSH_ENV}"
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' >> "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add
}

# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    kill -0 $SSH_AGENT_PID 2>/dev/null || {
        start_agent
    }
else
    start_agent
fi

2)然后运行$ source ~/.bashrc重新加载配置。

以上步骤来自https://github.com/abergs/ubuntuonwindows#2-start-an-bash-ssh-agent-on-launch

3)如果不存在,请创建一个SSH配置文件。使用以下命令创建新的配置文件:.ssh$ touch config

4)将以下内容添加到~/.ssh/config中。

Host github.com-<YOUR_GITHUB_USERNAME> 
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_work_gmail # path to your private key
AddKeysToAgent yes


Host csexperimental.abc.com
IdentityFile ~/.ssh/id_work_gmail # path to your private key
AddKeysToAgent yes

<More hosts and github configs can be added in similar manner mentioned above>

5) 使用命令$ ssh-add ~/.ssh/id_work_gmail将您的密钥添加到SSH代理中,然后您应该能够使用SSH连接到您的Github帐户或远程主机。例如,在上面代码示例的情况下:

$ ssh github.com-<YOUR_GITHUB_USERNAME>
或者
$ ssh <USER>@csexperimental.abc.com

将此密钥添加到SSH代理应该只需要执行一次。

6) 现在退出Windows Linux子系统上的Bash会话,即再次退出所有Bash控制台,然后再次启动新控制台并尝试使用SSH连接到您的Github主机或其他在SSH配置文件中配置的主机,这样就不需要任何额外步骤。

注意:

谢谢。



1
有趣的替代方案,使用WSL。+1 - VonC
@JigneshGohel 谢谢,这个脚本非常完美和干净!不过我想知道,为什么你要用 >> "${SSH_ENV}"?难道不应该只是 > "${SSH_ENV}" 吗?当然你的方法也可以运行,但是它会让 ~/.ssh/environment 文件变得越来越长,而且没有必要(至少我现在是这么认为的!)... 非常感谢!我觉得这个脚本应该被包含在 WSL Ubuntu 的默认 .bashrc 中,因为它非常有用! - MikeBeaton
1
只是一个快速提醒,如果你想加载除默认之外的SSH密钥,请将“/usr/bin/ssh-add”行更改为“/usr/bin/ssh-add <你的密钥名称>”。 - Jason
我没有文件~/.ssh/environment。它应该包含什么内容? - Ellen Spertus
我没有~/.ssh/environment这个文件。它应该包含什么内容? - undefined
如果shopt 'no clobber'已开启,您可以使用"${SSH_ENV}" >| /dev/null来预防错误并强制重定向。 - Edward J Beckett

14
如果目标是随时能够推送到GitHub repo,则在Windows下的C:\Users\tiago\.ssh(至少在我的情况下)创建名为config的文件,并添加以下内容。
Host github.com
    HostName github.com
    User your_user_name
    IdentityFile ~/.ssh/your_file_name

然后只需打开Git Bash,您就可以推送而无需手动启动ssh-agent并添加密钥。


1
每次输入密码短语时都会有提示,这有点烦人,但对我来说很好,因为我的默认 shell 无法运行代理。 - jaimedash

7
我发现最顺畅的方法是使用Pageant作为SSH代理和plink。
您需要配置一个putty会话,用于远程主机名。
您还需要下载可以从与putty相同的网站下载的plink.exe。
并且您需要运行Pageant并加载密钥。我在启动文件夹中有一个Pageant的快捷方式,可以在登录时加载我的SSH密钥。
安装git-scm后,您可以指定其使用tortoise/plink而不是OpenSSH。
净效果是,您可以随时打开git-bash并推送/拉取而不需要输入密码。
当Pageant加载您的密钥时,putty和WinSCP会话也适用相同的规则。它使生活变得更加轻松(和安全)。

6

我无法根据最佳答案使其工作,可能是因为我是个电脑新手,缺少一些显而易见的东西。但是只要提供给像我一样有挑战性的人一个提示,FINALLY成功的方法是通过下面其中一个链接中的一个(参考答案)。这仅涉及将以下内容简单粘贴到我的.bash_profile中:

env=~/.ssh/agent.env

agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }

agent_start () {
    (umask 077; ssh-agent >| "$env")
    . "$env" >| /dev/null ; }

agent_load_env

# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)

if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
    agent_start
    ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
    ssh-add
fi

unset env

我可能配置了一些奇怪的东西,但是当我将它添加到我的.profile.bashrc时并没有成功。我遇到的另一个真正的挑战是我不是这台电脑上的管理员,不能更改环境变量,必须经过IT批准才能更改,因此这是为那些无法访问的人提供的解决方案。

当您打开git bash时,如果提示输入ssh密码,则说明它正在工作。终于有东西起作用了,哈利路亚。


4

将以下代码添加到您的 ~/.bashrc 中(或从中 source 的文件),这样可以防止它在每个 shell 中不必要地运行多次:

if [ -z "$SSH_AGENT_PID" ]; then
        eval `ssh-agent -s`
fi

然后在 ~/.ssh/config 文件中添加 "AddKeysToAgent yes":

Host *
    AddKeysToAgent yes

正常 ssh 连接到您的服务器(或 git pull),您只会在每个会话中被要求输入一次密码/密码短语。


2
由于我不喜欢在 Windows 上使用 PuTTY 作为解决方法,所以我创建了一个非常简单的实用程序 ssh-agent-wrapper。它会扫描您的 .ssh 文件夹并将所有密钥添加到代理中。您只需要将它放入 Windows 启动文件夹中即可使用。 假设
  • ssh-agent 在路径中
  • shh-add 在路径中(通过选择安装 Git 时的“RED”选项)
  • 私钥位于 %USERPROFILE%/.ssh 文件夹中
  • 私钥名称以 id 开头(例如 id_rsa)

不错!+1。我总是使用 openssh(而不是 putty),所以这对于带有密码短语的私钥是一个有趣的解决方案。 - VonC
既然你已经在Github上了,为什么不把源代码变成一个Git仓库呢? - Thorbjørn Ravn Andersen
只需要从路径中删除 /releases 即可。;-) - Erez A. Korn

1
在您的~目录下创建一个新的.bashrc文件。
在那里,您可以放置您想要在每次启动bash时执行的命令。

它必须能够工作。尝试将一些简单的内容放入.bashrc文件中(例如echo test),并检查在执行Git Bash时是否已加载。 - David Ferenczy Rogožan
请注意,PowerShell 中的 ~ 可能与 Git Bash/Cygwin 中的 ~ 不同,具体取决于安装的版本和用户指定的选项。 - dragon788
在Windows系统中,将.bashrc文件放置于用户文件夹中,例如C:\Users\john - Martin van Driel

1
我写了一个脚本并创建了一个git仓库,解决了这个问题: https://github.com/Cazaimi/boot-github-shell-win
自述文件包含设置脚本的说明,这样每次打开新窗口/选项卡时,私钥会自动添加到ssh-agent中,如果您正在使用远程git仓库,则不必担心这个问题。

1

@VonC在这里提供了一个很好的答案

我只想把完整的脚本和所有指令放在一个地方。

参考这些指令:https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases?platform=windows

如何让ssh-agent在Windows中每次启动时加载您的私有ssh密钥并仅要求输入密码一次

在Windows 10上测试,使用Git For Windows 2.41.0-64位版本。

在Git Bash中,创建你的~/.bashrc文件
在你选择的编辑器中,现在编辑该文件,并将以下内容粘贴到文件底部。此脚本是从这里复制来的。我只添加了顶部和底部的注释以及echo命令:
# -------------------------------- START ----------------------------------- # 自动启动ssh-agent并在Git for Windows上加载所有私钥 # 复制自:https://dev59.com/fmMl5IYBdhLWcg3wbGl1#76568760 env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () { (umask 077; ssh-agent >| "$env") . "$env" >| /dev/null ; }
agent_load_env
# agent_run_state: 0=带有密钥的代理正在运行;1=没有密钥的代理;2=代理未运行 agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then echo "启动ssh-agent并添加您的私钥。" agent_start ssh-add elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then echo "将您的私钥添加到ssh-agent。" ssh-add fi unset env # -------------------------------- END -------------------------------------
使Git Bash重新加载~/.bashrc文件的更改。
要么:使用. ~/.bashrc手动重新加载~/.bashrc文件,或者:
关闭并重新打开所有Git Bash终端窗口。
这将自动启动ssh-agent,因为你刚刚添加到~/.bashrc文件中的脚本。
如果需要,请将所有私钥添加到您的ssh-agent中:
当脚本调用ssh-add时,具有标准路径的私钥(例如~/.ssh/id_ed25519~/.ssh/id_rsa)会自动添加。但是,如果您有具有自定义名称或路径的私钥,请现在添加它们:
ssh-add path/to/my/keys/id_ed25519 ssh-add path/to/my/keys/id_rsa_custom_name # 等等。
就是这样!正如教程所说

ssh-agent进程将持续运行,直到您退出登录、关闭计算机或终止该进程。

现在,你只需要在Windows重新启动时输入每个ssh密钥的私人密码一次,而不是在每次git pushgit pull操作,或每次Git Bash终端中,这两种方式都很烦人。

另外还有

  1. 我还想指出一个备选方案,由Atlassian和Bitbucket提供了一个经过充分记录的解决方案,链接在这里:https://support.atlassian.com/bitbucket-cloud/docs/set-up-personal-ssh-keys-on-windows/。在这个解决方案中,他们要求明确安装Windows版本的OpenSSH,并在Windows PowerShell中运行一些命令,让Git Bash使用Windows版本的OpenSSH。这与我上面提到的解决方案有很大不同,但也能起作用。然而,我更喜欢我上面提到的解决方案,因为我认为它更简单、更快捷、更通用,而且不需要对Windows可执行文件或PowerShell命令进行调整。相反,它只使用了Git for Windows附带和提供的工具。

1
好的。那应该确实有效。 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接