# 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)上运行. 想要破解吗? 只需对其进行分叉,提交并推送您的更改. 稍后,公共跑步者将选择更改并开始工作.