Filtros Git clean / smudge para segredos ansible do cofre

20

Estou tentando configurar o filtro clean / smudge no git para ter criptografia e descriptografia automáticas de arquivos que contêm segredos através do comando ansible-vault .

A peculiaridade do comando ansible-vault é que ele não é idempotente (ele cria um binário diferente cada vez que é invocado nos mesmos dados).

Comecei com a implementação sugerida nesta página do blog . Infelizmente, ele não funcionou corretamente, pois sempre que uma mancha é chamada (seja um checkout do git ou apenas um status do git), os arquivos secretos parecem modificados para o git, mesmo que não o sejam.

Então, me perguntei se o git compararia o binário que ele possui no índice com o arquivo atual filtrado e limpo, e tentei criar esses scripts da seguinte maneira:

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

A diferença aqui é que ele tenta comparar as versões atual e HEAD dos arquivos secretos de texto sem formatação (não criptografados), e somente no caso de divergir eles produzem um novo blob binário criptografado com o ansible-vault.

Infelizmente, após essa alteração, o git continua pensando que o arquivo secreto é sempre modificado. Mesmo depois de git addinserir o arquivo novamente, para que o blob git seja computado, o git acha que o arquivo é diferente e deixa a alteração entrar no commit. Observe que git diffretorne alterações vazias, como deveria.

Para referência, isso é mancha:

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

e isso é 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
ᴳᵁᴵᴰᴼ
fonte
Eu atualizei scripts que se comportam corretamente, exceto tentativas quando git para conflitos AutoMerge para abóbadas que vou postar logo
ᴳᵁᴵᴰᴼ
1
Jogando uma garrafa no mar, mas: o arquivo poderia ser diferente por causa de terminações de linhas diferentes ou de uma página de códigos diferente?
Tensibai
Eu tentaria remover o -neco da mancha, mas isso é um palpite. Nenhuma opção oculta para o diff do git dizendo para ignorar finais de linha única?
Tensibai
No entanto, uma outra idéia: github.com/dellis23/ansible-toolkit (vou cavar mais profundamente este um dia)
Tensibai

Respostas:

8

O problema aqui é causado pelo sal aleatório na criptografia do ansible-vault. Você pode hackear a classe VaultEditor para passar o sal a partir de um argumento no ansible-vault. O sal aleatório é gerado lib/ansible/parsing/vault/__init__.pynesta linha . É chamado de lib / ansible / cli / vault.py, onde você pode adicionar facilmente o argumento para o salt fixo. Se você o alterar, envie um patch upstream para o Ansible, eu adoraria usá-lo.

Este problema é discutido aqui em notícias de hackers . E existem outras implementações com ferramentas que usam sal fixo, como gitcrypt , transcrypt . Aqui também está um link para mais uma implementação usando o ansible-vault chamado ansible-vault-tools , mas este tem o mesmo problema de sal, até onde eu sei.

Jiri Klouda
fonte
Se você verificar o código, estou usando uma soma de verificação para solucionar a questão do sal variável, ou seja. descriptografe o cofre HEAD em uma pasta tmp primeiro e compare as somas de verificação dos arquivos de texto sem formatação antes de gerar o novo blob binário. Isso é um pouco lento, mas está bem. Meu problema está nas mesclagens agora; em certas situações, funciona; em outras, recebo o blob automaticamente antes que eu possa descriptografá-lo e quebre.
ᴳᵁᴵᴰᴼ
Se você examinar os três exemplos que vinculei, também existem algumas soluções alternativas para as mesclagens. E isso também está sendo discutido nos comentários das notícias dos hackers.
Jiri Klouda
BTW Mesclar é complicado. O que você precisa entender é que, no caso de você escolher todas as suas alterações ou todas as alterações do upstream durante a mesclagem, o git descobriria isso através da comparação de hash, o que funcionaria se o sal estivesse correto. O arquivo temporário não é suficiente para limpar / borrar. Você precisaria fazer o mesmo na mesclagem e, no caso de verificação sem mesclagem de conflitos, a versão já criptografada correta do git e usá-la em vez de re-criptografar com novo sal aleatório.
Jiri Klouda
Não tenho certeza se entendi o que você está dizendo aqui; a mesclagem ocorreria no texto sem formatação dos cofres (conforme a difusão), e manter os segredos sempre marcados como um conflito, mesmo para mesclagens automáticas, incluindo, assim, segredos re-criptografados mesclados em qualquer confirmação de mesclagem. realmente representa um problema (para mim).
ᴳᵁᴵᴰᴼ
Você pode ser específico sobre os problemas de mesclagem? Você deve fornecer um caso reproduzível. Mas eu ainda sugeriria procurar idéias nos 3 projetos mencionados acima. Quanto aos problemas de mesclagem, quando você mescla o conteúdo A com o conteúdo B e todos resolvem usar sempre A ou sempre B, para sistemas de controle de versão que é um caso especial e, às vezes, eles fazem isso vinculando a versão. O Git faz isso através de hash no conteúdo, portanto, assumirá que o hash será o mesmo, mas se você criptografar novamente, mesmo se o conteúdo for todo A, o hash não será o mesmo. Mas você pode ter outro problema
Jiri Klouda 14/03