简体   繁体   English

无密码 SSH 从 GitLab CI 到远程服务器

[英]Passwordless SSH from GitLab CI to Remote Server

Just recently I stumbled on an SSH issue that I cannot figure out what is missing.就在最近,我偶然发现了一个 SSH 问题,我无法弄清楚缺少什么。 We use GitLab CI to build and deploy the project to one of our remote servers.我们使用 GitLab CI 构建项目并将其部署到我们的远程服务器之一。 As a part of the upgrade plan, we need to replace the degrading Debian 6 server with a new RHEL 7 server.作为升级计划的一部分,我们需要用新的 RHEL 7 服务器替换性能下降的 Debian 6 服务器。 I cannot get the passwordless SSH to work right from GitLab Runner to a remote machine.我无法让无密码 SSH 从 GitLab Runner 到远程机器正常工作。

I created a reproducible example in a Dockerfile , the IP of the remote server and the user is replaced with non-sensitive data.我在Dockerfile中创建了一个可重现的示例,远程服务器的 IP 和用户被替换为非敏感数据。

FROM centos:7
RUN yum install -y epel-release
RUN yum update -y
RUN yum install -y openssh-clients
RUN useradd -m joe
RUN mkdir -p /home/joe/.ssh
COPY id_rsa_shared /home/joe/.ssh/id_rsa
RUN echo "Host *\n\tStrictHostKeyChecking no\n" >> /home/joe/.ssh/config
RUN ssh-keyscan 10.x.x.x >> /home/joe/.ssh/known_hosts
RUN chown -R joe:joe /home/joe/.ssh
USER joe
CMD ["/bin/bash"]

The file id_rsa_shared is created on local machine with the following command:使用以下命令在本地计算机上创建文件id_rsa_shared

ssh-keygen -t rsa -b 2048 -f./id_rsa_shared

ssh-copy-id -i./id_rsa_shared joe@10.xxx

This works on local .这适用于本地. A simple ssh joe@10.xxx uname -a in the docker container will output the following:一个简单的ssh joe@10.xxx uname -a在 docker 容器中将 output 以下内容:

Linux newweb01p.company.local 3.10.0-1160.25.1.el7.x86_64 #1 SMP Tue Apr 13 18:55:45 EDT 2021 x86_64 x86_64 x86_64 GNU/Linux

However , if I commit this to a branch as GitLab CI script, as shown:但是,如果我将其作为 GitLab CI 脚本提交到一个分支,如下所示:

image: centos:7

stages:
  - deploy

dev-www:
  stage: deploy
  tags:
    - docker
  environment:
    name: dev-www
    url: http://dev-www.company.local
    variables:
      DEV_HOST: 10.x.x.x
      APP_ENV: dev
      DEV_USER: joe
  script:
    - whoami
    - yum install -y epel-release
    - yum update -y
    - yum install -y openssh-clients
    - useradd -m joe
    - mkdir -p /home/joe/.ssh
    - cp "./gitlab/known_hosts" /home/joe/.ssh/known_hosts
    - echo "$DEV_USER_OPENSSH_KEY" >> /home/joe/.ssh/id_rsa
    - echo "Host *\n\tStrictHostKeyChecking no\n" >> /home/joe/.ssh/config
    - chown -R joe:joe /home/joe/.ssh/
    - chmod 600 /home/joe/.ssh/*
    - chmod 700 /home/joe/.ssh
    - ls -Fsal /home/joe/.ssh
    - su - joe
    - ssh -oStrictHostKeyChecking=no "${DEV_USER}@${DEV_HOST}" uname -a
  when: manual

The pipeline will fail authentication as shown:管道将无法通过身份验证,如下所示:

Running with gitlab-runner 13.12.0 (7a6612da)
    on docker.hqgitrunner01d.company.local K47w1s77
Preparing the "docker" executor
Using Docker executor with image centos:7 ...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image centos:7 ...
Using docker image sha256:xxx for centos:7 with digest centos:7@sha256:xxxx ...
Preparing environment
Running on runner-k47w1s77-project-93-concurrent-0 via hqgitrunner01d.company.local...
Getting source from Git repository
Fetching changes...
Reinitialized existing Git repository in /builds/webversion3/API/.git/
Checking out 6a7c193b as tdr/psr4-composer...

Updating/initializing submodules recursively...
Executing "step_script" stage of the job script
Using docker image sha256:xxx for centos:7 with digest centos:7@sha256:xxx ...
$ whoami
root
$ useradd -m joe
$ mkdir -p /home/joe/.ssh
$ cp "./gitlab/known_hosts" /home/joe/.ssh/known_hosts
$ echo "$DEV_USER_OPENSSH_KEY" >> /home/joe/.ssh/id_rsa
$ echo "Host *\n\tStrictHostKeyChecking no\n" >> /home/joe/.ssh/config
$ chown -R joe:joe /home/joe/.ssh/*
$ chmod 600 /home/joe/.ssh/*
$ chmod 700 /home/joe/.ssh
$ ls -Fsal /home/joe/.ssh
total 16
0 drwx------ 2 root root  53  Apr  1 15:19 ./
0 drwx------ 3 joe  joe   74  Apr  1 15:19 ../
4 -rw------- 1 joe  joe   37  Apr  1 15:19 config
4 -rw------- 1 joe  joe 3414  Apr  1 15:19 id_rsa
8 -rw------- 1 joe  joe 6241  Apr  1 15:19 known_hosts
$ su - joe
$ ssh -oStrictHostKeyChecking=no "${DEV_USER}@${DEV_HOST}" uname -a
Warning: Permanently added '10.x.x.x' (ECDSA) to the list of known hosts.
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

Cleaning up file based variables
ERROR: Job failed: exit code 1

Maybe there's a step I missed because I get a 'Permission denied, please try again' message.也许我错过了一个步骤,因为我收到“权限被拒绝,请重试”消息。 How do I get Docker Executor to use passwordless SSH to a remote server?如何让 Docker Executor 将无密码 SSH 用于远程服务器?

The solution was really simple, and straightforward.解决方案非常简单明了。 The important part is understanding SSH.重要的部分是理解 SSH。

The solution works.该解决方案有效。 A snippet from the .gitlab-ci.yml for those who has the same problem as I do. .gitlab-ci.yml中的一个片段,适用于那些和我有同样问题的人。

    ...
    - mkdir -p ~/.ssh
    - touch ~/.ssh/id_rsa ~/.ssh/config ~/.ssh/known_hosts
    - chmod 600 ~/.ssh/id_rsa ~/.ssh/config ~/.ssh/known_hosts
    - echo "$OPENSSH_KEY" >> ~/.ssh/id_rsa
    - echo "Host *\n\tStrictHostKeyChecking no" >> ~/.ssh/config
    - ssh-keyscan ${DEV_HOST} >> ~/.ssh/known_hosts

Just inline all your ssh options.只需内联所有 ssh 选项。 Use -i to specify your key file.使用-i指定您的密钥文件。 You can also use -o UserKnownHostsFile to specify your known hosts file -- you don't need to copy all that it into an ssh configuration.您还可以使用-o UserKnownHostsFile来指定您的已知主机文件——您不需要将其全部复制到 ssh 配置中。

This should be enough to ssh successfully:这应该足以 ssh 成功:

# ...
- echo "$DEV_USER_OPENSSH_KEY" > "${CI_PROJECT_DIR}/id_rsa.key"
- chmod 600 "${CI_PROJECT_DIR}/id_rsa.key"
- |
  ssh -i "${CI_PROJECT_DIR}/id_rsa.key" \
      -o IdentitiesOnly=yes \
      -o UserKnownHostsFile="${CI_PROJECT_DIR}/gitlab/known_hosts" \
      -o StrictHostKeyChecking=no \
      user@host ...

Also, since you're disabling StrictHostKeyChecking, you can also just use /dev/null for your UserKnownHostsFile .此外,由于您要禁用 StrictHostKeyChecking,因此您也可以只对UserKnownHostsFile使用/dev/null If you want key checking, omit the StrictHostKeyChecking=no option.如果您想要密钥检查,请省略StrictHostKeyChecking=no选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM