Git Clean / Smudge-Filter für anfällige Tresor-Geheimnisse

20

Ich versuche, einen Clean / Smudge-Filter in Git einzurichten, um Dateien, die Geheimnisse enthalten, automatisch durch den Befehl ansible-vault zu verschlüsseln und zu entschlüsseln .

Die Besonderheit des ansible-vault-Befehls besteht darin, dass er nicht idempotent ist (er erstellt jedes Mal eine andere Binärdatei, wenn er für dieselben Daten aufgerufen wird).

Ich habe mit der auf dieser Blog-Seite vorgeschlagenen Implementierung begonnen . Leider hat es nicht richtig funktioniert, da bei jedem Aufruf von smudge (sei es eine Git-Prüfung oder nur der Git-Status) die geheimen Dateien wie für Git geändert aussehen, auch wenn dies nicht der Fall ist.

Also habe ich mich gefragt, ob git die Binärdatei, die er im Index hat, mit der sauber gefilterten aktuellen Datei vergleichen würde, und ich habe versucht, auf diesen Skripten wie folgt aufzubauen:

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

Der Unterschied besteht darin, dass versucht wird, die aktuelle und die HEAD-Version der (unverschlüsselten) geheimen Dateien im Klartext zu vergleichen, und nur dann, wenn sie sich unterscheiden, ein neues mit ansible-vault verschlüsseltes Binär-Blob ausgegeben wird.

Leider glaubt git nach dieser Änderung weiterhin, dass die geheime Datei immer geändert wird. Auch nachdem git adddie Datei erneut erstellt wurde, sodass der Git-Blob berechnet wird, denkt Git, dass die Datei anders ist, und lässt die Änderung in das Festschreiben übergehen. Beachten Sie, dass git diffleere Änderungen wie gewünscht zurückgegeben werden.

Als Referenz ist dies Fleck:

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

und das ist 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
ᴳᵁᴵᴰᴼ
quelle
Ich habe Skripte aktualisiert, die sich korrekt verhalten, außer wenn git versucht, Konflikte auf Tresoren zu automatisieren, die ich in Kürze veröffentlichen werde
ᴳᵁᴵᴰᴼ
1
Eine Flasche ins Meer werfen, aber: Kann die Datei aufgrund unterschiedlicher Zeilenenden oder Codepage unterschiedlich sein?
Tensibai
Ich würde versuchen, das -nFleck-Echo zu entfernen , aber das ist eine Vermutung. Keine versteckte Option für git diff, um einzelne Zeilenenden zu ignorieren?
Tensibai
Noch eine Idee: github.com/dellis23/ansible-toolkit (ich werde mich eines Tages
genauer damit befassen

Antworten:

8

Das Problem wird hier durch das zufällige Salt bei der Ansible-Vault-Verschlüsselung verursacht. Sie können die VaultEditor-Klasse hacken, um das Salt von einem Argument in Ansible-Vault an sie weiterzuleiten. Das zufällige Salz wird in lib/ansible/parsing/vault/__init__.pydieser Zeile erzeugt . Es wird von lib / ansible / cli / vault.py aufgerufen, wo Sie leicht das Argument für Fixed Salt hinzufügen können. Wenn Sie es ändern, senden Sie bitte einen Upstream-Patch an Ansible. Ich würde ihn gerne verwenden.

Dieses Problem wird hier in den Hacker-News weiter diskutiert . Und es gibt andere Implementierungen mit Werkzeugen , das Salz Fest nehmen, nämlich gitcrypt , Transcrypt . Hier ist auch ein Link zu einer weiteren Implementierung mit ansible-vault namens ansible-vault-tools , aber diese hat meines Wissens das gleiche Salt-Problem.

Jiri Klouda
quelle
Wenn Sie den Code überprüfen, verwende ich eine Prüfsumme, um das Problem mit dem variablen Salz zu umgehen, dh. Entschlüsseln Sie zuerst den HEAD-Tresor in einem tmp-Ordner und vergleichen Sie die Prüfsummen von Nur-Text-Dateien, bevor Sie den neuen Binär-Blob generieren. Das ist etwas langsam, aber eigentlich in Ordnung. Mein Problem ist im merges jetzt; In bestimmten Situationen funktioniert es, in anderen Fällen wird der Blob automatisch gecompt, bevor ich ihn entschlüsseln kann und er bricht.
14.
Wenn Sie sich die drei Beispiele ansehen, die ich verlinkt habe, gibt es auch einige Problemumgehungen bei den Zusammenführungen. Und darüber wird auch in den Hacker-News-Kommentaren gesprochen.
Jiri Klouda
Übrigens Zusammenführen ist schwierig. Was Sie wissen müssen, ist, dass in dem Fall, in dem Sie alle Ihre Änderungen oder alle Änderungen aus dem Upstream während der Zusammenführung auswählen, git dies durch Hash-Vergleich herausfinden würde, was funktionieren würde, wenn das Salz richtig wäre. Die temporäre Datei reicht nicht für Clean / Smudge aus. Sie müssten dasselbe beim Zusammenführen tun und im Falle eines konfliktfreien Zusammenführens die korrekte, bereits verschlüsselte Version von git auschecken und diese verwenden, anstatt sie erneut mit neuem Zufalls-Salt zu verschlüsseln.
Jiri Klouda
Ich verstehe nicht, was du hier sagst. Das Zusammenführen würde im Klartext der Tresore erfolgen (je nach dem, wie es aussieht), und wenn die Geheimnisse auch bei automatischen Zusammenführungen immer als Konflikt markiert würden, würde dies nicht der Fall sein, wenn zusammengeführte, neu verschlüsselte Geheimnisse in ein Zusammenführungs-Commit einbezogen würden wirklich ein Problem darstellen (für mich).
14.
Können Sie sich dann auf die Zusammenführungsprobleme konzentrieren? Sie sollten reproduzierbaren Fall zur Verfügung stellen. Aber ich würde trotzdem vorschlagen, nach Ideen für die drei oben genannten Projekte zu suchen. Was die Zusammenführungsprobleme betrifft, wenn Sie Inhalt A mit Inhalt B zusammenführen und Sie alle beschlossen haben, für Versionskontrollsysteme immer A oder immer B zu nehmen, ist dies ein Sonderfall, und dies wird manchmal durch Verknüpfen der Version erreicht. Git tut dies durch Hash auf den Inhalt, so dass davon ausgegangen wird, dass der Hash derselbe ist. Wenn Sie ihn jedoch erneut verschlüsseln, ist der Hash nicht derselbe, auch wenn der Inhalt nur A ist. Aber Sie könnten ein anderes Problem haben
Jiri Klouda