# Using SSH keys with GitLab CI/CD

> 原文：[https://docs.gitlab.com/ee/ci/ssh_keys/README.html](https://docs.gitlab.com/ee/ci/ssh_keys/README.html)

*   [How it works](#how-it-works)
*   [SSH keys when using the Docker executor](#ssh-keys-when-using-the-docker-executor)
*   [SSH keys when using the Shell executor](#ssh-keys-when-using-the-shell-executor)
*   [Verifying the SSH host keys](#verifying-the-ssh-host-keys)
*   [Example project](#example-project)

# Using SSH keys with GitLab CI/CD[](#using-ssh-keys-with-gitlab-cicd "Permalink")

GitLab 当前不支持在构建环境（运行 GitLab Runner 的环境）中管理 SSH 密钥的内置支持.

SSH 密钥在以下情况下很有用：

1.  您想签出内部子模块
2.  您想使用包管理器（例如 Bundler）下载私有包
3.  您想要将应用程序部署到自己的服务器上，例如 Heroku
4.  您要执行从构建环境到远程服务器的 SSH 命令
5.  您想将文件从构建环境同步到远程服务器

如果上述任何事情都响了，那么您很可能需要 SSH 密钥.

支持最广泛的方法是通过扩展`.gitlab-ci.yml`来将 SSH 密钥注入构建环境，该解决方案可与任何类型的[执行器](https://docs.gitlab.com/runner/executors/) （Docker，shell 等）一起使用.

## How it works[](#how-it-works "Permalink")

1.  使用[`ssh-keygen`](https://linux.die.net/man/1/ssh-keygen)在本地创建新的 SSH 密钥对
2.  将私钥作为[变量](../variables/README.html)添加到您的项目中
3.  在作业期间运行[`ssh-agent`](https://linux.die.net/man/1/ssh-agent)以加载私钥.
4.  将公用密钥复制到您要访问的服务器上（通常在`~/.ssh/authorized_keys` ），如果要访问私有的 GitLab 存储库，则将其添加为[部署密钥](../../ssh/README.html#deploy-keys) .

**注意：**除非您启用[调试日志](../variables/README.html#debug-logging)记录，否则私钥将不会显示在作业日志中. 您可能还需要检查[管道](../pipelines/settings.html#visibility-of-pipelines)的[可见性](../pipelines/settings.html#visibility-of-pipelines) .

## SSH keys when using the Docker executor[](#ssh-keys-when-using-the-docker-executor "Permalink")

当您的 CI / CD 作业在 Docker 容器中运行（意味着包含环境）并且您想要在私有服务器中部署代码时，您需要一种访问它的方法. 这是 SSH 密钥对派上用场的地方.

1.  您首先需要创建一个 SSH 密钥对. 有关更多信息，请按照说明[生成 SSH 密钥](../../ssh/README.html#generating-a-new-ssh-key-pair) . **不要**在 SSH 密钥中添加密码，否则`before_script`会提示您输入密码.

2.  创建一个新[变量](../variables/README.html#gitlab-cicd-environment-variables) . 在" **密钥"中**输入名称`SSH_PRIVATE_KEY`然后在" **值"**字段中粘贴先前创建的*私钥*的内容.

3.  使用`before_script`操作修改`.gitlab-ci.yml` . 在以下示例中，假定使用基于 Debian 的图像. 根据需要进行编辑：

    ```
    before_script:
      ##
      ## Install ssh-agent if not already installed, it is required by Docker.
      ## (change apt-get to yum if you use an RPM-based image)
      ##
      - 'which  ssh-agent  ||  (  apt-get  update  -y  &&  apt-get  install  openssh-client  -y  )'

      ##
      ## Run ssh-agent (inside the build environment)
      ##
      - eval $(ssh-agent -s)

      ##
      ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
      ## We're using tr to fix line endings which makes ed25519 keys work
      ## without extra base64 encoding.
      ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
      ##
      - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -

      ##
      ## Create the SSH directory and give it the right permissions
      ##
      - mkdir -p ~/.ssh
      - chmod 700 ~/.ssh

      ##
      ## Optionally, if you will be using any Git commands, set the user name and
      ## and email.
      ##
      #- git config --global user.email "user@example.com"
      #- git config --global user.name "User name" 
    ```

    **注意：** [`before_script`](../yaml/README.html#before_script-and-after_script)可以全局设置或按作业设置.
4.  确保专用服务器的[SSH 主机密钥已验证](#verifying-the-ssh-host-keys) .

5.  作为最后一步，从添加您在第一步，你想拥有从构建环境中的接入服务创建一个*公共*密钥. 如果要访问私有的 GitLab 存储库，则需要将其添加为[部署密钥](../../ssh/README.html#deploy-keys) .

而已！ 现在，您可以在构建环境中访问私有服务器或存储库.

## SSH keys when using the Shell executor[](#ssh-keys-when-using-the-shell-executor "Permalink")

如果您使用的是 Shell 执行程序而不是 Docker，则设置 SSH 密钥会更加容易.

您可以从安装了 GitLab Runner 的计算机生成 SSH 密钥，并将该密钥用于在该计算机上运行的所有项目.

1.  首先，登录到运行您的作业的服务器.

2.  然后，从终端以`gitlab-runner`用户身份登录：

    ```
    sudo su - gitlab-runner 
    ```

3.  按照说明生成 SSH 密钥对，以[生成 SSH 密钥](../../ssh/README.html#generating-a-new-ssh-key-pair) . **不要**在 SSH 密钥中添加密码，否则`before_script`会提示您输入密码.

4.  作为最后一步，加前面创建要具有从构建环境中的接入服务的一个*公共*密钥. 如果要访问私有的 GitLab 存储库，则需要将其添加为[部署密钥](../../ssh/README.html#deploy-keys) .

完成后，尝试登录到远程服务器以接受指纹：

```
ssh example.com 
```

要访问 GitLab.com 上的存储库，可以使用`git@gitlab.com` .

## Verifying the SSH host keys[](#verifying-the-ssh-host-keys "Permalink")

最好检查私有服务器自己的公用密钥，以确保您不会受到中间人攻击的攻击. 万一发生任何可疑事件，您将注意到它，因为作业将失败（如果公钥不匹配，则 SSH 连接将失败）.

要查找服务器的主机密钥，请从受信任的网络（最好是从私有服务器本身）运行`ssh-keyscan`命令：

```
## Use the domain name
ssh-keyscan example.com

## Or use an IP
ssh-keyscan 1.2.3.4 
```

使用`SSH_KNOWN_HOSTS`作为"密钥"创建一个新[变量](../variables/README.html#gitlab-cicd-environment-variables) ，并作为"值"添加`ssh-keyscan`的输出.

**注意：**如果需要连接到多个服务器，则所有服务器主机密钥都需要收集在变量的**Value**中，每行一个密钥.**提示：**通过在`.gitlab-ci.yml`直接使用变量而不是`ssh-keyscan` ，这样做的好处是，如果主机域名由于某种原因而更改，则不必更改`.gitlab-ci.yml` . 而且，这些值是由您预定义的，这意味着如果主机密钥突然更改，CI / CD 作业将失败，并且您将知道服务器或网络出了点问题.

现在已经创建了`SSH_KNOWN_HOSTS`变量，除了上面[`.gitlab-ci.yml`](#ssh-keys-when-using-the-docker-executor)的[内容](#ssh-keys-when-using-the-docker-executor)之外，还需要添加以下内容：

```
before_script:
  ##
  ## Assuming you created the SSH_KNOWN_HOSTS variable, uncomment the
  ## following two lines.
  ##
  - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts

  ##
  ## Alternatively, use ssh-keyscan to scan the keys of your private server.
  ## Replace example.com with your private server's domain name. Repeat that
  ## command if you have more than one server to connect to.
  ##
  #- ssh-keyscan example.com >> ~/.ssh/known_hosts
  #- chmod 644 ~/.ssh/known_hosts

  ##
  ## You can optionally disable host key checking. Be aware that by adding that
  ## you are susceptible to man-in-the-middle attacks.
  ## WARNING: Use this only with the Docker executor, if you use it with shell
  ## you will overwrite your user's SSH config.
  ##
  #- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config' 
```

## Example project[](#example-project "Permalink")

为了方便起见，我们建立了一个[示例 SSH 项目](https://gitlab.com/gitlab-examples/ssh-private-key/) ，使用我们的公共[共享](../runners/README.html)运行程序在[GitLab.com](https://gitlab.com)上运行.

想要破解吗？ 只需对其进行分叉，提交并推送您的更改. 稍后，公共跑步者将选择更改并开始工作.