Подтверждение доверия подписи с gpg?

13

Мы хотели бы использовать подписи gpg для проверки некоторых аспектов наших инструментов управления конфигурацией системы. Кроме того, мы хотели бы использовать модель «доверия», в которой отдельные ключи системного администратора подписываются главным ключом подписи, а затем наши системы доверяют этому главному ключу (и используют «сеть доверия» для проверки подписей нашими системными администраторами).

Это дает нам большую гибкость, например, возможность легко отозвать доверие к ключу, когда кто-то уходит, но мы столкнулись с проблемой. Хотя gpgкоманда скажет вам, если ключ не является доверенным, она не возвращает код завершения, указывающий этот факт. Например:

# gpg -v < foo.asc
Version: GnuPG v1.4.11 (GNU/Linux)
gpg: armor header: 
gpg: original file name=''
this is a test
gpg: Signature made Fri 22 Jul 2011 11:34:02 AM EDT using RSA key ID ABCD00B0
gpg: using PGP trust model
gpg: Good signature from "Testing Key <someone@example.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: ABCD 1234 0527 9D0C 3C4A  CAFE BABE DEAD BEEF 00B0
gpg: binary signature, digest algorithm SHA1

Часть, о которой мы заботимся, такова:

gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.

Код выхода, возвращаемый gpg, в этом случае равен 0, несмотря на ошибку доверия:

# echo $?
0

Как заставить gpg потерпеть неудачу в случае, если что-то подписано ненадежной подписью?

Я видел некоторые предположения, что gpgvкоманда вернет правильный код завершения , но, к сожалению gpgv, не знает, как получить ключи от серверов ключей. Я думаю, что мы можем проанализировать вывод состояния (используя --status-fd) gpg, но есть ли лучший способ?

larsks
источник

Ответы:

6

Вот что в итоге получилось:

#!/bin/sh

tmpfile=$(mktemp gpgverifyXXXXXX)
trap "rm -f $tmpfile" EXIT

gpg --status-fd 3 --verify "$@" 3> $tmpfile || exit 1
egrep -q '^\[GNUPG:] TRUST_(ULTIMATE|FULLY)' $tmpfile

Это ищет информацию о доверии, которая gpgвыводится на --status-fd. Сценарий завершается с ошибкой при наличии ненадежной подписи (или недействительной / без подписи):

$ sh checksig sample.sh.bad 
gpg: Signature made Mon 24 Jun 2013 11:42:58 AM EDT using RSA key ID DCD5C569
gpg: Good signature from "Test User <testuser@example.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 6FCD 3CF0 8BBC AD50 662E  5070 E33E D53C DCD5 C569
$ echo $?
1

Сценарий завершается без ошибок при наличии действительной доверенной подписи:

$ sh checksig sample.sh.good
gpg: Signature made Mon 24 Jun 2013 11:38:49 AM EDT using RSA key ID 5C2864A8
gpg: Good signature from "Lars Kellogg-Stedman <...>"
$ echo $?
0
larsks
источник
5

Итак, позвольте мне попытаться разделить проблему:

Первая проблема, кажется, что ключ, который вы проверяете, не заслуживает доверия.

gpg -v < test.txt.asc 
gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux)
gpg: original file name='test.txt'
this is a test
gpg: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpg: using PGP trust model
gpg: Good signature from "John Doe <jdoe@noemail.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 5DD8 216D ADB1 51E8 4326  3ACA 1DED BB72 FE1B 770E
gpg: binary signature, digest algorithm SHA1

Я предположил, что это намеренно ... но прежде чем мы перейдем к тому, как это исправить, позвольте мне предложить вам использовать gpgv вместо gpg -v ? Вы поймете, почему через минуту:

$ gpgv < test.txt.asc 
gpgv: keyblock resource `/user/.gnupg/trustedkeys.gpg': file open error
gpgv: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpgv: Can't check signature: public key not found

$ echo $?
2

Нет ключа, нет доверия ... Нет, мы импортируем ключ вrustkeys.gpg

$ gpg --no-default-keyring --keyring trustedkeys.gpg --import jdoe_pub.gpg
gpg: keyring `/user/.gnupg/trustedkeys.gpg' created
gpg: key FE1B770E: public key "John Doe <jdoe@noemail.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
$ gpgv < test.txt.asc 
gpgv: Signature made Thu 11 Aug 2011 09:09:35 PM EST using RSA key ID FE1B770E
gpgv: Good signature from "John Doe <jdoe@noemail.com>"

$ echo $?
0

Надеюсь, это поможет

Андре де Миранда
источник
Я прокомментировал gpgv в своем вопросе - проблема с gpgv заключается в том, что, хотя он возвращает более полезный код ошибки, он не знает, как получить ключи с сервера ключей.
Жаворонки
1

На ум приходят два варианта (кроме анализа выходных данных).

Быстрый и грязный способ - запустить и то gpg и другоеgpgv . Первый запуск gpgгарантирует, что ключ был получен с сервера ключей, а затем gpgvдаст вам код возврата, который вы хотите.

Более элегантный, контролируемый способ (хотя это потребует дополнительных усилий ) - использовать библиотеку gpgme для проверки подписи. Это библиотека C, хотя есть обертки для Perl , PHP , Python и Ruby . (У Python достаточно низкий уровень, в то время как у Ruby есть несколько абстракций более высокого уровня, не уверен насчет Perl или PHP).

Библиотека GPGME, кажется, общается с серверами ключей, когда я ее использую, хотя вы захотите это подтвердить. Я написал немного кода, который использует библиотеку ruby ​​gpgme (для поиска verifyи verified_ok?для кода, который проверяет подпись, и sig_output_linesдля некоторого кода, который выясняет, доверяют ли подписи).

Хэмиш Даунер
источник
-1

А как насчет миграции конфигурации вашей системы на такой инструмент, как Puppet или Chef ?

В то время как нетривиальный объем работы, Chef (я не использовал Puppet), вы должны создавать учетные записи пользователей (и генерируются публичные / закрытые ключи). Хотя это не мешает пользователям изменять локальные файлы на сервере, chef-client периодически запускается и перезаписывает свои изменения при следующем запуске. (Периодические периодические запуски происходят по умолчанию.)

gWaldo
источник