Help us learn about your current experience with the documentation. Take the survey.

管道安全

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

密钥管理

密钥管理是开发者用于在具有严格访问控制的安全环境中安全存储敏感数据的系统。密钥是需要保密的敏感凭证。密钥的示例包括:

  • 密码
  • SSH 密钥
  • 访问令牌
  • 任何其他类型的凭证,其泄露会对组织造成危害

密钥存储

密钥管理提供商

最敏感且受最严格策略控制的密钥应存储在密钥管理器中。使用密钥管理器解决方案时,密钥存储在 GitLab 实例之外。该领域有许多提供商,包括 HashiCorp 的 VaultAzure Key VaultGoogle Cloud Secret Manager

您可以使用 GitLab 对某些 外部密钥管理提供商 的原生集成,在需要时在 CI/CD 管道中检索这些密钥。

CI/CD 变量

CI/CD 变量 是在 CI/CD 管道中存储和重用数据的便捷方式,但变量比密钥管理提供商安全性低。变量值:

  • 存储在 GitLab 项目、组或实例设置中。有权访问设置的用户可以访问未 隐藏 的变量值。
  • 可以被 覆盖,难以确定使用了哪个值。
  • 可能因管道配置错误而暴露。

适合存储在变量中的信息应该是可以暴露而不会带来利用风险的数据(非敏感数据)。

敏感数据应存储在密钥管理解决方案中。如果您没有密钥管理解决方案,并且想要将敏感数据存储在 CI/CD 变量中,请务必始终:

向 CI/CD 管道传递参数

向 CI/CD 管道传递参数时,请使用 CI/CD 输入 而不是管道变量。

输入提供:

  • 管道创建时的类型安全验证。
  • 明确的参数契约。
  • 增强安全性的作用域可用性。

在实现输入时,考虑 禁用管道变量 以防止安全漏洞,因为管道变量:

  • 缺乏类型验证。
  • 可以覆盖预定义变量,导致意外行为。
  • 与敏感密钥共享相同的权限范围。

管道完整性

确保管道完整性的关键安全原则包括:

  • 供应链安全:资产应从可信来源获取,并验证其完整性。
  • 可重现性:使用相同输入时,管道应产生一致的结果。
  • 可审计性:所有管道依赖项都应可追溯,并验证其来源。
  • 版本控制:管道依赖项的变更应被跟踪和控制。

Docker 镜像

始终使用 Docker 镜像的 SHA 摘要来确保客户端完整性验证。例如:

  • Node:
    • 使用:image: node@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
    • 而不是:image: node:latest
  • Python:
    • 使用:image: python@sha256:9876543210abcdef9876543210abcdef9876543210abcdef9876543210abcdef
    • 而不是:image: python:3.9

您可以使用以下命令查找具有特定标签的镜像的 SHA 摘要:

docker pull node:18.17.1
docker images --digests node:18.17.1

优先从保护镜像完整性的容器注册表拉取:

在可能的情况下,避免在容器引用中使用变量,因为它们可以被修改以指向恶意镜像。例如:

  • 优先使用:
    • image: my-registry.example.com/node:18.17.1
  • 而不是:
    • image: ${CUSTOM_REGISTRY}/node:latest
    • image: node:${VERSION}

包依赖项

您应该在作业中锁定包依赖项。使用锁文件中定义的精确版本:

  • npm:
    • 使用:npm ci
    • 而不是:npm install
  • yarn:
    • 使用:yarn install --frozen-lockfile
    • 而不是:yarn install
  • Python:
    • 使用:
      • pip install -r requirements.txt --require-hashes
      • pip install -r requirements.lock
    • 而不是:pip install -r requirements.txt
  • Go:
    • 使用 go.sum 中的精确版本:
      • go mod verify
      • go mod download
    • 而不是:go get ./...

例如,在 CI/CD 作业中:

javascript-job:
  script:
    - npm ci

Shell 命令和脚本

在作业中安装工具时,始终指定并验证精确版本。例如,在 Terraform 作业中:

terraform_job:
  script:
    # 下载特定版本
    - |
      wget https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip
      # 重要:始终验证校验和
      echo "c0ed7bc32ee52ae255af9982c8c88a7a4c610485cf1d55feeb037eab75fa082c terraform_1.5.7_linux_amd64.zip" | sha256sum -c
      unzip terraform_1.5.7_linux_amd64.zip
      mv terraform /usr/local/bin/
    # 使用已安装的版本
    - terraform init
    - terraform plan

版本管理工具

尽可能使用版本管理器:

node_build:
  script:
    # 使用 nvm 安装和使用特定的 Node 版本
    - |
      nvm install 16.15.1
      nvm use 16.15.1
    - node --version  # 验证版本
    - npm ci
    - npm run build

包含的配置

在使用 include 关键字 向管道添加配置或 CI/CD 组件时,尽可能使用特定的 ref。例如:

include:
  - project: 'my-group/my-project'
    ref: 8b0c8b318857c8211c15c6643b0894345a238c4e  # 固定到特定提交
    file: '/templates/build.yml'
  - project: 'my-group/security'
    ref: v2.1.0                                    # 固定到受保护的标签
    file: '/templates/scan.yml'
  - component: 'my-group/security-scans'           # 固定到特定版本
    version: '1.2.3'

避免无版本的包含:

include:
  - project: 'my-group/my-project'                   # 不安全
    file: '/templates/build.yml'
  - component: 'my-group/security-scans'             # 不安全
  - remote: 'https://example.com/security-scan.yml'  # 不安全

不要包含远程文件,而是下载文件并将其保存在您的仓库中。然后您可以包含本地副本:

include:
  - local: '/ci/security-scan.yml'  # 已验证并存储在仓库中

相关主题

  1. CIS Docker 基准测试
  2. Google Cloud:设计安全的部署管道