Valider la confiance de signature avec gpg?

13

Nous aimerions utiliser les signatures gpg pour vérifier certains aspects de nos outils de gestion de la configuration du système. De plus, nous aimerions utiliser un modèle de «confiance» dans lequel les clés sysadmin individuelles sont signées avec une clé de signature principale, puis nos systèmes font confiance à cette clé principale (et utilisent le «web de confiance» pour valider les signatures de nos administrateurs système).

Cela nous donne beaucoup de flexibilité, comme la possibilité de révoquer facilement la confiance sur une clé lorsque quelqu'un part, mais nous avons rencontré un problème. Bien que la gpgcommande vous indique si une clé n'est pas approuvée, elle ne semble pas renvoyer un code de sortie indiquant ce fait. Par exemple:

# 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 <[email protected]>"
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

La partie qui nous tient à cœur est la suivante:

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

Le code de sortie renvoyé par gpg dans ce cas est 0, malgré l'échec de l'approbation:

# echo $?
0

Comment faire échouer gpg dans le cas où quelque chose est signé avec une signature non fiable?

J'ai vu quelques suggestions selon lesquelles la gpgvcommande renverrait un code de sortie correct, mais gpgvne sait malheureusement pas comment récupérer les clés des serveurs de clés. Je suppose que nous pouvons analyser la sortie d'état (en utilisant --status-fd) gpg, mais y a-t-il une meilleure façon?

larsks
la source

Réponses:

6

C'est ce qui s'est soldé par:

#!/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

Cela recherche les informations d'approbation qui gpgsortent --status-fd. Le script se termine avec une erreur en présence d'une signature non approuvée (ou invalide / pas de signature):

$ 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 <[email protected]>"
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

Le script se ferme sans erreur en présence d'une signature valide et approuvée:

$ 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
la source
5

Permettez-moi donc d'essayer de diviser le problème:

Le premier problème semble que la clé contre laquelle vous testez n'est pas fiable.

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 <[email protected]>"
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

J'ai supposé que c'était intentionnel ... mais avant de découvrir comment résoudre ce problème, permettez-moi de vous suggérer d'utiliser gpgv au lieu de gpg -v ? Vous comprendrez pourquoi dans une minute:

$ 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

Pas de clé, pas de confiance ... Non, nous importons la clé dans trustedkeys.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 <[email protected]>" 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 <[email protected]>"

$ echo $?
0

J'espère que cela aide

Andre de Miranda
la source
J'ai commenté gpgv dans ma question - le problème avec gpgv est que même s'il renvoie un code d'erreur plus utile, il ne sait pas comment récupérer les clés d'un serveur de clés.
larsks
1

Deux options viennent à l'esprit (autre que l'analyse de la sortie).

Un moyen rapide et sale serait d'exécuter les deux gpg et gpgv. La première exécution de gpggarantirait que la clé a été récupérée à partir du serveur de clés, puis gpgvvous donnera le code retour que vous souhaitez.

Une manière plus élégante et contrôlée (bien que cela impliquerait plus de travail) serait d'utiliser la bibliothèque gpgme pour vérifier la signature. Il s'agit d'une bibliothèque C, bien qu'il existe des wrappers pour Perl , PHP , Python et Ruby . (Celui de Python est de niveau assez bas, tandis que celui de Ruby a des abstractions de niveau supérieur, pas sûr de Perl ou PHP).

La bibliothèque GPGME semble parler aux serveurs de clés lorsque je l'ai utilisée, bien que vous souhaitiez le confirmer. J'ai écrit un peu de code qui utilise la bibliothèque gpgme rubis (recherche verifyet verified_ok?pour le code qui vérifie une signature, et sig_output_linespour un code qui fonctionne si une signature est digne de confiance).

Hamish Downer
la source
-1

Qu'en est-il de la migration de la configuration de votre système vers un outil comme Puppet ou Chef ?

Bien qu'une quantité de travail non négligeable, Chef (je n'ai pas utilisé Puppet), vous devez créer des comptes d'utilisateurs (et les clés pub / privées sont générées). Bien que cela n'empêche pas les utilisateurs de modifier les fichiers localement sur le serveur, chef-client s'exécute périodiquement et écrasera leurs modifications lors de la prochaine exécution. (Des exécutions périodiques périodiques se produisent par défaut.)

gWaldo
la source