Git clean / smudge filter untuk kemungkinan rahasia vault

20

Saya mencoba untuk mensetup filter clean / smudge di git agar enkripsi dan dekripsi file secara otomatis berisi rahasia melalui perintah vault yang dimungkinkan .

Keunikan dari perintah anault-vault adalah bahwa ia tidak idempoten (ini menciptakan biner yang berbeda setiap kali dipanggil pada data yang sama).

Saya mulai dengan implementasi yang disarankan di halaman blog ini . Sayangnya itu tidak berfungsi dengan benar, karena setiap kali noda dipanggil (baik itu checkout git, atau hanya status git), file-file rahasia terlihat dimodifikasi untuk git, bahkan jika tidak.

Jadi saya bertanya-tanya apakah git akan membandingkan biner yang dia miliki dalam indeks dengan file saat ini yang disaring bersih, dan saya mencoba membangun skrip tersebut seperti berikut:

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

Perbedaannya di sini adalah bahwa ia mencoba untuk membandingkan versi saat ini dan HEAD dari file rahasia teks biasa (tidak terenkripsi), dan hanya dalam kasus mereka berbeda menghasilkan gumpalan biner baru dienkripsi dengan kubah yang dimungkinkan.

Sayangnya, setelah perubahan ini git terus berpikir file rahasia selalu dimodifikasi. Bahkan setelah git addmemasukkan file lagi, sehingga git blob dikomputasi, git berpikir file itu berbeda dan biarkan perubahannya masuk ke dalam commit. Perhatikan bahwa git diffmengembalikan perubahan kosong, sebagaimana mestinya.

Untuk referensi, ini noda:

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

dan ini berbeda:

#!/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
ᴳᵁᴵᴰᴼ
sumber
Saya telah memperbarui skrip yang berperilaku benar kecuali ketika git mencoba untuk mengotomatiskan konflik pada kubah yang akan saya posting segera
ᴳᵁᴵᴰᴼ
1
Melempar botol ke laut tetapi: bisakah file tersebut berbeda karena akhiran baris yang berbeda atau halaman kode yang berbeda?
Tensibai
Saya akan mencoba mengeluarkan -ndari gema noda, tapi itu dugaan. Tidak ada opsi tersembunyi untuk git diff yang mengatakannya untuk mengabaikan akhir baris tunggal?
Tensibai
Namun ide lain: github.com/dellis23/ansible-toolkit (saya akan menggali lebih dalam pada hari ini)
Tensibai

Jawaban:

8

Masalahnya di sini disebabkan oleh garam acak dalam enkripsi kubah yang mungkin. Anda bisa meretas kelas VaultEditor untuk mengirimkan garam ke sana dari argumen di kubah yang mungkin. Garam acak dihasilkan lib/ansible/parsing/vault/__init__.pypada baris ini . Itu disebut dari lib / ansible / cli / vault.py di mana Anda dapat dengan mudah menambahkan argumen untuk garam tetap. Jika Anda benar-benar mengubahnya, silakan kirim tambalan hulu ke Ansible, saya ingin menggunakannya.

Masalah ini dibahas lebih lanjut di sini di berita hacker . Dan ada implementasi lain dengan alat yang mengambil garam tetap, yaitu gitcrypt , transcrypt . Berikut ini juga tautan ke satu implementasi lagi menggunakan ansible-vault yang disebut ansible-vault-tools , tetapi yang ini memiliki masalah garam yang sama sejauh yang saya tahu.

Jiri Klouda
sumber
Jika Anda memeriksa kode, saya menggunakan checksum untuk menyelesaikan masalah variabel garam, yaitu. mendekripsi kubah HEAD di folder tmp terlebih dahulu dan bandingkan checksum dari file teks biasa sebelum membuat gumpalan biner yang baru. Itu agak lambat tapi sebenarnya ok. Masalah saya ada pada penggabungan sekarang; dalam situasi tertentu ia berfungsi, di lain hal saya mendapatkan gumpalan diotomatisasi sebelum saya dapat mendekripsi dan rusak.
ᴳᵁᴵᴰᴼ
Jika Anda melihat ke tiga contoh yang telah saya tautkan, ada beberapa solusi untuk penggabungan juga. Dan itu sedang dibahas dalam komentar berita hacker juga.
Jiri Klouda
Penggabungan BTW itu rumit. Yang perlu Anda sadari adalah bahwa jika Anda memilih semua perubahan atau semua perubahan dari hulu selama penggabungan, git akan mencari tahu melalui perbandingan hash, yang akan bekerja jika garamnya benar. File temp tidak cukup pada clean / smudge. Anda perlu melakukan hal yang sama pada penggabungan dan dalam kasus checkout penggabungan non-konflik yang benar sudah dienkripsi versi dari git dan gunakan yang bertentangan untuk mengenkripsi ulang dengan garam acak baru.
Jiri Klouda
Tidak yakin saya mengerti apa yang Anda katakan di sini; penggabungan akan terjadi pada teks biasa dari kubah (seperti yang terjadi melalui perbedaan), dan memiliki rahasia selalu ditandai sebagai konflik bahkan untuk penggabungan otomatis, sehingga termasuk rahasia yang dienkripsi ulang yang digabungkan dalam setiap komitmen gabungan, tidak akan benar-benar mewakili masalah (untuk saya).
ᴳᵁᴵᴰᴼ
Bisakah Anda menjadi spesifik tentang masalah gabungan? Anda harus menyediakan kasing yang dapat direproduksi. Tetapi saya masih menyarankan untuk mencari ide ke dalam 3 proyek yang disebutkan di atas. Adapun masalah penggabungan, ketika Anda menggabungkan konten A dengan konten B dan Anda semua telah memutuskan untuk selalu mengambil A atau selalu B, untuk sistem kontrol versi yang merupakan kasus khusus dan mereka kadang-kadang akan melakukannya dengan menghubungkan versi bersama. Git melakukannya melalui hash pada konten, sehingga akan menganggap hash akan sama, tetapi jika Anda mengenkripsi ulang, bahkan jika konten semuanya A, hash tidak akan sama. Tetapi Anda dapat memiliki masalah lain
Jiri Klouda