在 CI/CD 流程中,SSH 密钥的安全使用取决于具体场景:是用于拉取代码仓库,还是用于登录远程服务器部署。最稳妥的做法是将私钥存进平台的加密变量(Secrets),配合专用密钥限制权限,严禁硬编码。

先说结论:区分“仓库访问”与“服务器部署”两种场景,私钥存入 CI/CD 平台 Secrets,公钥配置到对应目标端。

  • 场景判断:拉取代码用 Git 平台 Deploy Key,部署服务器用服务器 SSH 密钥。
  • 核心操作:生成独立密钥对,私钥加密存储,流水线动态加载。
  • 安全底线:私钥权限 600,目录 700,禁止日志打印,定期轮换。

场景区分:仓库访问 vs 服务器部署

配置前必须明确密钥用途,两者配置位置完全不同:

  • 场景 A:拉取私有代码仓库
    用途:CI/CD 流水线需要克隆私有仓库或子模块。
    配置位置:Git 平台(GitHub/GitLab)的 Deploy Keys 设置。
    权限:通常只读,若需推送需开启写权限(有限制)。
  • 场景 B:部署到远程服务器
    用途:流水线构建完成后,通过 SSH 登录生产/测试服务器执行脚本。
    配置位置:目标服务器的 ~/.ssh/authorized_keys
    权限:仅限特定用户登录,建议配合 sudo 限制命令。

第一步:生成专用密钥

不要使用默认的 id_rsa,生成专门用于 CI/CD 的密钥。Ed25519 算法比传统 RSA 更安全高效。

ssh-keygen -t ed25519 -C "ci-deploy-key" -f ~/.ssh/id_ed25519_deploy

生成后得到两个文件:id_ed25519_deploy(私钥)和 id_ed25519_deploy.pub(公钥)。

第二步:配置公钥(分场景)

场景 A:Git 平台 Deploy Key

  • GitHub:进入仓库 Settings > Deploy keys > Add deploy key,粘贴公钥内容。若需推送代码,勾选 "Allow write access"。
  • GitLab:进入 Settings > Repository > Deploy Keys,粘贴公钥。注意部署密钥触发的 Pipeline 权限可能受限。

场景 B:远程服务器登录

将公钥内容追加到目标服务器对应用户的 ~/.ssh/authorized_keys 文件中:

cat id_ed25519_deploy.pub | ssh user@remote_host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

第三步:CI/CD 配置示例

1. GitHub Actions 配置

在仓库 Settings > Secrets and variables > Actions 中新建 Secret,名为 SSH_PRIVATE_KEY,内容为私钥文件全文。

name: Deploy via SSH
on: [push]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup SSH
        uses: webfactory/ssh-agent@v0.5.3
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: Verify Connection
        run: ssh -o StrictHostKeyChecking=no user@remote_host "echo 'Connected'"

2. GitLab CI 配置

在 Settings > CI/CD > Variables 中新建变量 SSH_PRIVATE_KEY(类型 File 或 Variable,建议 masked)。

before_script:
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
  # 注意:生产环境建议预先已知主机指纹,避免中间人攻击
  - ssh-keyscan -H remote_host >> ~/.ssh/known_hosts

script:
  - ssh user@remote_host "cd /var/www && git pull"

第四步:验证与排查

验证方法:

在流水线中添加测试步骤,确认免密连接成功且无密码提示。

  • 仓库访问:ssh -T git@github.com 或 git ls-remote git@gitlab.com:namespace/repo.git
  • 服务器部署:ssh -i ~/.ssh/id_ed25519_deploy user@remote_host "echo ok"

常见错误排查:

  • Permission denied (publickey):检查私钥权限是否为 600(chmod 600 key),目录是否为 700。
  • Known hosts 验证失败:首次连接未知主机可能被拒绝,需提前扫描或关闭严格检查(StrictHostKeyChecking=no,仅限内网)。
  • 换行符错误:存入 Secrets 时私钥换行符可能丢失,脚本中建议使用 tr -d '\r' 处理。
  • 密钥泄露风险:确保 CI/CD 平台开启了变量屏蔽(Masked),切勿在脚本中 echo 私钥内容。

安全最佳实践

  • 最小权限原则:Deploy Key 默认只读,仅必要时开启写权限。服务器密钥建议限制 authorized_keys 命令选项(如 command="...")。
  • 密钥轮换:建议每 6-12 个月轮换一次密钥,旧密钥失效前更新 CI/CD 变量。
  • 避免中间人攻击:生产环境尽量避免使用 StrictHostKeyChecking=no,建议将已知主机指纹硬编码到仓库或配置中。

来源 https://www.zjcp.cc/ask/11199.html

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐