简体   繁体   English

如何在Docker中使用GitLab Runner查看自定义CA根证书

[英]How to make GitLab Runner in Docker see a custom CA Root certificate

I have installed and configured: 我已安装并配置:

  1. an on-premises GitLab Omnibus on ServerA running on HTTPS 在HTTPS上运行的ServerA上的本地GitLab Omnibus
  2. an on-premises GitLab-Runner installed as Docker Service in ServerB ServerB中作为Docker Service安装的本地GitLab-Runner

ServerA certificate is generated by a custom CA Root ServerA证书由自定义CA Root生成

The Configuration 配置

I've have put the CA Root Certificate on ServerB: 我已将CA根证书放在ServerB上:

/srv/gitlab-runner/config/certs/ca.crt

Installed the Runner on ServerB as described in Run GitLab Runner in a container - Docker image installation and configuration : 按照容器中的Run GitLab Runner中的描述在ServerB上安装Runner - Docker镜像安装和配置

docker run -d --name gitlab-runner --restart always \
           -v /srv/gitlab-runner/config:/etc/gitlab-runner \
           -v /var/run/docker.sock:/var/run/docker.sock \
           gitlab/gitlab-runner:latest

Registered the Runner as described in Registering Runners - One-line registration command : 注册跑步者 - 单行注册命令中所述注册跑步者

docker run --rm -t -i 
            -v /srv/gitlab-runner/config:/etc/gitlab-runner 
           --name gitlab-docker-runner gitlab/gitlab-runner register \
           --non-interactive \
           --executor "docker" \
           --docker-image alpine:latest \
           --url "https://MY_PRIVATE_REPO_URL_HERE/" \
           --registration-token "MY_PRIVATE_TOKEN_HERE" \
           --description "MyDockerServer-Runner" \
           --tag-list "TAG_1,TAG_2,TAG_3" \
           --run-untagged \
           --locked="false"

This command gave the following output: 此命令提供以下输出:

Updating CA certificates... 更新CA证书...
Runtime platform arch=amd64 os=linux pid=5 revision=cf91d5e1 version=11.4.2 运行时平台arch = amd64 os = linux pid = 5 revision = cf91d5e1 version = 11.4.2
Running in system-mode. 在系统模式下运行。

Registering runner... succeeded runner=8UtcUXCY 注册跑步者...成功的跑步者= 8UtcUXCY
Runner registered successfully. 跑步者注册成功。 Feel free to start it, but if it's running already the config should be automatically reloaded! 随意启动它,但如果它已经运行,配置应该自动重新加载!

I checked with 我查了一下

$ docker exec -it gitlab-runner bash 

and once in the container with 和一次在容器中

$ awk -v cmd='openssl x509 -noout -subject' '
/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt

and the custom CA root is correctly there . 并且自定义CA根目录正确

The Problem 问题

When running Gitlab-Runner from GitLab-CI, the pipeline fails miserably telling me that: 从GitLab-CI运行Gitlab-Runner时,管道失败告诉我:

$ git clone https://gitlab-ci-token:${CI_BUILD_TOKEN}@ServerA/foo/bar/My-Project.wiki.git $ git clone https:// gitlab-ci-token:$ {CI_BUILD_TOKEN} @ ServerA / foo / bar / My-Project.wiki.git


Cloning into 'My-Project.wiki'... 克隆到'My-Project.wiki'......


fatal: unable to access ' https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@ServerA/foo/bar/My-Project.wiki.git/ ': server certificate verification failed. 致命:无法访问' https:// gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@ServerA/foo/bar/My-Project.wiki.git/ ': 服务器证书验证失败。 CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none CAfile:/etc/ssl/certs/ca-certificates.crt CRLfile:none


ERROR: Job failed: exit code 1 错误:作业失败:退出代码1

It does not recognize the Issuer (my custom CA Root), but according to The self-signed certificates or custom Certification Authorities , point n.1, it should out-of-the-box: 它无法识别Issuer(我的自定义CA Root),但根据自签名证书或自定义证书颁发机构 ,点n.1,它应该是开箱即用的:

Default: GitLab Runner reads system certificate store and verifies the GitLab server against the CA's stored in system . 默认值: GitLab Runner读取系统证书存储,并根据存储在系统中的CA验证GitLab服务器

I've then tried the solution from point n.3, editing 然后,我从第n.3点开始尝试解决方案,编辑

/srv/gitlab-runner/config/config.toml:

and adding: 并添加:

[[runners]]
tls-ca-file = "/srv/gitlab-runner/config/certs/ca.crt"

But it still doesn't work. 但它仍然无效。

How can I make Gitlab Runner read the CA Root certificate? 如何让Gitlab Runner读取CA Root证书?

You have two options: 您有两种选择:

Ignore SSL verification 忽略SSL验证

Put this at the top of your .gitlab-ci.yml : 把它放在.gitlab-ci.yml的顶部:

variables:
  GIT_SSL_NO_VERIFY: "1"

Point GitLab-Runner to the proper certificate 将GitLab-Runner指向正确的证书

As outlined in the official documentation , you can use the tls-*-file options to setup your certificate, eg: 官方文档中所述,您可以使用tls - * - file选项设置证书,例如:

[[runners]]
  ...
  tls-ca-file = "/etc/gitlab-runner/ssl/ca-bundle.crt"
  [runners.docker]
  ...

As the documentation states, "this file will be read every time when runner tries to access the GitLab server." 正如文档所述,“每当跑步者试图访问GitLab服务器时,都会读取此文件。”

Other options include tls-cert-file to define the certificate to be used if needed. 其他选项包括tls-cert-file用于定义在需要时使用的证书。

While I've still not got why it doesn't work out-of-the-box, I've found the Egg of Columbus : 虽然我还没有拿到过,为什么它不工作外的开箱, 我发现哥伦布的蛋

Gitlab-Runner configuration: Gitlab-Runner配置:

[[runners]]
  name = "MyDockerServer-Runner"
  url = "https://MY_PRIVATE_REPO_URL_HERE/"
  token = "MY_TOKEN_HERE"
  executor = "docker"
  ...
  [runners.docker]
    image = "ubuntu:latest"

  # The trick is the following:
    volumes = ["/cache","/srv/gitlab-runner/config:/etc/gitlab-runner"]
    ...

Gitlab-ci.yml pipeline: Gitlab-ci.yml管道:

MyJob:
    image: ubuntu:latest

    script:
      - awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt
      - git clone https://gitlab-ci-token:${CI_BUILD_TOKEN}@ServerA/foo/bar/My-Project.wiki.git
      - wget -O foo.png https://ServerA/foo/bar/foo.png 

    before_script:
      - apt-get update -y >/dev/null
      - apt-get install -y apt-utils dialog >/dev/null
      - apt-get install -y git >/dev/null
      - apt-get install -y wget >/dev/null

    # The trick is the following:
      - cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt
      - update-ca-certificates

That's it: 而已:

  • Mount the volume once (per Docker executor ) 安装卷一次(每个Docker执行器
  • Update the CA certificates once (per job ) 一次更新CA证书(每个作业

And everything will work as expected : git clone , wget https , etc... 一切都会按预期工作git clonewget https等...

A great workaround, until someone at GitLab will fix it or explain me where I'm wrong (be my guest!) 一个很好的解决方法,直到有人在GitLab修复它或解释我错在哪里(做我的客人!)

Not sure it's the best approach, but at least it worked for me. 不确定这是最好的方法,但至少它对我有用。 You can create a customized gitlab runner image and add your root CA inside: 您可以创建一个自定义的gitlab runner图像并在其中添加根CA:

├── Dockerfile
└── myca.crt
# Dockerfile
FROM gitlab/gitlab-runner:latest
COPY myca.crt /usr/local/share/ca-certificates
RUN update-ca-certificates

Build it: 建立它:

docker build -t custom-gitlab-runner .

And rerun all your commands, just remember to use this new image name. 并重新运行所有命令,只需记住使用此新图像名称。

Off-topic , but related and might be useful 偏离主题 ,但相关,可能有用

Dockerized gitlab-runner seem to also ignore entries in your /etc/hosts , so if you have launched Gitlab on a custom domain, eg https://gitlab.local.net , you need to pass the values from /etc/hosts when launching/registering gitlab runner: Dockerized gitlab-runner似乎也忽略了/etc/hosts条目,所以如果你在自定义域上启动Gitlab,例如https://gitlab.local.net ,你需要从/etc/hosts传递值。启动/注册gitlab runner:

docker run -d --name gitlab-runner --restart always \
       --add-host="gitlab.local.net:192.168.1.100" \
       ...

If you want to launch docker:dind (docker in docker service) container to build docker images, you also need to set these values inside /srv/gitlab-runner/config/config.toml : 如果你想启动docker:dinddocker:dind service in docker:dind service)容器来构建docker镜像,你还需要在/srv/gitlab-runner/config/config.toml设置这些值:

[[runners]]
  url = "https://gitlab.local.net/"
  executor = "docker"
  pre_clone_script = "echo '192.168.1.100 gitlab.local.net registry.local.net' >> /etc/hosts"
  ...

From the output you provided i think that the certificate might be OK but you are lacking the CRL file : server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none 从您提供的输出我认为证书可能没问题,但您缺少CRL文件: server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

The CRL file is used to verify that even if the certificate is valid is hasn't been revoked by the CA owner. CRL文件用于验证即使证书有效,CA所有者也未撤消该文件。 You shoudl then need to : 然后你需要:

1) Generate a CRL file based on your CA: 1)根据您的CA生成CRL文件:

openssl ca -gencrl -keyfile ca.key -cert ca.crt -out crl.pem

source: https://blog.didierstevens.com/2013/05/08/howto-make-your-own-cert-and-revocation-list-with-openssl/ 来源: https//blog.didierstevens.com/2013/05/08/howto-make-your-own-cert-and-revocation-list-with-openssl/

2) Instruct the runner to use it : 2)指导跑步者使用它:

[[runners]]
  ...
  tls-ca-file = "/etc/gitlab-runner/ssl/ca-bundle.crt"
  crl-file = "/etc/gitlab-runner/ssl/ca.crl"

3) Of course setting GIT_SSL_NO_VERIFY will work but you will be more sensitive to man-in-the-middle attacks 3)当然设置GIT_SSL_NO_VERIFY会起作用,但你会对中间人攻击更敏感

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

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