自从升级到macOS 10.12(Sierra)以来,在使用Capistrano部署代码时遇到了问题,"Permission denied(publickey)".

Jak*_*uld 16 macos ssh capistrano

所以我刚刚将我的Mac mini(2012年末)升级到macOS 10.12(Sierra),一切似乎都很好,但我遇到了一个奇怪的问题,就是用Capistrano部署代码.我收到以下错误:

Permission denied (publickey).
Run Code Online (Sandbox Code Playgroud)

以前在Mac OS X 10.11(El Capitan)或之前的任何版本中从未出现此问题.为什么现在突然发生这种情况?下面失败的Capistrano部署的完整输出:

jakes_mac:SomeCode jake$ cap staging deploy
INFO [hkdgad21] Running /usr/bin/env mkdir -p /tmp/somecode/ as jake@example.com
DEBUG [hkdgad21] Command: /usr/bin/env mkdir -p /tmp/somecode/
jake@example.com's password:
INFO [hkdgad21] Finished in 5.166 seconds with exit status 0 (successful).
DEBUG Uploading /tmp/somecode/git-ssh.sh 0.0%
INFO Uploading /tmp/somecode/git-ssh.sh 100.0%
INFO [xyz20312] Running /usr/bin/env chmod +x /tmp/somecode/git-ssh.sh as jake@example.com
DEBUG [xyz20312] Command: /usr/bin/env chmod +x /tmp/somecode/git-ssh.sh
INFO [xyz20312] Finished in 0.240 seconds with exit status 0 (successful).
INFO [abcdef01] Running /usr/bin/env git ls-remote --heads git@github.com:SomeUser/SomeCode.git as jake@example.com
DEBUG [abcdef01] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/somecode/git-ssh.sh /usr/bin/env git ls-remote --heads git@github.com:SomeUser/SomeCode.git )
DEBUG [abcdef01]    Permission denied (publickey).
DEBUG [abcdef01]    fatal: Could not read from remote repository.
DEBUG [abcdef01]
DEBUG [abcdef01]    Please make sure you have the correct access rights
DEBUG [abcdef01]    and the repository exists.
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as jake@example.com: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

SSHKit::Command::Failed: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Tasks: TOP => git:check
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as jake@example.com: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.
Run Code Online (Sandbox Code Playgroud)

请确保您具有正确的访问权限并且存储库存在.

Jak*_*uld 30

看起来这是一个问题,SSH密钥没有像以前在Mac OS X 10.11(El Capitan)中那样自动添加.这是来自macOS Sierra的预期行为还是与OpenSSH相关的东西?

方法1:将所有已知密钥添加到SSH代理.

所以我找到的一个解决方案是ssh-add使用-A选项运行- 它使用存储在钥匙串中的任何密码将所有已知身份添加到SSH代理 - 如下所示:

ssh-add -A
Run Code Online (Sandbox Code Playgroud)

现在这可行,但它不会在重新启动后持续存在.因此,如果您想再也不用担心这一点,只需打开您的用户~/.bash_profile文件,如下所示:

nano ~/.bash_profile
Run Code Online (Sandbox Code Playgroud)

并将此行添加到底部:

ssh-add -A 2>/dev/null;
Run Code Online (Sandbox Code Playgroud)

现在当你打开一个新的终端窗口时,一切都应该是好的!

方法2:仅将密钥链中的SSH密钥添加到代理.

因此,虽然该ssh-add -A选项应该适用于大多数基本情况,但最近我遇到了一个问题,我在一台机器上设置了6-7个Vagrant盒子(使用SSH密钥/身份进行访问),并且更常见id_rsa.pub.

长话短说,由于服务器访问基于密码而SSH密钥/身份是SSH密钥/身份,因此基于SSH密钥/身份的尝试失败太多,我最终被锁定在远程服务器之外.所以SSH代理尝试了我所有的SSH密钥,失败了,我甚至无法获得密码提示.

问题在于,ssh-add -A即使没有必要,也只是随意添加您拥有的每个SSH密钥/身份; 例如在Vagrant盒子的情况下.

经过大量测试后,我的解决方案如下.

首先,如果你有更多的SSH密钥/身份添加到你的代理 - 如你所示 - ssh-add -l然后从代理清除它们,如下所示:

ssh-add -D
Run Code Online (Sandbox Code Playgroud)

完成后,启动SSH代理作为后台进程,如下所示:

eval "$(ssh-agent -s)"
Run Code Online (Sandbox Code Playgroud)

现在,它变得奇怪,我不太清楚为什么.在某些情况下,您可以专门~/.ssh/id_rsa.pub为代理添加密钥/标识,如下所示:

ssh-add ~/.ssh/id_rsa.pub
Run Code Online (Sandbox Code Playgroud)

输入你的密码,点击Return,你应该好好去.

但在其他情况下,只需运行此即可获得添加的密钥/标识:

ssh-add -K
Run Code Online (Sandbox Code Playgroud)

如果这一切都有效,请键入ssh-add -l,您应该看到列出了一个单独的SSH密钥/标识.

都好?现在打开你的.bash_profile:

nano ~/.bash_profile
Run Code Online (Sandbox Code Playgroud)

并将此行添加到底部; -A如果您有相应的评论或删除版本:

ssh-add -K
Run Code Online (Sandbox Code Playgroud)

这将允许在每次启动/重新启动时将SSH密钥/身份重新加载到SSH代理.


更新1:基于davidalger的回答,我发现了一个更好的全局解决方案,可以适用于系统上的所有用户.只需通过以下方式打开位于此处的全局SSH配置sudo:

sudo nano /etc/ssh/ssh_config
Run Code Online (Sandbox Code Playgroud)

并将此行添加到文件的底部:

AddKeysToAgent yes
Run Code Online (Sandbox Code Playgroud)

这样做 - 删除.bash_profile修复后,一切都很好.


更新2:Apple现在UseKeychain为开放的SSH配置选项添加了一个选项,并考虑ssh-add -A了解决方案.

从macOS Sierra 10.12.2开始,Apple(我假设)UseKeychain为SSH配置添加了一个配置选项.检查手册页(via man ssh_config)显示以下信息:

UseKeychain
        On macOS, specifies whether the system should search for
        passphrases in the user's keychain when attempting to use a par-
        ticular key. When the passphrase is provided by the user, this
        option also specifies whether the passphrase should be stored
        into the keychain once it has been verified to be correct.  The
        argument must be ``yes'' or ``no''.  The default is ``no''.
Run Code Online (Sandbox Code Playgroud)

这可以归结为Apple将解决方案视为添加ssh-add -A到您的.bash_profile Open Radar票证中所解释的,或者添加UseKeychain为每个用户中的一个选项~/.ssh/config.


dav*_*ger 8

这是来自macOS Sierra的预期行为还是与OpenSSH相关的东西?

这是由于OpenSSH 7.2中的一项新功能导致SSH客户端的行为发生了变化.从发行说明:

 ssh(1): Add an AddKeysToAgent client option which can be set to
   'yes', 'no', 'ask', or 'confirm', and defaults to 'no'.  When
   enabled, a private key that is used during authentication will be
   added to ssh-agent if it is running (with confirmation enabled if
   set to 'confirm').
Run Code Online (Sandbox Code Playgroud)

还引入了其他有趣的(与安全相关的)功能,尽管该版本主要被视为错误修复版本.此特定功能导致OS X上的默认行为更改,因为它的默认值为"no",OS X(我不知道其他客户端)以前在使用时向代理添加了密钥.

因此,如果您将以下内容添加到您的~/.ssh/config文件(或ssh_config应该位于其中的全局/etc/ssh/ssh_config),则会在使用时将密钥再次添加到您的代理中.

AddKeysToAgent yes
Run Code Online (Sandbox Code Playgroud)

这种单线程非常简单:

echo "AddKeysToAgent yes" >> ~/.ssh/config
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我能够实现预期的行为:

$ ssh-add -l
The agent has no identities.
$ ssh -T git@bitbucket.org 
logged in as davidalger.

You can use git or hg to connect to Bitbucket. Shell access is disabled.
$ ssh-add -l
2048 SHA256:<snip> (RSA)
Run Code Online (Sandbox Code Playgroud)