使用 VAULT 加密的 GITLAB CICD Pipeline
新钛云服已为您服务1486天
目的
在 Vault 上启用 JWT 身份验证方法 利用 JWT 授权从 Vault 中读取密钥以进行 Gitlab CI/CD 作业
背景
什么是 Gitlab?
GitHub 是一项公开可用的免费服务,它要求所有代码(除非您有付费帐户)公开。任何人都可以看到您推送给GitHub的代码并提供改进建议。GitHub目前承载数以万计的开源项目的源代码。
GitLab是一种类似github的服务,组织可以使用它来提供git存储库的内部管理。它是一个自我托管的Git-repository管理系统,可以保持用户代码的私密性,并且可以轻松地部署代码的更改。
什么是HashiCorp Vault?
集中管理各种私密信息; 为私密信息设置租期(Lease),到期后自动失效; 密钥的动态生成、注销和滚动更新; 动态创建无需保存的一次性登录密钥; 作为数据加密/解密接口; 完整的审计记录; 命令行 以及 RESTful API 访问接口;
什么是 CI/CD?
了解 JWT 授权
JWT默认不加密,但可以加密。生成原始令牌后,可以使用改令牌再次对其进行加密。
JWT不仅可用于认证,还可用于信息交换。善用JWT有助于减少服务器请求数据库的次数。
JWT的最大缺点是服务器不保存会话状态,一旦JWT签发,在有效期内将会一直有效。
JWT的有效期不宜设置太长,认证信息,因此一旦信息泄露,任何人都可以获得令牌的所有权限。
为了减少JWT数据盗用和窃取的风险,JWT建议使用加密的HTTPS协议进行传输。
^什么是 JWT,为什么要使用 JWT^
(https://www.youtube.com/watch?v=7Q17ubqLfaM&t=1s)
第 1 步:身份验证/授权
第 2 步:生成 JWT
第 3 步:使用 JWT 进行授权
1. Header: 用于说明签名的加密算法等,下面类型的json经过base64编码后得到JWT头部。
2. Payload: 标准定义了7个字段,载荷json经过base64编码后得到JWT的载荷。
{ iss (issuer):签发人 exp (expiration time):过期时间 sub (subject):主题 aud (audience):受众 nbf (Not Before):生效时间 iat (Issued At):签发时间 jti (JWT ID):编号}
示例:
{ "sub": "1", "iss": "http://localhost:8000/user/sign_up", "iat": 1451888119, "exp": 1454516119, "nbf": 1451888119, "jti": "37c107e4609ddbcc9c096ea5ee76c667"}
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
了解Gitlab + Vault + JWT 授权
第 0 步:创建 Gitlab 项目/存储库
第 1 步:配置 Vault 和密钥
secrets/gitlab/project_1
步骤 2a:设置 Gitlab pipeline
.gitlab-ci.yml
配置。首先,这个文件是在项目 repo 中定义的。虽然此配置可能是各式各样的,但基本内容将如下图所示。首先在变量部分定义vault address、vault secret path和vault role。当 CI/CD 管道被触发时,Gitlab 将生成一个 JWT 作为以下环境变量传递给管道CI_JOB_JWT
。步骤 2b:生成 JWT
第 3 步和第 4 步:向 Vault 进行身份验证 + Vault 验证 JWT
bounder_issuer
以及要提供的 JKWS 端点。bound_issuer
通常被设置为 Gitlab 的 FQDN,以指示 Vault“谁”可以使用此身份验证方法并设置一个指向JKWS端点的URL,从而来指示 Vault“如何”验证 JWT。因此,当 Vault 收到 JWT 请求时,它会确保请求者已被批准使用此身份验证方法,并且可以验证 JWT 的创建者。bound_issuer/iss
字段,通常是来自 JWT payload的 Gitlab 的 FQDN。接下来,Vault 对提取的字段进行查找以获取该字段的 JWKS 端点bound_issuer
。Vault 使用 JKWS 端点验证签名的 JWT payload,以确保 Gitlab 是请求的创建者。gitlab.hackinglab.local
。 正如您将在下面的分步说明中看到的那样,我设置bound_issuer
到gitlab.hackinglab.local
。并且 JWKS 端点设置为jwks_url = "https://gitlab.hackinglab.local/-/jwks"
。iss
应该匹配的字段bound_issuer
提供给Vault。接下来,Vault 将通过将 JWT 签名与位于所提供的 JWKS 端点的签名进行比较来验证 JWT 签名。第 5 步:Vault检测边界声明和附加策略
gitlab-vault-readonly
附加政策,以及bound_claims
定义“谁”的附加参数的部分可以承担这个角色。bound_claims
部分指出必须满足以下标准:只有 Gitlab project/repo project_id为2可以担任此角色,并且仅构建一个 CI/CD 管道master主可以承担这个角色。bound_claims
符合此标准,则可以担任此角色。最后,假设JWT包含此角色的必要条件,Vault将生成一个令牌。此Vault令牌将被授予担任此角色的能力。第 6 步和第 7 步:Vault 返回令牌 + Gitlab runner从 Vault 读取密钥
READ
和 LIST
权限:secrets/gitlab/project_1
。那么这是什么意思?假设 Gitlab runner正在尝试读取以下密钥:secrets/gitlab/project_1/password
,根据策略,它可以读取该密钥。secrets/mysql_db/super_secret_db_passwrd
,根据策略,它没有读取该密钥的权限。前提条件
为每个服务生成 DNS A 记录
现有的 Gitlab 基础环境
至少有一个 Gitlab runner
预先部署好的 Vault服务
创建一个 Gitlab 存储库
登录到 Gitlab
选择左上角的“项目”
选择“创建空白项目”
进入Vault Gitlab作为项目名称
选择“创建项目” 选择左上角的“项目概览”
记录项目ID
设置Vault
启用 JWT 身份验证
使用 CLI 工具登录 Vault
curl -s -k -X GET https://gitlab.<base_domain>: 8443 ///jwks
测试 Gitlab JWT 身份验证
以管理员身份通过 CLI 登录 Vault
echo | openssl s_client -connect gitlab.<base_domain>:<port> 2 >& 1 | sed - ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/gitlab.crt
如果 Gitlab 由自签名证书提供服务,请下拉证书 vault auth enable jwt
vault write auth/jwt/config jwks_url= "https://gitlab.<base_domain>:<port>/-/jwks" bound_issuer= "gitlab.<base_domain>" jwks_ca_pem= "$( cat /tmp/gitlab.crt) "
Vault read auth/jwt/config
测试 Vault JWT 身份验证
创建密钥
vault secrets enable -version=2 -path=secrets kv
启用Vault服务vault kv put secrets/<secret path> <secret_key>=<secret_value>
vault kv get secrets/gitlab/project_1
取回密码
设置 Vault 以提供 Gitlab 对密钥的访问权限
Vault Policy
cd GitlabVaultCICD
进入相关目录cp conf/vault/policies/gitlab-vault-policy.hcl.example conf/vault/policies/gitlab-vault-policy.hcl
vim conf/vault/policies/gitlab-vault-policy.hcl
并设置:{{ vault_secret_path }}
将此设置为密钥所在的 Vault 路径vault policy write <policy name> conf/vault/policies/gitlab-vault-policy.hcl
示例策略名称: gitlab-vault-readonly
Vault role
登录到 Gitlab
浏览到您要授予对 Vault 机密访问权限的 Gitlab 存储库
选择左上角的“项目概览”
获取项目 ID cp conf/vault/roles/gitlab-jwt-role.json.example conf/vault/roles/gitlab-jwt-role.json
vim conf/vault/roles/gitlab-jwt-role.json
并设置:{{ gitlab_project_id }}
– 将此设置为项目 ID上面的图显示了project_id 为 2
{{ gitlab_vault_role }}
上一节中 Vault 策略的名称 – 使用
gitlab-vault-readonly
cat conf/vault/roles/gitlab-jwt-role.json | vault write auth/jwt/role/gitlab-vault-readonly -
.gitlab-ci.yml - 获取 Vault 密钥
登录到 Gitlab
浏览到您要授予对 Vault 机密访问权限的 Gitlab 存储库
选择左上角的“项目概览”
选择“新建文件”
VAULT_ADDR
– 设置为 Vault 的 HTTP URL 地址{{vault_search_path}}
– 设置为上面创建的 Vault 密钥路径{{gitlab_vault_role}}
– 设置为上面为 Gitlab 创建的 Vault 角色保存并退出
进入 .gitlab-ci.yml
作为文件名复制内容 conf/gitlab/gitlab-ci-example.yml.example
进入.gitlab-ci.yml并设置:选择左侧的 CI/CD > 管道 选择最新的管道作业 选择Vault_secrets stage
总结:
HashiCorp Vault
是一个密钥管理工具。与 Git 相比,Vault 的核心功能是以本机方式来处理机密信息的。所以对于配置密钥信息来说,使用 Vault 作为 Config Server 的后端存储,是一种更好的选择。了解 JWT 授权的工作原理
了解授权和认证的区别
如何从 Vault 为 Gitlab CI/CD 管道请求密钥
如何设置 Vault JWT 身份验证方法
如何创建一个 .gitlab-ci.yml配置
参考:
在 docker-compose 替换 NGINX 配置中的环境变量(https://stackoverflow.com/questions/56649582/substitute-environment-variables-in-nginx-config-from-docker-compose) 在 GNU/Linux 上手动安装 GitLab Runner(https://docs.gitlab.com/runner/install/linux-manually.html) 在 Windows 10 上安装 Hyper-V(https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) 使用 openssl 从服务器获取证书(http://using%20openssl%20to%20get%20the%20certificate%20from%20a%20server/) Vaults – JWT/OIDC 身份验证方法(https://www.vaultproject.io/docs/auth/jwt) Youtube – HashiCorp Vault GitLab 集成:为什么以及如何?(https://www.youtube.com/watch?v=VmQZwfgp3aA) Youtube – 什么是 JWT,为什么要使用 JWT(https://www.youtube.com/watch?v=7Q17ubqLfaM&t=2s)
了解新钛云服
新钛云服荣膺第四届FMCG零售消费品行业CIO年会「年度数字化服务最值得信赖品牌奖」
新钛云服三周岁,公司月营收超600万元,定下百年新钛的发展目标
当IPFS遇见云服务|新钛云服与冰河分布式实验室达成战略协议
新钛云服正式获批工信部ISP/IDC(含互联网资源协作)牌照
新钛云服,打造最专业的Cloud MSP+,做企业业务和云之间的桥梁
往期技术干货
刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读!
OpenStack与ZStack深度对比:架构、部署、计算存储与网络、运维监控等
点👇分享
戳👇在看
微信扫码关注该文公众号作者