Git清理/涂抹过滤器以获取可疑的Vault机密


20

我正在尝试在git中设置清理/涂抹过滤器,以通过ansible-vault命令对包含机密的文件进行自动加密和解密。

ansible-vault命令的特殊之处在于它不是幂等的(每次在同一数据上调用它都会创建一个不同的二进制文件)。

从此博客页面建议的实现开始。不幸的是,它无法正常工作,因为每当调用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 add再次读取文件后,计算出git blob,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

这是差异:

#!/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试图automerge冲突拱顶上,我将在稍后发布,除了脚本
ᴳᵁᴵᴰᴼ

1
但是,如果在海上扔一个瓶子,由于行尾或代码页不同,文件是否可能不同?
Tensibai

我会尝试-n从污迹回波中删除,但这只是一个猜测。没有git diff的隐藏选项,告诉它忽略单行结尾?
2015年

还有一个想法:github.com/dellis23/ansible-toolkit(这一天我会做得更深入)
Tensibai,2017年

Answers:


8

这里的问题是由ansible-vault加密中的随机盐引起的。您可以修改VaultEditor类,以将ansible-vault中的参数传递给盐。lib/ansible/parsing/vault/__init__.py在这条线上生成随机盐。从lib / ansible / cli / vault.py中调用它,您可以在其中轻松添加固定盐的参数。如果确实要更改它,请向Ansible提交上游补丁,我很乐意使用它。

有关此问题,请参阅黑客新闻。还有其他的实现与收取定额盐,即工具gitcrypttranscrypt。这也是使用ansible-vault的另一个实现的链接,称为ansible-vault-tools,但是据我所知,这也存在相同的问题。


如果您检查代码,则我将使用校验和来解决可变盐问题,即。首先,在tmp文件夹中解密HEAD保险库,并在生成新的二进制Blob之前比较纯文本文件的校验和。有点慢,但实际上还可以。我的问题是现在合并。在某些情况下它可以工作,在其他情况下,我可以将blob自动合并,然后才能对其解密并破解。
ᴳᵁᴵᴰᴼ

如果您查看我链接的三个示例,那么在合并中也有一些解决方法。黑客新闻评论中也对此进行了讨论。
吉里·克鲁达

BTW合并非常棘手。您需要意识到的是,如果您在合并过程中选择了所有更改或从上游选择所有更改,则git会通过哈希比较来解决这一问题,如果正确,则可以使用。临时文件不足以进行清理/涂抹。您需要在合并时执行相同的操作,如果发生非冲突合并,请从git中检出正确的已加密版本,并使用该版本,而不是使用新的随机盐重新加密。
吉里·克劳达

不知道我明白你在说什么;合并将在保管库的纯文本上进行(通过差异进行),并且即使对于自动合并,也始终将机密标记为冲突,因此不会在任何合并提交中包括合并的重新加密机密确实代表了一个问题(对我而言)。
ᴳᵁᴵᴰᴼ

您能否具体说明合并问题?您应该提供可复制的案例。但是我仍然建议在上述3个项目中寻找想法。对于合并问题,当您将内容A与内容B合并在一起时,对于版本控制系统(这是特例),他们都决心始终采用A或始终采用B,有时它们会通过将版本链接在一起来做到这一点。Git通过对内容进行哈希处理来完成此操作,因此它将假定哈希值是相同的,但是如果您重新加密,即使内容全部为A,哈希值也将不相同。但是你可以有其他的问题
吉日Klouda
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.