안전한 볼트 비밀을위한 Git clean / smudge 필터


20

git에서 clean / smudge 필터 를 설정 하여 ansible-vault 명령을 통해 비밀을 포함하는 파일을 자동으로 암호화하고 해독 하려고 합니다.

ansible-vault 명령의 특징은 dem 등성이 아니라는 것입니다 (동일한 데이터에서 호출 될 때마다 다른 바이너리를 작성 함).

이 블로그 페이지 에서 제안 된 구현으로 시작했습니다 . 불행히도 smudge가 호출 될 때마다 (git checkout 또는 git status) 비밀 파일은 git에 대해 수정 된 것처럼 보입니다.

그래서 git이 인덱스에있는 바이너리를 깨끗한 필터링 된 현재 파일과 비교할 것인지 궁금해하고 다음과 같이 해당 스크립트를 작성하려고했습니다.

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

여기서 차이점은 일반 텍스트 (암호화되지 않은) 비밀 파일의 현재 버전과 HEAD 버전을 비교하려고 시도하며 출력이 다른 경우에만 ansible-vault로 암호화 된 새 이진 Blob을 출력한다는 것입니다.

불행히도,이 변경 후에 git은 비밀 파일이 항상 수정되었다고 계속 생각합니다. git addgit blob이 계산되도록 파일을 다시 ing 한 후에도 git은 파일이 다르다고 생각하고 변경 사항을 커밋으로 보냅니다. git diff비어있는 변경 내용 을 반환해야합니다.

참고로, 이것은 얼룩입니다.

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

그리고 이것은 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

git이 곧 게시 할 볼트에서 충돌을 자동 병합하려고 할 때를 제외하고는 올바르게 동작하는 스크립트를 업데이트했습니다.
ᴳᵁᴵᴰᴼ

1
바다에 병을 던지지 만 다른 줄 끝이나 다른 코드 페이지로 인해 파일이 다를 수 있습니까?
Tensibai

-n얼룩 에코에서를 제거하려고 시도 하지만 추측입니다. 단일 행 끝을 무시하도록 지시하는 git diff에 대한 숨겨진 옵션이 없습니까?
Tensibai

또 다른 아이디어 : github.com/dellis23/ansible-toolkit (이 날에 더 깊이 파고들 것입니다)
Tensibai

답변:


8

여기서 문제는 볼트 저장소 암호화의 임의 소금으로 인해 발생합니다. VaultEditor 클래스를 해킹하여 볼트 저장소의 인수에서 소금을 전달할 수 있습니다. 무작위 소금은 lib/ansible/parsing/vault/__init__.py라인 에서 생성됩니다 . 그것은에서 호출되는 lib 디렉토리 / ansible / CLI / vault.py 쉽게 고정 소금의 인수를 추가 할 수있는. 변경 한 경우 Ansible에 업스트림 패치를 제출하십시오. 사용하고 싶습니다.

이 문제는 해커 뉴스 에서 더 논의됩니다 . 그리고 고정 소금을 사용하는 도구, 즉 gitcrypt , transcrypt 와 같은 다른 구현이 있습니다 . 여기 ansible-vault-tools 라는 ansible-vault를 사용하는 또 다른 구현에 대한 링크가 있지만 이것은 내가 아는 한 동일한 소금 문제가 있습니다.


코드를 확인하면 체크섬을 사용하여 가변 소금 문제를 해결할 수 있습니다. 먼저 tmp 폴더에서 HEAD 저장소를 해독하고 새 이진 블로 브를 생성하기 전에 일반 텍스트 파일의 체크섬을 비교하십시오. 조금 느리지 만 실제로는 괜찮습니다. 내 문제는 지금 합병에있다; 특정 상황에서는 작동하고 다른 상황에서는 블랍을 자동 병합하여 해독하기 전에 중단합니다.
ᴳᵁᴵᴰᴼ

내가 연결 한 세 가지 예를 살펴보면 병합에 대한 해결 방법도 있습니다. 그리고 그것은 해커 뉴스 의견에서도 논의되고 있습니다.
Jiri Klouda

BTW 병합은 까다 롭습니다. 당신이 알아야 할 것은 병합하는 동안 업스트림에서 모든 변경 사항이나 모든 변경 사항을 선택하는 경우 git은 해시 비교를 통해 알아낼 것입니다. 소금이 맞으면 작동합니다. 청소 / 얼룩에 임시 파일이 충분하지 않습니다. 병합에서 동일한 작업을 수행해야하며 충돌이 아닌 병합 체크 아웃의 경우 git에서 올바른 암호화 된 버전을 체크 아웃하고 새로운 임의 소금으로 다시 암호화하는 대신 해당 버전을 사용하십시오.
Jiri Klouda

나는 당신이 여기서 말하는 것을 이해하지 못합니다. 병합은 볼트의 일반 텍스트에서 발생하며 (확산을 통해 진행됨) 비밀은 자동 병합에서도 충돌로 표시되므로 병합 커밋 내의 병합 된 재 암호화 된 비밀을 포함하여 정말 (나에게) 문제를 나타냅니다.
ᴳᵁᴵᴰᴼ

그런 다음 병합 문제를 구체적으로 지정할 수 있습니까? 재현 가능한 사례를 제공해야합니다. 그러나 여전히 위에서 언급 한 3 가지 프로젝트에 대한 아이디어를 찾아 볼 것을 제안합니다. 병합 문제와 관련하여 컨텐츠 A를 컨텐츠 B와 병합하고 특별한 경우 인 버전 제어 시스템의 경우 항상 A 또는 항상 B를 취하기로 결정한 경우가 있으며 때로는 버전을 서로 연결하여이를 수행합니다. Git은 콘텐츠의 해시를 통해 해시가 동일하다고 가정하지만 콘텐츠가 모두 A 인 경우에도 다시 암호화하면 해시가 동일하지 않습니다. 그러나 당신은 다른 문제가있을 수 있습니다
Jiri Klouda
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.