自升级到 macOS 10.12 (Sierra) 后使用 Capistrano 部署代码时出现问题,“权限被拒绝(公钥)”。

Problems deploying code with Capistrano since upgrading to macOS 10.12 (Sierra), “Permission denied (publickey).”

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

Permission denied (publickey).

以前在 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.

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

似乎是 SSH 密钥没有自动添加的问题,因为它曾经在 Mac OS X 10.11 (El Capitan) 中。这是来自 macOS Sierra 还是连接到 OpenSSH 的预期行为?

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

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

ssh-add -A

现在这有效,但它不会在重新启动后持续存在。所以如果你不想再担心这个,只需像这样打开用户的 ~/.bash_profile 文件:

nano ~/.bash_profile

并将这一行添加到底部:

ssh-add -A 2>/dev/null;

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

方法 2:仅将钥匙串中的 SSH 密钥添加到代理。

因此,虽然 ssh-add -A 选项应该适用于大多数基本情况,但我 运行 最近遇到了一个问题,我有 6-7 个 Vag运行t 盒子(使用 SSH keys/identities for access) setup on a machine on common id_rsa.pub in place.

长话短说,由于基于 SSH keys/identities 的失败尝试太多,我最终被远程服务器锁定,因为服务器访问是基于密码的,而 SSH keys/identities 是SSH keys/identities。所以 SSH 代理尝试了 所有 我的 SSH 密钥,但失败了,我什至无法进入密码提示。

问题是 ssh-add -A 会任意添加每个 SSH key/identity 到代理,即使没有必要这样做;例如 Vag运行t boxes.

经过多次测试,我的解决方案如下。

首先,如果您添加到代理的 SSH keys/identities 多于您的需要——如 ssh-add -l 所示,然后像这样从代理中清除它们:

ssh-add -D

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

eval "$(ssh-agent -s)"

现在,它变得很奇怪,我不太清楚为什么。在某些情况下,您可以像这样专门将 ~/.ssh/id_rsa.pub key/identity 添加到代理中:

ssh-add ~/.ssh/id_rsa.pub

输入您的密码,点击Return,您就可以开始了。

但在其他情况下,只需 运行 就足以添加 key/identity:

ssh-add -K

如果一切正常,请输入 ssh-add -l,您应该会看到一个单独的 SSH key/identity 列出。

还好吗?现在打开你的 .bash_profile:

nano ~/.bash_profile

并将这一行添加到底部;评论或删除 -A 版本(如果有):

ssh-add -K

这将允许 SSH key/identity 在每个 startup/reboot 上重新加载到 SSH 代理。


更新 1: 基于 我发现了一个更好的全局解决方案,适用于系统上的所有用户。只需通过 sudo:

打开位于此处的全局 SSH 配置
sudo nano /etc/ssh/ssh_config

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

AddKeysToAgent yes

是吗——删除 .bash_profile 修复后一切正常。


更新 2:Apple 现在已将 UseKeychain 选项添加到打开的 SSH 配置选项,并考虑 ssh-add -A 一个解决方案。

从 macOS Sierra 10.12.2 开始,Apple(我假设)已经为 SSH 配置添加了一个 UseKeychain 配置选项。检查手册页(通过 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''.

这归结为 Apple 将解决方案视为将 ssh-add -A 添加到您的 .bash_profile as explained in this Open Radar ticket 或添加 UseKeychain 作为每个用户 ~/.ssh/config.

Is this expected behavior from macOS Sierra or something connected to OpenSSH?

这是由于 OpenSSH 7.2 中的一项新功能导致 SSH 客户端的行为发生变化。来自 release notes:

 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').

虽然该版本主要被认为是错误修复版本,但还引入了其他有趣的(与安全相关的)功能。此特定功能导致 OS X 上的默认行为更改,因为它的默认值为 'no' 和 OS X(我不知道其他客户端)先前将密钥添加到代理他们被使用了。

因此,如果您将以下内容添加到您的 ~/.ssh/config 文件(或应该位于 /etc/ssh/ssh_config 中的全局 ssh_config),密钥将再次添加到您的代理中,因为它们被使用了。

AddKeysToAgent yes

这一行使它变得非常简单:

echo "AddKeysToAgent yes" >> ~/.ssh/config

这样做之后,我能够实现预期的行为:

$ 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)

这帮助我解决了 MacOS Serra 上的问题:

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