当涉及处理机密信息(如密码、令牌、密钥文件等)等,以下问题值得考虑:

  • 安全性十分重要,但高安全性往往伴随着高度的不便。

  • 在团队中,共享某些密钥有时无法避免(因此现在我们需要考虑在多人之间分发和更新密钥的安全方法)。

  • 具体的密钥通常取决于环境。

目前市面上已经存在许多较为成熟的密钥管理产品,比如 HashiCorp Vault,AWS Secrets Manager 以及 GCP Secret Manager。由于这些产品需要集成和维护等服务,因此在项目中引入会增加一定成本和开销。阅读本文,将带你了解如何在 Docker 容器中设置 git-secretgpg

本文将对以下几点展开讲解:

  • 识别包含密钥的文件

  • 确保将密钥添加到.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 镜像中设置 gpggit-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 没有被添加到 .gitignoregit-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 存储库中加密和存储密钥(上)的更多相关文章

  1. git-secret:在 Git 存储库中加密和存储密钥(下)

    在之前的文章中(点击此处查看上一篇文章),我们了解了如何识别包含密钥的文件,将密钥添加到 .gitignore ,通过 git-secret 进行加密,以及将加密文件提交到存储库.在本篇文章中,将带你 ...

  2. git 从存储库中删除敏感数据(删除文件历史)

    1.如果您的历史记录中还没有包含敏感数据的存储库的本地副本,请将存储库克隆到本地计算机. git clone https://github.com/YOUR-USERNAME/YOUR-REPOSIT ...

  3. 无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支

    无法将分支 master 发布到远程 origin,因为远程存储库中已存在具有同一名称的分支.发布此分支将导致远程存储库中的分支发生非快进更新. 第一次用oschina的git设置完远程仓库后提交出现 ...

  4. 【Cocos2d-X开发学习笔记】第29期:游戏中数据的存储(上)

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一般游戏中都需要记录玩家数据,便于玩家下次登录时 ...

  5. 本地git部署web连接azure的git存储库

    ​​​本地git部署web 创建本地存储仓库 输入以下命令创建git本地仓库(会在当前目录下生产一个.git的目录) git init 然后提交内容 在git仓库所在的目录下存放好需要的网页文件 将文 ...

  6. g4e基础篇#4 了解Git存储库(Repo)

    章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git 分布式版本控制系统的优势 Git 安装和设置 了解Git存储库(Repo) 起步 1 – 创建分支和保存代码 起步 2 – 了解Git ...

  7. git rebase VS git merge? 更优雅的 git 合并方式值得拥有

    写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...

  8. git rebase VS git merge

    git rebase VS git merge 写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online(回复公众号「工具」,获取更多内容) , ...

  9. Git安装/VScode+Git+Github

    Git安装/VScode+Git+Github 1. 相关简介 git 版本控制工具,支持该工具的网站有Github.BitBucket.Gitorious.国内的OS China仓库.Csdn仓库等 ...

随机推荐

  1. 讲透JAVA Stream的collect用法与原理,远比你想象的更强大

    大家好,又见面了. 在我前面的文章<吃透JAVA的Stream流操作,多年实践总结>中呢,对Stream的整体情况进行了细致全面的讲解,也大概介绍了下结果收集器Collectors的常见用 ...

  2. kubernetes 静态存储与动态存储

    静态存储   Kubernetes 同样将操作系统和 Docker 的 Volume 概念延续了下来,并且对其进一步细化.Kubernetes 将 Volume 分为持久化的 PersistentVo ...

  3. .NET的求复杂类型集合的差集、交集、并集

    前言 如标题所述,在ASP.NET应用程序开发中,两个集合做比较时 我们使用微软IEnumerable封装的 Except/Intersect/Union 取 差集/交集/并集 方法是非常的方便的: ...

  4. Vue脚手架(CLI)第一天

    vue 1.脚手架的搭建(CLI) 1.1.下载nodejs,在官网, [nodejs官网地址][ https://nodejs.org/en/ ] 无脑下一步就可以了.环境自动安装 1.2.下载脚手 ...

  5. 解决国内不能访问github的问题

    问题 最近访问GitHub总是不稳定,经常连不上, 出各种错误(OpenSSL SSL_read: Connection was reset, errno 10054, Connection refu ...

  6. BZOJ2286/Luogu2495 [Sdoi2011]消耗战 (虚树)

    // never forget open "Head.cpp", boy, never ! #include <iostream> #include <cstdi ...

  7. MyBatis-Plus 代码生成

    MyBatis-Plus官网的代码生成器配置不是特别全,在此整理了较为完整的配置,供自己和大家查阅学习. // 代码生成器 AutoGenerator mpg = new AutoGenerator( ...

  8. PerfView专题 (第六篇):如何洞察 C# 中 GC 的变化

    一:背景 在洞察 GC 方面,我觉得市面上没有任何一款工具可以和 PerfView 相提并论,这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因,这篇我们先简单聊聊 PerfView 到 ...

  9. Manacher算法讲解——字符串最长回文子串

    引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...

  10. c++基础思维导图2

    c++基础思维导图2 结构体 结构体的基本概念:用户自定义的数据类型 结构体定义和使用 struct 结构体名{结构体成员} struct 结构体名 变量名: struct 结构体名 变量名 = {成 ...