当波及解决机密信息(如明码、令牌、密钥文件等)等,以下问题值得思考:

  • 安全性非常重要,但高安全性往往随同着高度的不便。
  • 在团队中,共享某些密钥有时无奈防止(因而当初咱们须要思考在多人之间散发和更新密钥的平安办法)。
  • 具体的密钥通常取决于环境。

目前市面上曾经存在许多较为成熟的密钥治理产品,比方 HashiCorp Vault,AWS Secrets Manager 以及 GCP Secret Manager。因为这些产品须要集成和保护等服务,因而在我的项目中引入会减少肯定老本和开销。浏览本文,将带你理解如何在 Docker 容器中设置 git-secretgpg

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

  • 辨认蕴含密钥的文件
  • 确保将密钥增加到 .gitignore
  • 通过 git-secret 进行加密
  • 将加密文件提交到存储库

在最初咱们将可能调用:

make secret-decrypt

这将会披露代码库中的密钥,在必要时对其进行批改,而后运行:

make secret-encrypt

须要再次加密密钥,以便提交(并推送到近程存储库),要查看实际效果请运行以下命令:

# checkout the branchgit checkout part-6-git-secret-encrypt-repository-docker# build and start the docker setupmake make-initmake docker-buildmake 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 gpgmake gpg-init# ensure that the decrypted secret file does not existls passwords.txt# decrypt the secret filemake secret-decrypt# show the content of the secret filecat 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="[email protected]"gpg --batch --gen-key <<EOFKey-Type: 1Key-Length: 2048Subkey-Type: 1Subkey-Length: 2048Name-Real: $nameName-Email: $emailExpire-Date: 0%no-protectionEOF

%no-protection 创立一个没有明码的key。

输入:

$ name="Pascal Landau"$ email="[email protected]"$ 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> EOFgpg: key E1E734E00B611C26 marked as ultimately trustedgpg: revocation certificate stored as '/root/.gnupg/opengpg-revocs.d/74082D81525723F5BF5B2099E1E734E00B611C26.rev'

也能够在没有 --batch 标记的状况下以交互方式疏导整个过程运行gpg --gen-key,而后导出、列出和导入公有 gpg Key,能够通过以下形式导出:

email="[email protected]"path="secret.gpg"gpg --output "$path" --armor --export-secret-key "$email"

记住不能共享此密钥。

-----BEGIN PGP PRIVATE KEY BLOCK-----lQOYBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejvG21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339XDPO3Rys+CmnZchcEgnbOfQlEqo51DMj6mRF2Ra/6svh7lqhrixGx1BaKn6VlHkC...ncIcHxNZt7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZxT3SieoBPd+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]      74082D81525723F5BF5B2099E1E734E00B611C26uid [ultimate] Pascal Landau <[email protected]>ssb rsa2048 2022-03-27 [SEA]

能够通过以下形式导入私钥:

path="secret.gpg"gpg --import "$path"

失去以下输入:

$ path="secret.gpg"$ gpg --import "$path"gpg: key E1E734E00B611C26: "Pascal Landau <[email protected]>" not changedgpg: key E1E734E00B611C26: secret key importedgpg: Total number processed: 1gpg: unchanged: 1gpg: secret keys read: 1gpg: 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="[email protected]"path="public.gpg"gpg --armor --export "$email" > "$path"

导出如下:

-----BEGIN PGP PUBLIC KEY BLOCK-----mQENBF7VVBwBCADo9un+SySu/InHSkPDpFVKuZXg/s4BbZmqFtYjvUUSoRAeSejvG21nwttQGut+F+GdpDJL6W4pmLS31Kxpt6LCAxhID+PRYiJQ4k3inJfeUx7Ws339...3LLbK7Qxz0cV12K7B+n2ei466QAYXo03a7WlsPWn0JTFCsHoCOphjaVsncIcHxNZt7eK644nWDn7j52HsRi+wcWsZ9mjkUgZLtyMPJNB5qlKQ18QgVdEAhuZxT3SieoBPd+tZikhu3BqyIifmLnxOJOjOIhbQrgFiblvzU1iOUOTOcSIB+7A=g0hF-----END PGP PUBLIC KEY BLOCK-----

通过以下形式列出所有公钥:

gpg --list-keys

输入:

$ gpg --list-keys/root/.gnupg/pubring.kbx------------------------pub rsa2048 2022-03-27 [SCEA]      74082D81525723F5BF5B2099E1E734E00B611C26uid [ultimate] Pascal Landau <[email protected]>sub rsa2048 2022-03-27 [SEA]

通过以下形式以与私钥雷同的形式导入公钥:

path="public.gpg"gpg --import "$path"

例如:

$ gpg --import /var/www/app/public.gpggpg: key E1E734E00B611C26: "Pascal Landau <[email protected]>" not changedgpg: Total number processed: 1gpg: unchanged: 1

git-secret

git-secret的官方网站能够找到具体介绍该工具的内容。git-secret容许将某些文件申明为“secret”并通过 gpg 加密。而后能够将加密的文件间接平安地存储在 Git 存储库中,并在须要时进行解密。本文应用 git-secret v0.4.0

$ git secret --version0.4.0

git-secret 装置

Alpine 的装置阐明如下:

sh -c "echo 'https://gitsecret.jfrog.io/artifactory/git-secret-apk/all/main'" >> /etc/apk/repositorieswget -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#alpineADD https://gitsecret.jfrog.io/artifactory/api/security/keypair/public/repositories/git-secret-apk /etc/apk/keys/git-secret-apk.rsa.pubRUN 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 initgit-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-agentEOFtee .gitsecret/keys/S.gpg-agent.ssh <<EOF%Assuan%socket=/tmp/S.gpg-agent.sshEOFtee .gitsecret/keys/gpg-agent.conf <<EOFextra-socket /tmp/S.gpg-agent.extrabrowser-socket /tmp/S.gpg-agent.browserEOF

这一步很必要,因为 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 failedgpg-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.extrabrowser-socket /tmp/S.gpg-agent.browser

增加、列出和删除用户

要增加新用户,必须首先导入其专用 gpg 密钥。而后运行:

email="[email protected]"git secret tell "$email"

在这种状况下,用户 [email protected] 当初将可能解密这些密钥。要显示用户请运行:

git secret whoknows$ git secret whoknows[email protected]

要删除用户,请运行:

email="[email protected]"git secret killperson "$email"

这时此命令在 git-secret >= 0.5.0 中已重命名为 removeperson

$ git secret killperson [email protected]git-secret: removed keys.git-secret: now [[email protected]] do not have an access to the repository.git-secret: make sure to hide the existing secrets again.

用户 [email protected] 将无奈再解密这些密钥。

留神删除用户后须要从新加密秘密,并轮换加密的密钥。

增加、列出和删除文件以进行加密

运行 git secret add [filenames...] 来为文件加密:

git secret add .env

如果 .env 没有被增加到 .gitignoregit-secret 将显示正告并主动增加。

git-secret: these files are not in .gitignore: .envgit-secret: auto adding them to .envgit-secret: 1 item(s) added.

如已增加,则增加文件时不会收回正告。

$ git secret add .envgit-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 .envgit-secret: removed from index.git-secret: ensure that files: [.env] are now not ignored.

加密文件

要加密文件,请运行:

git secret hide

输入:

$ git secret hidegit-secret: done. 1 of 1 files are hidden.

所有通过 git secret tell 被增加的用户可能解密这些曾经加密的文件,这也意味着每当增加新用户时,您都须要再次运行此命令。

解密文件

能够通过以下形式解密文件:

git secret reveal

输入:

$ git secret revealFile '/var/www/app/.env' exists. Overwrite? (y/N) ygit-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 changesgit-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调整等内容,放弃关注哦~