使用 SOPS 管理 Git 仓库中敏感信息的完整教程

引言

在现代软件开发中,敏感信息如数据库连接字符串、API 密钥、令牌等常常需要存储在代码仓库中(如 Git)。直接以明文形式存储这些信息会带来严重的安全风险,例如仓库被泄露时导致数据暴露。为了解决这个问题,我们可以使用 SOPS(Secrets OPerationS)工具来加密这些敏感数据。SOPS 由 Mozilla 开发,目前是 CNCF Sandbox 项目,它支持多种加密后端(如 age、PGP、AWS KMS 等),并允许在本地开发时透明地编辑明文,而仓库中保持加密状态。

本教程将一步步指导你使用 SOPS + age(一种简单、安全的加密工具)来实现:

  • 在 Git 仓库中存储加密的敏感文件(如 YAML/JSON 配置)。
  • 本地开发者透明编辑(看到明文)。
  • 服务器拉取代码后,使用服务器上的密钥解密,并在程序中读取。

这种方案特别适合自托管环境或团队协作,避免了明文泄露,同时集成 GitOps 工具(如 Flux 或 ArgoCD)也很友好。预计完成时间:30-60 分钟。

先决条件

  • 操作系统:Linux、macOS 或 Windows(WSL 推荐)。
  • Git:已安装并配置好仓库。
  • 编辑器:如 VS Code、Vim,支持 YAML/JSON。
  • 基本命令行知识:熟悉 bash 或类似 shell。
  • 示例文件:准备一个敏感配置文件,例如 secrets.yaml
    db:
      url: "mysql://user:pass123@host:3306/mydb"
      password: "verysecret"
    api:
      key: "sk-abcdefghijklmnopqrstuvwxyz"
    
  • 可选:如果使用云服务,可替换 age 为 AWS KMS 等,但本教程聚焦 age。

步骤 1: 安装 SOPS 和 age

  1. 下载 SOPS

    • 访问 GitHub 仓库:https://github.com/getsops/sops/releases
    • 下载最新版本(推荐 v3.8.1 或更高)。例如,对于 Linux AMD64:
      wget https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 -O /usr/local/bin/sops
      chmod +x /usr/local/bin/sops
      
    • macOS:使用 Homebrew brew install sops
    • Windows:下载 .exe 文件并添加到 PATH。
  2. 下载 age

    • 访问 GitHub 仓库:https://github.com/FiloSottile/age/releases
    • 下载最新版本(推荐 v1.2.0 或更高)。例如,对于 Linux:
      wget https://github.com/FiloSottile/age/releases/download/v1.2.0/age-v1.2.0-linux-amd64.tar.gz
      tar xzf age-v1.2.0-linux-amd64.tar.gz
      sudo mv age/age age/age-keygen /usr/local/bin/
      
    • macOS:brew install age
    • Windows:类似下载并配置。
  3. 验证安装

    sops --version
    age --version
    age-keygen --version
    

    输出应显示版本号。

步骤 2: 生成 age 密钥对

age 使用公钥加密、私钥解密。密钥对只需生成一次。

  1. 在安全位置运行:

    age-keygen -o agekeys.txt
    
    • 这会生成一个文件 agekeys.txt,内容类似:
      # created: 2026-01-14T19:00:00+08:00
      # public key: age1ql52nd0j2lhfsda6lxpck0w80pn8n7vx3qlt2cpmegpj4kw67kmq7xxxxx
      AGE-SECRET-KEY-1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      
    • 公钥(以 age1 开头):用于加密,可公开。
    • 私钥(以 AGE-SECRET-KEY- 开头):用于解密,严格保密。
  2. 安全存储密钥

    • 本地开发者:将私钥存入密码管理器(如 1Password、LastPass)。
    • 服务器:将私钥存到受保护文件,如 /etc/age-server.key(权限 chmod 600),或作为环境变量 SOPS_AGE_KEY
    • 警告:切勿将私钥提交到 Git!丢失私钥将导致数据永久不可解密。
  3. 团队协作:如果多人开发,为每个成员生成独立密钥对,并收集公钥(稍后配置)。

步骤 3: 配置 SOPS(创建 .sops.yaml)

在 Git 仓库根目录创建 .sops.yaml 文件,用于定义加密规则。

  1. 编辑 .sops.yaml

    creation_rules:
      - path_regex: \.(yaml|yml|json)$  # 匹配 YAML/JSON 文件
        encrypted_regex: ^(data|stringData|password|token|key|secret|api_key|db_url|pass|credentials)$  # 只加密匹配这些键的 value
        age:
          - recipient: age1ql52nd0j2lhfsda6lxpck0w80pn8n7vx3qlt2cpmegpj4kw67kmq7xxxxx  # 你的公钥
          # - recipient: age1anotherpubkey...  # 加其他成员公钥
    
    • path_regex:指定哪些文件应用规则。
    • encrypted_regex:结构化加密,只加密敏感字段(如 password),而非整个文件。
    • age:列出所有允许加密的公钥。
  2. 提交到 Git:

    git add .sops.yaml
    git commit -m "Add SOPS configuration"
    git push
    

步骤 4: 加密和编辑敏感文件(本地透明操作)

SOPS 允许你像编辑普通文件一样操作,但仓库中自动加密。

  1. 创建新加密文件

    sops secrets.yaml
    
    • SOPS 会打开默认编辑器(可配置为 VS Code:export EDITOR=code --wait)。
    • 输入明文内容,保存退出 → 文件自动加密保存。
    • Git 中查看:cat secrets.yaml 显示加密形式(如 ENC[AES256_GCM,data:xxxx...,iv:...,tag:...,type:str])。
  2. 编辑现有文件

    sops secrets.yaml
    
    • SOPS 先用私钥解密,显示明文 → 编辑 → 保存后重新加密。
    • 透明性:无需手动解密/加密,感觉像普通文件。配置环境变量 SOPS_AGE_KEY_FILE=~/agekeys.txt 后,甚至无需每次输入密码。
  3. 提交到 Git

    git add secrets.yaml
    git commit -m "Add encrypted secrets"
    git push
    
    • 仓库中始终是加密态。
  4. 解密查看(可选)

    sops --decrypt secrets.yaml
    
    • 输出明文,但不修改文件。

步骤 5: 服务器侧部署和解密

服务器拉取代码后,文件是加密的。需要在部署流程中解密。

  1. 安装 SOPS 和 age:服务器上重复步骤 1。

  2. 存储私钥:如 echo "AGE-SECRET-KEY-..." > /etc/age-server.key && chmod 600 /etc/age-server.key

  3. 在部署脚本中解密

    • 简单方式:生成明文文件。

      export SOPS_AGE_KEY_FILE=/etc/age-server.key
      sops --decrypt secrets.yaml > decrypted-secrets.yaml
      
    • 程序读取 decrypted-secrets.yaml

    • 更安全方式(不落地明文):使用 exec-env 注入环境变量。

      export SOPS_AGE_KEY_FILE=/etc/age-server.key
      sops exec-env secrets.yaml 'your-app-command --arg'
      
      • 示例:在 Python 程序中:
        import os
        import mysql.connector
        
        db_url = os.getenv('db__url')  # SOPS 注入的环境变量(双下划线分隔嵌套键)
        db_password = os.getenv('db__password')
        api_key = os.getenv('api__key')
        
        # 连接数据库
        conn = mysql.connector.connect(
            host="host", user="user", password=db_password, database="mydb"
        )
        # 使用 api_key 调用 API
        
      • 运行:sops exec-env secrets.yaml 'python app.py'
  4. 集成 CI/CD:在 Jenkins/Dockerfile 中添加解密步骤,或使用 Kubernetes Secrets Operator。

步骤 6: 团队协作和密钥管理

  1. 添加新成员

    • 为新成员生成 age 密钥对。
    • 将其公钥添加到 .sops.yamlage 列表。
    • 运行 sops updatekeys secrets.yaml 更新所有文件(用新密钥重新加密)。
  2. 撤销访问

    • .sops.yaml 移除公钥。
    • 运行 sops updatekeys secrets.yaml
    • 旧成员无法再解密新版本文件。
  3. 密钥轮换

    • 生成新密钥对。
    • 更新 .sops.yaml
    • sops updatekeys --all 重新加密所有匹配文件。
  4. 备份:定期备份私钥到安全位置(如加密 U 盘)。

注意事项和最佳实践

  • 安全性:始终使用强密钥,避免共享私钥。考虑集成硬件密钥(如 YubiKey)。
  • 性能:SOPS 只加密敏感部分,不会影响大文件。
  • 错误处理:如果解密失败,检查环境变量或密钥文件权限。常见错误:sops: no valid recipients found(公钥不匹配)。
  • 替代后端:如果使用 AWS,替换 age 为 kms: - arn:aws:kms:...(需 AWS CLI 配置)。
  • Git 集成:添加 Git hook(如 pre-commit)确保敏感文件始终加密。
  • 审计:使用 git log 检查历史,确保无明文泄露。
  • 局限性:SOPS 不支持二进制文件加密(如证书),用 age 单独处理。
  • 资源:官方文档 https://github.com/getsops/sops;age 文档 https://age-encryption.org/。

结尾

通过本教程,你已学会使用 SOPS + age 安全管理 Git 仓库中的敏感信息。这种方法平衡了安全性和便利性,适用于从个人项目到企业级应用的各种场景。如果遇到问题,检查日志或社区论坛。欢迎反馈或扩展到其他后端!

posted @ 2026-01-14 20:04  sophomore  阅读(6)  评论(0)    收藏  举报