git-secret:在 Git 存储库中加密和存储密钥(上)
当涉及处理机密信息(如密码、令牌、密钥文件等)等,以下问题值得考虑:
安全性十分重要,但高安全性往往伴随着高度的不便。
在团队中,共享某些密钥有时无法避免(因此现在我们需要考虑在多人之间分发和更新密钥的安全方法)。
具体的密钥通常取决于环境。
目前市面上已经存在许多较为成熟的密钥管理产品,比如 HashiCorp Vault,AWS Secrets Manager 以及 GCP Secret Manager。由于这些产品需要集成和维护等服务,因此在项目中引入会增加一定成本和开销。阅读本文,将带你了解如何在 Docker 容器中设置 git-secret
和 gpg
。
本文将对以下几点展开讲解:
识别包含密钥的文件
确保将密钥添加到
.gitignore
通过
git-secret
进行加密将加密文件提交到存储库
在最后我们将能够调用:
make secret-decrypt
这将会披露代码库中的密钥,在必要时对其进行修改,然后运行:
make secret-encrypt
需要再次加密密钥,以便提交(并推送到远程存储库),要查看实际效果请运行以下命令:
# checkout the branch
git checkout part-6-git-secret-encrypt-repository-docker
# build and start the docker setup
make make-init
make docker-build
make docker-up
# "create" the secret key - the file "secret.gpg.example" would usually NOT live in the repo!
cp secret.gpg.example secret.gpg
# initialize gpg
make gpg-init
# ensure that the decrypted secret file does not exist
ls passwords.txt
# decrypt the secret file
make secret-decrypt
# show the content of the secret file
cat passwords.txt
Tooling
我们在 PHP base
镜像中设置 gpg
和 git-secret
以便这些工具在所有其他容器中都可用。以下所有命令都在 application
容器中执行。
请注意,git-secret
在主机系统和 docker 容器之间共享的文件夹中使用时需要注意。将在下面称为 “git-secret
目录和 gpg-agent
socket”的部分中更详细地解释这一点。
gpg
gpg 是The GNU Privacy Guard的缩写,是 OpenPGP 标准的开源实践。简而言之,GNU允许我们创建一个个人密钥文件对(类似于 SSH 密钥),其中包含一个私有密钥和一个可以与您想要解密其消息的其他方共享的公共密钥。
gpg 安装
关于安装,我们可以简单地运行 apk add gnupg
并相应更新 .docker/images/php/base/Dockerfile
:
# File: .docker/images/php/base/DockerfileRUN apk add --update --no-cache \
bash \
gnupg \
make \
#...
创建 gpg 密钥对
我们需要通过以下方式创建 gpg
密钥对(Key Pair):
name="Pascal Landau"
email="pascal.landau@example.com"
gpg --batch --gen-key <<EOF
Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: $name
Name-Email: $email
Expire-Date: 0
%no-protection
EOF
%no-protection
创建一个没有密码的key。
输出:
$ name="Pascal Landau"
$ email="pascal.landau@example.com"
$ gpg --batch --gen-key <<EOF
> Key-Type: 1
> Key-Length: 2048
> Subkey-Type: 1
> Subkey-Length: 2048
> Name-Real: $name
> Name-Email: $email
> Expire-Date: 0
> %no-protection
> EOF
gpg: key E1E734E00B611C26 marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/opengpg-revocs.d/74082D81525723F5BF5B2099E1E734E00B611C26.rev'
也可以在没有 --batch
标志的情况下以交互方式引导整个过程运行gpg --gen-key
,然后导出、列出和导入私有 gpg
Key,可以通过以下方式导出:
email="pascal.landau@example.com"
path="secret.gpg"
gpg --output "$path" --armor --export-secret-key "$email"
记住不能共享此密钥。
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQOYBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejv
G21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339
XDPO3Rys+CmnZchcEgnbOfQlEqo51DMj6mRF2Ra/6svh7lqhrixGx1BaKn6VlHkC
...
ncIcHxNZt7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZ
xT3SieoBPd+tZikhu3BqyIifmLnxOJOjOIhbQrgFiblvzU1iOUOTOcSIB+7A
=YmRm
-----END PGP PRIVATE KEY BLOCK-----
所有密钥都可以通过以下方式列出:
gpg --list-secret-keys
输出:
$ gpg --list-secret-keys
/root/.gnupg/pubring.kbx
------------------------
sec rsa2048 2022-03-27 [SCEA]
74082D81525723F5BF5B2099E1E734E00B611C26
uid [ultimate] Pascal Landau <pascal.landau@example.com>
ssb rsa2048 2022-03-27 [SEA]
可以通过以下方式导入私钥:
path="secret.gpg"
gpg --import "$path"
得到以下输出:
$ path="secret.gpg"
$ gpg --import "$path"
gpg: key E1E734E00B611C26: "Pascal Landau <pascal.landau@example.com>" not changed
gpg: key E1E734E00B611C26: secret key imported
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys unchanged: 1
注意:如果secret key需要密码,这里会提示输入密码。我们可以使用以下方法绕过提示--batch --yes --pinentry-mode loopback
:
path="secret.gpg"
gpg --import --batch --yes --pinentry-mode loopback "$path"
目前还不需要提供密码,但需要在稍后尝试解密文件时提供。
导出、列出和导入gpg
公钥,可以通过以下方式导出public.gpg
:
email="pascal.landau@example.com"
path="public.gpg"
gpg --armor --export "$email" > "$path"
导出如下:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejv
G21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339
...
3LLbK7Qxz0cV12K7B+n2ei466QAYXo03a7WlsPWn0JTFCsHoCOphjaVsncIcHxNZ
t7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZxT3SieoB
Pd+tZikhu3BqyIifmLnxOJOjOIhbQrgFiblvzU1iOUOTOcSIB+7A
=g0hF
-----END PGP PUBLIC KEY BLOCK-----
通过以下方式列出所有公钥:
gpg --list-keys
输出:
$ gpg --list-keys
/root/.gnupg/pubring.kbx
------------------------
pub rsa2048 2022-03-27 [SCEA]
74082D81525723F5BF5B2099E1E734E00B611C26
uid [ultimate] Pascal Landau <pascal.landau@example.com>
sub rsa2048 2022-03-27 [SEA]
通过以下方式以与私钥相同的方式导入公钥:
path="public.gpg"
gpg --import "$path"
例如:
$ gpg --import /var/www/app/public.gpg
gpg: key E1E734E00B611C26: "Pascal Landau <pascal.landau@example.com>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
git-secret
git-secret的官方网站可以找到详细介绍该工具的内容。git-secret允许将某些文件声明为“secret”并通过 gpg
加密。然后可以将加密的文件直接安全地存储在 Git 存储库中,并在需要时进行解密。本文使用 git-secret v0.4.0
:
$ git secret --version
0.4.0
git-secret 安装
Alpine 的安装说明如下:
sh -c "echo 'https://gitsecret.jfrog.io/artifactory/git-secret-apk/all/main'" >> /etc/apk/repositories
wget -O /etc/apk/keys/git-secret-apk.rsa.pub 'https://gitsecret.jfrog.io/artifactory/api/security/keypair/public/repositories/git-secret-apk'
apk add --update --no-cache git-secret
.docker/images/php/base/Dockerfile
进行更新:
# File: .docker/images/php/base/Dockerfile
# install git-secret
# @see https://git-secret.io/installation#alpine
ADD https://gitsecret.jfrog.io/artifactory/api/security/keypair/public/repositories/git-secret-apk /etc/apk/keys/git-secret-apk.rsa.pub
RUN echo "https://gitsecret.jfrog.io/artifactory/git-secret-apk/all/main" >> /etc/apk/repositories && \
apk add --update --no-cache \
bash \
git-secret \
gnupg \
make \
#...
git-secret 用法
初始化 git-secret
git-secret
通过在 Git 存储库的根目录中运行的以下命令进行初始化。
git secret init$ git secret init
git-secret: init created: '/var/www/app/.gitsecret/'
只需这样操作一次,稍后会把文件夹提交到 Git,将包含以下文件:
$ git status | grep ".gitsecret"
new file: .gitsecret/keys/pubring.kbx
new file: .gitsecret/keys/pubring.kbx~
new file: .gitsecret/keys/trustdb.gpg
new file: .gitsecret/paths/mapping.cfg
该 pubring.kbx~
文件(带有波浪号~
)只是一个临时文件,可以安全地被 git 忽略。
git-secret Directory 和 gpg-agent Socket
要 git-secret
在主机系统和 Docker 之间共享的目录中使用,还需要运行以下命令:
tee .gitsecret/keys/S.gpg-agent <<EOF
%Assuan%
socket=/tmp/S.gpg-agent
EOF
tee .gitsecret/keys/S.gpg-agent.ssh <<EOF
%Assuan%
socket=/tmp/S.gpg-agent.ssh
EOF
tee .gitsecret/keys/gpg-agent.conf <<EOF
extra-socket /tmp/S.gpg-agent.extra
browser-socket /tmp/S.gpg-agent.browser
EOF
这一步很必要,因为 git-secret
在主机系统和 Docker 容器之间共享代码库的设置中使用时存在问题,具体如下:
gpg
使用gpg-agent
来执行其任务,这两个工具通过在pgp-agent
的--home-directory
中创建的套接字进行通信。代理通过
git-secret
使用的gpg
命令隐式启动,使用.gitsecret/keys
目录作为--home-directory
。由于
--home-directory
的位置与主机系统共享,因此套接字创建将失败。
对应的错误信息是:
gpg: can't connect to the agent: IPC connect call failed
gpg-agent: error binding socket to '/var/www/app/.gitsecret/keys/S.gpg-agent': I/O error
解决此问题,可以通过将其他 gpg 配置文件放在 .gitsecret/keys
目录中,将 gpg
配置为对套接字使用不同的位置:
S.gpg-agent
%Assuan%
socket=/tmp/S.gpg-agent
s.gpg-agent.ssh
%Assuan%
socket=/tmp/S.gpg-agent
gpg-agent.conf
extra-socket /tmp/S.gpg-agent.extra
browser-socket /tmp/S.gpg-agent.browser
添加、列出和删除用户
要添加新用户,必须首先导入其公用 gpg 密钥。然后运行:
email="pascal.landau@example.com"
git secret tell "$email"
在这种情况下,用户pascal.landau@example.com
现在将能够解密这些密钥。要显示用户请运行:
git secret whoknows$ git secret whoknows
pascal.landau@example.com
要删除用户,请运行:
email="pascal@example.com"
git secret killperson "$email"
这时此命令在 git-secret >= 0.5.0
中已重命名为 removeperson
$ git secret killperson pascal.landau@example.com
git-secret: removed keys.
git-secret: now [pascal.landau@example.com] do not have an access to the repository.
git-secret: make sure to hide the existing secrets again.
用户 pascal@example.com 将无法再解密这些密钥。
注意删除用户后需要重新加密机密,并轮换加密的密钥。
添加、列出和删除文件以进行加密
运行 git secret add [filenames...]
来为文件加密:
git secret add .env
如果 .env
没有被添加到 .gitignore
,git-secret
将显示警告并自动添加。
git-secret: these files are not in .gitignore: .env
git-secret: auto adding them to .env
git-secret: 1 item(s) added.
如已添加,则添加文件时不会发出警告。
$ git secret add .env
git-secret: 1 item(s) added.
只需要添加一次文件。然后将它们存在 .gitsecret/paths/mapping.cfg
:
$ cat .gitsecret/paths/mapping.cfg
.env:505070fc20233cb426eac6a3414399d0f466710c993198b1088e897fdfbbb2d5
还可以通过以下方式显示添加的文件:
git secret list$ git secret list
.env
需要主要的是,这个时候文件尚未加密,如果要从加密中删除文件,请运行:
git secret list$ git secret list
.env
输出:
$ git secret remove .env
git-secret: removed from index.
git-secret: ensure that files: [.env] are now not ignored.
加密文件
要加密文件,请运行:
git secret hide
输出:
$ git secret hide
git-secret: done. 1 of 1 files are hidden.
所有通过 git secret tell
被添加的用户能够解密这些已经加密的文件,这也意味着每当添加新用户时,您都需要再次运行此命令。
解密文件
可以通过以下方式解密文件:
git secret reveal
输出:
$ git secret reveal
File '/var/www/app/.env' exists. Overwrite? (y/N) y
git-secret: done. 1 of 1 files are revealed.
文件被解密并将覆盖当前未加密的文件。
使用
-f
选项强制覆盖并以非交互方式运行。如果只想检查加密文件的内容,可以使用
git secret cat $filename
例如,git secret cat. env
。
当 gpg
密钥受密码保护时,需要通过 -p
选项传递密码。以下是密码示例 123456
:
git secret reveal -p 123456
显示加密和解密文件间的变化
加密文件的一个问题是,无法在远程工具的代码审查期间审查加密文件。为了了解进行了哪些更改,显示加密文件和解密文件之间的更改能够帮助解决这个问题。可以通过以下方式完成:
git secret changes
输出:
$ echo "foo" >> .env
$ git secret changes
git-secret: changes in /var/www/app/.env:
--- /dev/fd/63
+++ /var/www/app/.env
@@ -34,3 +34,4 @@
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
+foo
注意底部的 +foo
. 它是通过在第一行 echo "foo">>>.env
添加的。
本文是git-secret用法的上篇,在下篇中我们将会介绍git-secret的初始设置、Makefile调整等内容,保持关注哦~
git-secret:在 Git 存储库中加密和存储密钥(上)的更多相关文章
- git-secret:在 Git 存储库中加密和存储密钥(下)
在之前的文章中(点击此处查看上一篇文章),我们了解了如何识别包含密钥的文件,将密钥添加到 .gitignore ,通过 git-secret 进行加密,以及将加密文件提交到存储库.在本篇文章中,将带你 ...
- git 从存储库中删除敏感数据(删除文件历史)
1.如果您的历史记录中还没有包含敏感数据的存储库的本地副本,请将存储库克隆到本地计算机. git clone https://github.com/YOUR-USERNAME/YOUR-REPOSIT ...
- 无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支
无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支.发布此分支将导致远程存储库中的分支发生非快进更新. 第一次用oschina的git设置完远程仓库后提交出现 ...
- 【Cocos2d-X开发学习笔记】第29期:游戏中数据的存储(上)
本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一般游戏中都需要记录玩家数据,便于玩家下次登录时 ...
- 本地git部署web连接azure的git存储库
本地git部署web 创建本地存储仓库 输入以下命令创建git本地仓库(会在当前目录下生产一个.git的目录) git init 然后提交内容 在git仓库所在的目录下存放好需要的网页文件 将文 ...
- g4e基础篇#4 了解Git存储库(Repo)
章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git 分布式版本控制系统的优势 Git 安装和设置 了解Git存储库(Repo) 起步 1 – 创建分支和保存代码 起步 2 – 了解Git ...
- git rebase VS git merge? 更优雅的 git 合并方式值得拥有
写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...
- git rebase VS git merge
git rebase VS git merge 写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online(回复公众号「工具」,获取更多内容) , ...
- Git安装/VScode+Git+Github
Git安装/VScode+Git+Github 1. 相关简介 git 版本控制工具,支持该工具的网站有Github.BitBucket.Gitorious.国内的OS China仓库.Csdn仓库等 ...
随机推荐
- Python3.7将普通图片(png)转换为SVG图片格式并且让你的网站Logo(图标)从此”动”起来
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_148 在之前的几篇文章中,介绍了业界中比较火爆的图片技术SVG(Scalable Vector Graphics),比如Iconf ...
- 8月份的.NET Conf 活动 专注于 .NET MAUI
.NET Conf:Focus on MAUI 是一个为期一天的免费直播活动,将于太平洋时间 8 月 9 日上午 9 点开始,来自社区和 Microsoft 团队的演讲者们将分享使用MAUI .了解. ...
- GS2107-WTBD 用什么软件为什么新建不了GS系列
1.GS系列GOT必须使用官网上的新软件,资料下载-软件下载-GOT 1000 & GOT 2000 & GOT Simple 画面设计软件,下载安装后,机种选择GS系列即可. 2.在 ...
- 急如闪电快如风,彩虹女神跃长空,Go语言高性能Web框架Iris项目实战-初始化项目ep00
在Golang Web编程的世界里,君不言高性能则已,言高性能必称Iris.彩虹女神的名号响彻寰宇.名动江湖,单论一个快字,无人能出其右,就连以简洁轻量著称于世的Gin也难以望其项背,只见彩虹女神Ir ...
- 054_末晨曦Vue技术_处理边界情况之组件之间的循环引用
组件之间的循环引用 点击打开视频讲解更详细 假设你需要构建一个文件目录树,像访达或资源管理器那样的.你可能有一个 <tree-folder> 组件,模板是这样的: <p> &l ...
- 【java】学习路径32-绝对路径与相对路径
获取文件路径的时候,我们发现有两个方法,getAbsolutePath和getPath两个方法. 前者是获取绝对路径,后者是相对路径. 绝对路径指的是完整路径,从盘符开始. 相对路径指的是从java当 ...
- 在cmd中使用doskey来实现alias别名功能
作为一枚网络工程师,经常就是面对一堆黑框框,也是就是终端.不同操作系统.不同厂家的目录,功能相同但是键入的命令又大不相同,这些差异化容易让脑子混乱.比如华为.思科.H3C.锐捷的设备, ...
- 输入a、b、c三个整数,按先大后小的顺序输出a、b和c。注意请使用指针变量的方式进行比较和输出。
`void swap(int *a,int *b,int c){ if(a < *b){ int temp = *a; //防止temp没有初始化 随机存放地址指向系统工作区间 可以对temp初 ...
- Sentinel 源码分析-限流原理
1. git clone senetinel 源码到本地,切换到release1.8分支 2. 找到FlowQpsDemo.java, 根据sentinel自带的案例来学习sentinel的原理 3. ...
- Linux 常用脚本命令
Linux 常用(脚本)命令 1. 统计目录下文件个数 ll |grep "^-"|wc -1 解释 grep "^-"表示抓取以-开头的行(其他忽略)