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

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.