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

Posted

技术标签:

【中文标题】升级到 macOS 10.12 (Sierra) 后,使用 Capistrano 部署代码时出现问题,“权限被拒绝(公钥)”。【英文标题】:Problems deploying code with Capistrano since upgrading to macOS 10.12 (Sierra), “Permission denied (publickey).” 【发布时间】:2017-02-04 12:33:16 【问题描述】:

所以我刚刚将我的 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.

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

【问题讨论】:

在尝试并重试提出的解决方案后,我发现了我遇到的特殊问题。 Apple 放弃了 DSA 转而使用 RSA,所以现在只有这个可以工作。我找到的链接有一个分步解决方案。祝你好运! medium.freecodecamp.com/… 【参考方案1】:

这似乎是 SSH 密钥没有像以前在 Mac OS X 10.11 (El Capitan) 中那样自动添加的问题。这是来自 macOS Sierra 的预期行为还是连接到 OpenSSH 的东西?

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

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

ssh-add -A

现在这有效,但它不会在重新启动后持续存在。因此,如果您不想再担心这个问题,只需打开用户的 ~/.bash_profile 文件,如下所示:

nano ~/.bash_profile

并将这一行添加到底部:

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

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

方法 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

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

eval "$(ssh-agent -s)"

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

ssh-add ~/.ssh/id_rsa.pub

输入您的密码,点击 Return,您应该一切顺利。

但在其他情况下,只需运行它就足以添加密钥/身份:

ssh-add -K

如果一切正常,请输入 ssh-add -l,您应该会看到列出的唯一 SSH 密钥/身份。

一切都好吗?现在打开你的.bash_profile

nano ~/.bash_profile

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

ssh-add -K

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


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

sudo nano /etc/ssh/ssh_config

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

AddKeysToAgent yes

这样做了吗?在删除 .bash_profile 修复后,一切都很好。


更新 2:Apple 现在已在打开的 SSH 配置选项中添加了 UseKeychain 选项,并认为 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 中的选项之一。

【讨论】:

这行得通,但它真的是唯一的方法吗?如果感觉很脏。 @KevinZych 我同意。也许未来的 macOS Sierra 补丁会有一些“更好”的方式来处理这个问题?但在伟大的计划中,编辑.bash_profile 以添加一行代码是对此“肮脏”的最干净的方式。 我同意@JakeGould,我刚刚将ssh-add 命令添加到我的.bash_profile,它现在可以工作。希望当有更好的解决方案时,此线程会得到更新。 @JakeGould / @KevinZych 请参阅下面发布的我的答案。 OpenSSH 中有一个名为 AddKeysToAgent 的新设置 出于某种原因,AddKeysToAgent 是(并重新启动)并没有为我解决问题......而且 ssh-add -A 也没有,我唯一可以开始工作的是 ssh-add - K【参考方案2】:

这是来自 macOS Sierra 还是连接到 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 上的默认行为发生变化,因为它的默认值为“否”并且 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)

【讨论】:

很好的信息。我记得新的 SSH 规范,但不记得具体细节。但是 FWIW,将 AddKeysToAgent yes 添加到 ~/.ssh/config 对我来说根本不起作用。起作用的是将其添加到位于/etc/ssh/ssh_config 的全局配置文件中。 看来对我来说,我必须运行ssh -T git@github.com 否则我会得到同样的错误。有谁知道为什么会这样?添加“AddKeysToAgent”没有帮助:( @ChrisJeon 尝试使用ssh -vT git@github.com 获取详细输出并查看失败的地方。对我来说,相关线路是Skipping ssh-dss key ~/.ssh/id_dsa - not in PubkeyAcceptedKeyTypes。最终,我从 DSA 密钥切换到 2048 位 RSA 密钥 (ssh-keygen -t rsa -b 2048),尽管您可以在配置文件中添加类似 PubkeyAcceptedKeyTypes=+ssh-dss 的内容(未经测试)。【参考方案3】:

这有助于我解决 MacOS Serra 上的问题:

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

【讨论】:

这个方法在2+年前发布的自答答案中有详细说明。

以上是关于升级到 macOS 10.12 (Sierra) 后,使用 Capistrano 部署代码时出现问题,“权限被拒绝(公钥)”。的主要内容,如果未能解决你的问题,请参考以下文章

macOS Sierra 10.12显示允许任何来源

从 OS Sierra 10.12 上的终端分段错误 11 错误重新签署 IPA

macOS 10.12 Sierra 上的捆绑错误

macOS(Sierra 10.12)上Android源码(AOSP)的下载编译与导入到Android Studio

MacOS Sierra很慢?为什么?以及如何解决?

黑苹果macOS Sierra 10.12 安装教程(venue11 pro测试)