所以我刚刚将我的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 [email protected]
DEBUG [hkdgad21] Command: /usr/bin/env mkdir -p /tmp/somecode/
[email protected]'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 [email protected]
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 [email protected]:SomeUser/SomeCode.git as [email protected]
DEBUG [abcdef01] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/somecode/git-ssh.sh /usr/bin/env git ls-remote --heads [email protected]: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 [email protected]: 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 [email protected]: 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相关的东西?
所以我找到的一个解决方案是使用ssh-add
选项运行-A
,它使用存储在钥匙串中的任何密码将所有已知身份添加到SSH代理中,如下所示:
ssh-add -A
现在这可行,但它不会在重新启动后持续存在。因此,如果您想再也不用担心这个问题,只需打开用户的~/.bash_profile
文件,如下所示:
nano ~/.bash_profile
并将此行添加到底部:
ssh-add -A 2>/dev/null;
现在当你打开一个新的终端窗口时,一切都应该是好的!
因此,虽然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
修复后,一切都很好。
UseKeychain
option to the open SSH config options and considers ssh-add -A
a solution as well.从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
的选项之一。
这是来自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上的默认行为更改,因为它的默认值为“no”,OS X(我不知道其他客户端)以前在使用时向代理添加了密钥。
因此,如果将以下内容添加到~/.ssh/config
文件(或应位于ssh_config
中的全局/etc/ssh/ssh_config
)中,则会在使用时将密钥再次添加到代理中。
AddKeysToAgent yes
这种单线程非常简单:
echo "AddKeysToAgent yes" >> ~/.ssh/config
完成此操作后,我能够实现预期的行为:
$ ssh-add -l
The agent has no identities.
$ ssh -T [email protected]
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 Sierra上的问题:
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa_file