gitlab ci 如何登录 ssh 到目标机器

gitlab ci 如何 ssh 登录远程的机器

在 GitLab CI 中,如果你需要通过 SSH 登录到目标机器执行命令(例如部署应用、重启服务等),可以通过以下步骤安全地配置 SSH 登录。由于 CI/CD 环境是自动化的,不能手动输入密码,因此需要使用 SSH 密钥进行无密码登录。


✅ 步骤一:生成 SSH 密钥对(用于登录目标机器)

在你的本地机器或 CI 环境中生成一个 SSH 密钥对(建议为 CI 专用):

ssh-keygen -t rsa -b 4096 -C "gitlab-ci@yourdomain.com" -f gitlab-ci-ssh-key

这会生成两个文件:

  • gitlab-ci-ssh-key(私钥)
  • gitlab-ci-ssh-key.pub(公钥)

✅ 步骤二:将公钥添加到目标机器

gitlab-ci-ssh-key.pub 的内容添加到目标机器的 ~/.ssh/authorized_keys 文件中。

例如,登录目标机器并执行:

echo "ssh-rsa AAAAB3NzaC1yc2E... gitlab-ci@yourdomain.com" >> ~/.ssh/authorized_keys

确保目标机器的 SSH 服务正常运行,并允许密钥登录(检查 /etc/ssh/sshd_config 中的 PubkeyAuthentication yes)。


✅ 步骤三:在 GitLab 中添加 SSH 私钥为 CI/CD 变量

  1. 进入你的 GitLab 项目。
  2. 进入 Settings > CI / CD > Variables
  3. 点击 Expand
  4. 添加一个变量:
  • Key: SSH_PRIVATE_KEY(或任意名称)
  • Value: 将 gitlab-ci-ssh-key 文件的内容粘贴进来(注意:不要有额外空格或换行错误)
  • Type: FileVariable(推荐使用 File 类型更安全)
  • ✅ 勾选 Mask variable(如果内容是敏感信息)
  • ❌ 不要勾选 Protect variable 除非你只在 protected branches 上运行

🔐 推荐使用 File 类型
- Key: SSH_PRIVATE_KEY
- Value: 私钥内容(如 -----BEGIN RSA PRIVATE KEY-----\n...
- Type: File
- 这样 GitLab 会自动将其写入文件,路径为 $SSH_PRIVATE_KEY


✅ 步骤四:在 .gitlab-ci.yml 中配置 SSH 登录

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    # 安装 SSH 客户端
    - apk add --update openssh-client git
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh

    # 如果使用 File 类型变量
    - mv $SSH_PRIVATE_KEY ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa

    # 或者如果是普通变量(非 File 类型),使用下面方式写入
    # echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    # chmod 600 ~/.ssh/id_rsa

    # 禁用主机密钥检查(仅用于 CI,注意安全风险)
    - echo -e "Host target-server\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile=/dev/null\n" > ~/.ssh/config
    - chmod 600 ~/.ssh/config

  script:
    # 执行远程命令
    - ssh user@your.target.server.ip "echo 'Hello from remote!' && pwd"
    - ssh user@your.target.server.ip "cd /var/www/myapp && git pull origin main && systemctl restart myapp"

  only:
    - main

✅ 可选优化:使用 SSH Agent

更高级的方式是使用 ssh-agent 来管理密钥,避免直接写入文件。

before_script:
  - apk add --update openssh-client
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
  - ssh-keyscan your.target.server.ip >> ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts

✅ 安全建议

  1. 使用专用密钥:不要使用个人 SSH 密钥。
  2. 限制目标机器权限:SSH 用户应仅拥有必要权限(如只允许执行特定命令)。
  3. 使用堡垒机或跳板机时,可结合 ProxyCommand。
  4. 避免密码登录:CI 中无法交互输入密码。

❌ 常见错误

  • 私钥格式错误(Windows 换行符 \r\n)→ 使用 tr -d '\r' 清理。
  • 权限问题:~/.ssh/id_rsa 必须是 600
  • StrictHostKeyChecking yes 导致连接中断 → 使用 ssh -o StrictHostKeyChecking=no 或配置 ~/.ssh/config
  • 目标机器防火墙或 SSH 服务未开启。

总结

通过将 SSH 私钥作为 GitLab CI 变量注入,并在 CI 脚本中配置 SSH 客户端,即可实现自动登录目标机器。核心是:

  1. 生成密钥对
  2. 公钥放目标机器
  3. 私钥放 GitLab CI 变量
  4. CI 脚本中配置 SSH 并执行命令

这样就能安全、自动化地完成部署或远程操作。

如需更安全方案,可考虑使用 GitLab Deploy TokensAnsible + Vault 等工具集成。