Подписание коммита проходит успешно на локальной рабочей станции, но на той же рабочей станции через SSH происходит сбой?

Подписание коммита проходит успешно на локальной рабочей станции, но на той же рабочей станции через SSH происходит сбой?

Я работаю на машине 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 уже поддерживает режим замыкания на себя по умолчанию.)

Связанный контент