
Я работаю на машине Ubuntu 18.04.3 LTS x86_64 (полностью пропатченной). На машине есть рабочий стол GNOME3. Иногда я сижу за рабочей станцией, а иногда подключаюсь к рабочей станции по SSH.
Когда я сижу за рабочей станцией, подпись коммитов Git работает. Я использую git commit -S ... -m ...
, и все работает так, как и ожидалось. Я получаю запрос пользовательского интерфейса на ввод моего пароля GnuPG, и работа идет как обычно.
Когда я работаю удаленно на той же рабочей станции через 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. Я не знаю о каких-либо специальных конфигурациях для этой установки. Однако репозиторий находится в моей локальной сети (а не в 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 нет в $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
Убедитесь, что файлы запуска оболочки (.bashrc или .zshrc) устанавливают переменную среды $GPG_TTY:
export GPG_TTY=$(tty)
В том, как GnuPG показывает запросы на ввод пароля, есть несколько уровней косвенности. Он не показывает их напрямую и даже не запускает пользовательский интерфейс «pinentry» напрямую — вместо этого он передает несколько соответствующих переменных окружения вgpg-агентдемон (который является общим для всех ваших сеансов), а затем gpg-agent пытается запустить «pinentry» на правильном TTY или правильном дисплее X11.
По какой-то пока необъяснимой причине, когдагпготправляет информацию о сеансеgpg-агент, он не утруждает себя поиском настоящего TTY самостоятельно (или даже передачей его в качестве дескриптора файла); онвсегдаожидает, что переменная среды $GPG_TTY присутствует и содержит информацию.
В качестве альтернативы вы можете избежать этого, включив опцию «loopback pinentry», при которой запросы на ввод пароля gpg-agent возвращаются обратногпгвместо запуска пользовательского интерфейса PIN-кода.
Для этого добавьте опцию pinentry-mode loopback
в ~/.gnupg/gpg.conf.
(В старых (устаревших) версиях GnuPG вам также может понадобиться опция allow-loopback-pinentry
в ~/.gnupg/gpg-agent.conf, и после ее добавления вам нужно будет выполнить обновление с помощью gpg-connect-agent reloadagent /bye
. Последняя версия GnuPG уже поддерживает режим замыкания на себя по умолчанию.)