안전한 볼트 비밀을위한 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.