gpg-agent 神秘地停止工作 - 远程系统上的代理不再连接到 ssh 套接字

lop*_*ass 5 linux osx ssh gpg-agent yubikey

我在本地系统上使用 yubikey nano 在远程系统上进行加密/解密/签名,以及 SSH 代理转发。我记得这是一个设置的负担,但它已经完美地工作了几个月。突然就断了。我的搜索都返回了我在设置时阅读的相同链接,但我被卡住了。

SSH 代理转发莫名其妙地工作。远程系统显示:

REMOTE:$ ssh-add -L
ssh-rsa blahblah cardno:123
Run Code Online (Sandbox Code Playgroud)

我可以使用 SSH 从远程系统登录到其他服务器,它使用 nano 进行身份验证(我知道这一点,因为它需要触摸才能启用代理签名)。我可以在本地系统的 gpg-agent 日志中看到有关 SSH 签名的日志。

但是,我根本无法让 GPG 签名/加密工作。如果我在远程系统上运行以下命令:

REMOTE:$ echo "$(uname -a)" |  gpg2 --armor --clearsign --default-key 0x1234
gpg: all values passed to '--default-key' ignored
gpg: no default secret key: No secret key
gpg: [stdin]: clearsign failed: No secret key
Run Code Online (Sandbox Code Playgroud)

在本地 gpg-agent 日志中,我没有看到有关尝试的日志。如果我运行这个命令,我可以在本地 gpg-agent 日志中看到日志条目:

REMOTE:$ $ netcat  -U /home/user/.gnupg/S.gpg-agent
OK Pleased to meet you
RESET
OK
GETINFO PID
ERR 67109115 Forbidden <GPG Agent>
POOP
ERR 67109139 Unknown IPC command <GPG Agent>
Run Code Online (Sandbox Code Playgroud)

这会导致本地代理中的这些日志:

2018-01-05 16:38:32 gpg-agent[865] DBG: chan_10 -> OK Pleased to meet you
2018-01-05 16:38:35 gpg-agent[865] DBG: chan_10 <- RESET
2018-01-05 16:38:35 gpg-agent[865] DBG: chan_10 -> OK
2018-01-05 16:38:45 gpg-agent[865] DBG: chan_10 <- GETINFO PID
2018-01-05 16:38:45 gpg-agent[865] DBG: chan_10 -> ERR 67109115 Forbidden <GPG Agent>
2018-01-05 16:39:01 gpg-agent[865] DBG: chan_10 <- POOP
2018-01-05 16:39:01 gpg-agent[865] DBG: chan_10 -> ERR 67109139 Unknown IPC command <GPG Agent>
Run Code Online (Sandbox Code Playgroud)

如果我在远程系统上的 gpg-connect-agent 上运行 strace -f -F,它似乎连接到 /var/run 中的套接字,但不是从本地系统在 ~/.gnupg/ 中转发的套接字。我尝试删除两个套接字,杀死所有 gpg-agent 进程并将 SSH 远程转发更改为转到 /var/run 位置或 ~/.gnupg 位置,但无济于事。有可能我搞砸了这些步骤,我会再试一次,但我想知道是否有人知道答案,我希望下次遇到这种情况时可以轻松找到帖子。

本地系统:

Mac OS X 10.11.6
gpg installed with brew
gpg (GnuPG) 2.2.1
libgcrypt 1.8.1
Run Code Online (Sandbox Code Playgroud)

远程系统:

ubuntu 17.10
gpg (GnuPG) 2.1.15
libgcrypt 1.7.8
Run Code Online (Sandbox Code Playgroud)

编辑:好的,不知道发生了什么变化,但我把它放在一边,然后回来尝试再次切换插座,现在可以工作了:

REMOTE:$ $ echo "$(uname -a)" |  strace -f -F gpg2 --armor --clearsign --default-key 0x1234
...
a bunch of garbage
...
stat("/run/user/1000/gnupg/S.gpg-agent", {st_mode=S_IFSOCK|0600, st_size=0, ...}) = 0
socket(AF_UNIX, SOCK_STREAM, 0)         = 5
Run Code Online (Sandbox Code Playgroud)

将我的 SSH 远程转发到这个新位置有效。我发誓我之前使用 gpgconf --list-dir agent-ssh-socket 提供的套接字路径尝试过这个,但没有任何运气。可能忘记杀死现有的代理。碰巧的是,我偶然看到一篇博客文章报告说这发生了变化:https : //blog.kylemanna.com/linux/gpg-213-ssh-agent-socket-moved/

lop*_*ass 1

更新:取消链接您的套接字,请参阅底部的编辑。

这里显然存在一个间歇性的错误,或者这是所有这些系统如何相互作用的副作用。我不想讨论太多细节/推测,但我会考虑以下几点:

  • 第二个 SSH 会话连接第一个会话的管道(这应该发生吗?)
  • REMOTE 上 SSHD 中的 StreamLocalBindUnlink 无法正确获取管道(可能是因为远程端的代理仍然打开它们?)

一个很好的解决方法是在 .ssh/config 中使用单独的特殊主机进行 gpg 代理转发,并确保仅登录该主机名一次!

发生的几次情况非常令人沮丧,因为管道/正在运行的代理和新 sshd 会话没有创建新套接字的实例的组合导致了各种混乱(再次可能是由于正在运行的代理保持打开旧的套接字文件) )。通常,我没有时间尝试解决这样的问题。

终于遇到了这个问题,我能够进行故障排除和修复,我可以可靠地重现该问题并展示如何修复它:

工作制度

REMOTE:$ echo "$(uname -a)" | gpg --armor --clearsign --default-key 0x1234
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Linux pooter 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE/0lJ/t51agRvvTILdQ2kyDf6wDYFAl9JgSYACgkQdQ2kyDf6

-----END PGP SIGNATURE-----
Run Code Online (Sandbox Code Playgroud)

从本地系统运行另一个 SSH 或 Rsync

LOCAL: $ rsync -avze ssh test.txt pooter:
bind [127.0.0.1]:5901: Address already in use
Run Code Online (Sandbox Code Playgroud)

SCP 不会造成问题,但 RSYNC 显然会进行 ssh 登录,因为我看到文件复制时端口转发失败

远程加密/解密现在失败

REMOTE:$ echo "$(uname -a)" | gpg --armor --clearsign --default-key 0x1234
gpg: all values passed to '--default-key' ignored
gpg: no default secret key: No secret key
gpg: [stdin]: clear-sign failed: No secret key
Run Code Online (Sandbox Code Playgroud)

修复方法

  1. 注销所有具有套接字转发的 SSH 会话
  2. 杀死远程系统上的所有 gpg 代理
  3. 验证 /var/run/xxxx/gnupg 中的管道是否就位
  4. 如果管道消失,请使用套接字转发登录并验证它们是否已重新创建

对于步骤 3 和 4,我看到它是双向的,有时管道保留,有时它们适当地消失。可能还需要删除管道文件并重新登录并确保重新创建它们。

现在一切都应该可以再次进行加密/解密

更新 - 更简单的修复

今天无缘无故地发生了这种事,我很恼火。我必须来找到这篇文章,但我太懒了,无法做我原来的帖子告诉我要做的所有事情来修复。我是从我上面的猜想的角度来考虑这个情况的。长话短说,这有效:

  1. Killall gpg-agent && 退出
  2. CTRL^C # 断开转发端口
  3. 等待约 1 分钟
  4. 重新登录

一切又恢复正常了

编辑:我又发生了这种情况,我又添加了一步。找到您的 unix 域套接字文件并从不同的 shell/登录运行以下命令: unlink /path/to/socket