Filtres Git Clean / Smudge pour les secrets du coffre-fort Ansible

20

J'essaie de configurer le filtre Clean / Smudge dans git pour avoir le cryptage et le décryptage automatiques des fichiers contenant des secrets via la commande ansible-vault .

La particularité de la commande ansible-vault est qu'elle n'est pas idempotente (elle crée un binaire différent à chaque fois qu'elle est invoquée sur les mêmes données).

J'ai commencé avec l'implémentation suggérée dans cette page de blog . Malheureusement, cela n'a pas fonctionné correctement, car chaque fois que smudge est appelé (que ce soit un git checkout ou simplement git status), les fichiers secrets ont l'air modifiés pour git, même s'il ne l'est pas.

Je me suis donc demandé si git comparerait le binaire qu'il a dans l'index avec le fichier actuel filtré et j'ai essayé de construire sur ce script comme suit:

#!/bin/sh -x
# clean filter, it is invoked with %f

if [ ! -r "$HOME/.vault_password" ]; then
  exit 1
fi

tmp=`mktemp`
cat > $tmp

# get the plain text from the binary in the index
tmphead=`mktemp`
git show HEAD:$1 > $tmphead
contenthead=`echo "embedded" | ansible-vault view $tmphead --vault-password-file=$HOME/.vault_password`
export PAGER=cat
echo -n "$contenthead" | tee $tmphead

# if current and index plain text version differ
if [ "`md5sum $tmp | cut -d' ' -f1`" != "`md5sum $tmphead | cut -d' ' -f1`" ]; then
  tmpcrypt=`mktemp`
  cp $tmp $tmpcrypt
  # generate a new crypted blob
  echo "embedded" | ansible-vault encrypt $tmpcrypt --vault-password-file=$HOME/.vault_password > /dev/null 2>&1
  cat "$tmpcrypt"
else
  # just return the HEAD version
  cat "$tmphead"
fi

rm $tmp $tmphead $tmpcrypt

La différence ici est qu'il essaie de comparer les versions actuelles et HEAD des fichiers secrets en texte brut (non cryptés), et seulement dans le cas où ils diffèrent, un nouveau blob binaire crypté avec ansible-vault.

Malheureusement, après ce changement, git continue de penser que le fichier secret est toujours modifié. Même après avoir à nouveau git addgénéré le fichier, afin que le blob git soit calculé, git pense que le fichier est différent et laisse le changement entrer dans le commit. Notez que git diffrenvoyez les modifications vides, comme il se doit.

Pour référence, c'est une tache:

#!/bin/sh

if [ ! -r "$HOME/.vault_password" ]; then
  exit 1
fi

tmp=`mktemp`
cat > $tmp

export PAGER='cat'
CONTENT="`echo "embedded" | ansible-vault view "$tmp" --vault-password-file=$HOME/.vault_password 2> /dev/null`"

if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
  echo "Looks like one file was commited clear text"
  echo "Please fix this before continuing !"
  exit 1
else
  echo -n "$CONTENT"
fi

rm $tmp

et c'est diff:

#!/bin/sh

if [ ! -r "$HOME/.vault_password" ]; then
  exit 1
fi

export PAGER='cat'
CONTENT=`echo "embedded" | ansible-vault view "$1" --vault-password-file=$HOME/.vault_password 2> /dev/null`

if echo "$CONTENT" | grep 'ERROR: data is not encrypted' > /dev/null; then
  cat "$1"
else
  echo "$CONTENT"
fi
ᴳᵁᴵᴰᴼ
la source
J'ai mis à jour des scripts qui se comportent correctement, sauf lorsque git essaie de générer automatiquement des conflits sur les coffres que je
publierai sous
1
Jeter une bouteille à la mer mais: le fichier pourrait-il être différent en raison de différentes fins de ligne ou d'une page de codes différente?
Tensibai
J'essaierais de supprimer le -nde l'écho des taches, mais c'est une supposition. Pas d'option cachée pour git diff lui disant d'ignorer les fins de ligne unique?
Tensibai
Encore une autre idée: github.com/dellis23/ansible-toolkit ( j'explorerai plus profondément cette journée)
Tensibai

Réponses:

8

Le problème ici est causé par le sel aléatoire dans le cryptage ansible-vault. Vous pouvez pirater la classe VaultEditor pour lui passer le sel à partir d'un argument dans ansible-vault. Le sel aléatoire est généré lib/ansible/parsing/vault/__init__.pysur cette ligne . Il est appelé depuis lib / ansible / cli / vault.py où vous pouvez facilement ajouter l'argument pour le sel fixe. Si vous le modifiez, veuillez soumettre un correctif en amont à Ansible, j'adorerais l'utiliser.

Ce problème est discuté plus en détail ici sur les nouvelles des pirates . Et il y a d' autres mises en œuvre avec des outils fixes qui prennent le sel, à savoir gitcrypt , Transcrypt . Voici également un lien vers une autre implémentation utilisant ansible-vault appelée ansible-vault-tools , mais celle-ci a le même problème de sel pour autant que je sache.

Jiri Klouda
la source
Si vous vérifiez le code, j'utilise une somme de contrôle pour contourner le problème du sel variable, c'est-à-dire. déchiffrez d'abord le coffre HEAD dans un dossier tmp et comparez les sommes de contrôle des fichiers en texte brut avant de générer le nouveau blob binaire. C'est un peu lent mais ça va. Mon problème est sur les fusions maintenant; dans certaines situations, cela fonctionne, dans d'autres, je fais fusionner le blob avant de pouvoir le décrypter et il se casse.
ᴳᵁᴵᴰᴼ
Si vous regardez les trois exemples que j'ai liés, il existe également des solutions de contournement sur les fusions. Et cela est également discuté dans les commentaires des pirates.
Jiri Klouda
La fusion BTW est délicate. Ce que vous devez comprendre, c'est que dans le cas où vous choisissez toutes vos modifications ou toutes les modifications en amont pendant la fusion, git comprendrait cela par une comparaison de hachage, ce qui fonctionnerait si le sel était bon. Le fichier temporaire n'est pas suffisant sur clean / smudge. Vous devrez faire de même lors de la fusion et en cas de fusion sans conflit, vérifiez la bonne version déjà chiffrée de git et utilisez-la plutôt que de rechiffrer avec un nouveau sel aléatoire.
Jiri Klouda
Je ne suis pas sûr de comprendre ce que vous dites ici; la fusion se produirait sur le texte brut des coffres-forts (comme il en va différemment), et avoir les secrets toujours marqués comme un conflit même pour les fusions automatiques, incluant ainsi des secrets rechiffrés fusionnés dans tout commit de fusion, ne serait pas représentent vraiment un problème (pour moi).
ᴳᵁᴵᴰᴼ
Pouvez-vous être précis sur les problèmes de fusion? Vous devez fournir un étui reproductible. Mais je suggérerais quand même de chercher des idées dans les 3 projets mentionnés ci-dessus. En ce qui concerne les problèmes de fusion, lorsque vous fusionnez le contenu A avec le contenu B et que vous avez tous résolu de prendre toujours A ou toujours B, pour les systèmes de contrôle de version, c'est un cas spécial et ils le feront parfois en reliant la version ensemble. Git le fait via le hachage du contenu, il supposera donc que le hachage sera le même, mais si vous rechiffrez, même si le contenu est entièrement A, le hachage ne sera pas le même. Mais vous pourriez avoir un autre problème
Jiri Klouda