我正在使用一台 Ubuntu 18.04.3 LTS x86_64 机器(已完全修补)。该机器有一个 GNOME3 桌面。有时我坐在工作站,有时我通过 SSH 进入工作站。
当我坐在工作站时,Git 提交签名可以正常工作。我使用git commit -S ... -m ...
,一切按预期进行。我收到一个 GnuPG 密码 UI 提示,工作流程照常进行。
当我通过 SSH 在同一工作站上远程工作时,我必须放弃提交签名,因为:
$ git commit -S log.h -m "Remove unneeded header"
error: gpg failed to sign the data
fatal: failed to write commit object
我正在使用 SSH、Git 和 GnuPG 的“标准”配置。我不知道此设置有任何特殊配置。但是,存储库位于我的本地 LAN 上(而不是 GitHub、GitLab 等):
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = ssh://git@callmaster:/var/callboot-src
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
以下位置没有专门的 GnuPG conf 文件$HOME/.gnupg
:
$ ls -A ~/.gnupg/
3F537D88ADBC1677-private-key.asc pubring.kbx
private-keys-v1.d trustdb.gpg
搜索未找到问题。我收到了很多有关 Git 签名失败的信息,但没有找到针对此特定情况的结果。
我缺少哪个配置选项以便签名可以在本地和通过 SSH 进行?
pinentry
机器上的情况如下:
$ ls -Al /usr/bin/pinentry-*
-rwxr-xr-x 1 root root 63992 Feb 5 2018 /usr/bin/pinentry-curses
-rwxr-xr-x 1 root root 72184 Feb 5 2018 /usr/bin/pinentry-gnome3
lrwxrwxrwx 1 root root 30 Sep 2 19:14 /usr/bin/pinentry-x11 -> /etc/alternatives/pinentry-x11
进而:
$ ls -Al /etc/alternatives/pinentry-*
lrwxrwxrwx 1 root root 24 Sep 2 19:14 /etc/alternatives/pinentry-x11 -> /usr/bin/pinentry-gnome3
lrwxrwxrwx 1 root root 40 Sep 2 19:14 /etc/alternatives/pinentry-x11.1.gz -> /usr/share/man/man1/pinentry-gnome3.1.gz
答案1
确保您的 shell 启动文件(.bashrc 或 .zshrc)设置了 $GPG_TTY 环境变量:
export GPG_TTY=$(tty)
GnuPG 显示密码提示的方式有几层间接层。它不会直接显示它们,甚至不会直接启动“pinentry”UI——而是将一些相关的环境变量传递给gpg-代理守护进程(在所有会话中共享),然后 gpg-agent 尝试在正确的 TTY 或正确的 X11 显示器上启动“pinentry”。
由于某些尚未解释的原因,当GPG发送会话信息至gpg-代理,它不需要自己查找真正的 TTY(甚至不需要将其作为文件描述符传递);它总是期望 $GPG_TTY 环境变量存在并包含信息。
另外,你可以通过启用“loopback pinentry”选项来避免这种情况,其中 gpg-agent 的密码请求会返回到GPG而不是启动 pinentry UI。
为此,请将选项添加pinentry-mode loopback
到 ~/.gnupg/gpg.conf。
(在较旧的(过时的) GnuPG 版本中,您可能还需要 ~/.gnupg/gpg-agent.conf 中的选项allow-loopback-pinentry
,添加后您需要使用 进行更新gpg-connect-agent reloadagent /bye
。最新的 GnuPG 已经默认允许环回模式。)