git加密远程仓库
我本来对写这种step by step guide是不感兴趣的,公司付钱我都懒得写。但是这次我发现由于相关的开源工具还不够成熟,有一些坑并且很难debug,于是写下这篇博客,希望能节省大家的一些时间。
目的¶
我们很少自己去配置git服务器,相反,我们经常会使用一些第三方托管git repo的服务,例如github,这里有一个提供免费服务的网站列表: https://git.wiki.kernel.org/index.php/GitHosting
在使用这些服务的时候,我们可能需要储存一些私密信息,因此也存在将其暴露给第三方服务的风险。能否在并不信任服务提供商的同时使用他们的服务呢?一个解决方法就是每次我们push到remote之前都将repo加密,每次pull之后再解密。其实就是在与第三方的通信中加了一个代理。从第三方角度来看我们只是存了一些无法解释的乱码。恰好有一些工具可以提供这样的功能。
准备工作¶
首先我排除了git-crypt。
git-crypt 被设计用来加密git repo中的部分文件,其依赖于git filters。我个人认为属于防君子不防小人,如果第三方网站对你的敏感数据感兴趣,完全可以修改.gitattributes来禁用加密。更主要的原因是,如果你有一些access_token, private key之类的secret就不应该存在repo里。最佳实践应该是设法将其安全地存放在部署环境里。
于是我决定使用git-remote-gcrypt,其提供对整个仓库的加密。
git-remote-gcrypt只是一个让你用GnuPG去加密仓库的helper,自然也依赖于GnuPG。
多说几句,GnuPG其实是PGP的开源仿制版。PGP的作者是Phil Zimmermann,他有一个魔改版本的摩尔定律:
技术往往会自然地朝着易于监控的方向发展,计算机追踪我们的能力每18个月就会增加一倍。
因此我们需要安装GnuPG和git-remote-gcrypt:
on Debian/Ubuntu:
on MacOS:
生成密钥¶
首先使用gpg生成密钥,根据提示一步步往下走就可以。
之后你可以通过--list-keys参数来查看保存在本地的密钥:
| Bash | |
|---|---|
如果以后你的密钥泄露了,可以用--gen-revoke来生成撤销证书:
| Bash | |
|---|---|
也可以通过--delete-secret-key --delete-key来删除本地保存的密钥, 必须先删除private key。
更新密码:
| Bash | |
|---|---|
设置仓库¶
只需要remote url的前面加上gcrypt::,然后设置remote.<YOUR_CRYPTED_REMOTE>.gcrypt-participants 即可。url也可以是一个本地地址,不过一般没必要这么做。
例如:
| Bash | |
|---|---|
如果你用zsh的话,记得添加以下环境变量在你的cli:
| Bash | |
|---|---|
相关issue: gpg: signing failed: Inappropriate ioctl for device · Issue #2798 · keybase/keybase-issues
否则你之后会遇到如下错误:
| Bash | |
|---|---|
如果你不幸在看到提示以前已经push并且出错了,那么你就将遇到另一个大坑:
| Bash | |
|---|---|
是的,一旦出错,这个remote就不能用了,你将不得不再设置一个remote,例如crypted2:
| Bash | |
|---|---|
相关issue:git-remote-gcrypt might report a repository as "not found" · Issue #2 · jcouyang/dotfiles
导入导出密钥¶
既然都放在云上了,肯定是希望从另一台计算机可以访问到,否则也没必要折腾了。首先我们需要也安装好gunpg和git-remote-gcrypt,然后需要在另一台计算机上配置好密钥。
可以通过--output来导出密钥到文件,--armor选项以ASCII码的格式导出。
| Bash | |
|---|---|
导入:
| Bash | |
|---|---|
转移仓库¶
然后就非常简单了,直接git clone就可以,别忘了加上gcrypt::。
| Bash | |
|---|---|
就到这里吧,接下来基本上和正常使用git没有任何区别。如果本文提到的issue已经fixed了,欢迎评论或私信作者。我会更新相应内容。