简体   繁体   中英

How to make Drone Docker Plugin use self-signed certs?

I'm facing the same problem as here - I have set up a private Docker Registry with TLS certification (certificates generated via Certbot ), and I can interact with it directly via curl etc. (thus proving that the certificate is correct), but the Docker Plugin in my Drone flow gives an error x509: certificate signed by unknown authority .

As per this StackOverflow answer , I believe that putting the certificate at /etc/docker/certs.d/<my_registry_address:port>/ca.crt should fix this problem, but it doesn't appear to (neither does adding the certificate into the standard /etc/ssl/certs/ca-certificates.crt location)

Demonstration that the certificates work as-expected, having already built the Docker Drone Plugin locally as per https://github.com/drone-plugins/drone-docker :

$ docker run --rm -v <path_to_directory_containing_pems>:/custom-certs -it --entrypoint /bin/sh plugins/docker
/ # ls /custom-certs
accounts       archive        csr            keys           live           renewal        renewal-hooks
/ # apk add curl
...
OK: 28 MiB in 56 packages
/ # curl https://docker-registry.scubbo.org:8843/v2/_catalog
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
/ # curl https://docker-registry.scubbo.org:8843/v2/_catalog --cacert /custom-certs/live/docker-registry.scubbo.org/fullchain.pem
{"repositories":[...]}
/ # cat /custom-certs/live/docker-registry.scubbo.org/fullchain.pem >> /etc/ssl/certs/ca-certificates.crt
/ # curl https://docker-registry.scubbo.org:8843/v2/_catalog
{"repositories":[...]}

Here's my .drone.yml , for a Runner instantiated with --env=DRONE_RUNNER_VOLUMES=/var/run/docker.sock:/var/run/docker.sock,<path_to_directory_containing_pems>:/custom-certs :

kind: pipeline
name: hello-world
type: docker

platform:
  os: linux
  arch: arm64

steps:
  - name: copy-cert-into-place
    image: busybox
    volumes:
      - name: docker-cert-persistence
        path: /etc/docker/certs.d/
    commands:
      # https://stackoverflow.com/a/56410355/1040915
      # Note that we need to mount the whole `custom-certs` directory into the workflow and then copy the file to `/etc/...`,
      # rather than mounting the file directly into `/etc/...`, because the original file is a symlink and it's not possible (AFAIK)
      # to instruct Docker to "mount the eventual-target-of this symlink into <location>"
      - mkdir -p /etc/docker/certs.d/docker-registry.scubbo.org:8843
      - cp -L /custom-certs/live/docker-registry.scubbo.org/fullchain.pem /etc/docker/certs.d/docker-registry.scubbo.org:8843/ca.crt
  - name: check-cert-persists-between-stages
    image: alpine
    volumes:
      - name: docker-cert-persistence
        path: /etc/docker/certs.d/
    commands:
      - apk add curl
      # The command below would fail if the cert was unavailable or invalid
      - curl https://docker-registry.scubbo.org:8843/v2/_catalog --cacert /etc/docker/certs.d/docker-registry.scubbo.org:8843/ca.crt
  - name: build-image
    # ...contents irrelevant to this question...
  - name: push-built-image
    image: plugins/docker
    volumes:
      - name: docker-cert-persistence
        path: /etc/docker/certs.d/
    settings:
      repo: docker-registry.scubbo.org:8843/scubbo/blog_nginx
      tags: built_in_ci
      debug: true
      launch_debug: true
volumes:
  - name: docker-cert-persistence
    temp: {}

giving these logs from push-built-image step - ending in...

+ /usr/local/bin/docker tag 472d41d9c03ee60fe9c1965ad9cfd36a1cdb6cbf docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci

+ /usr/local/bin/docker push docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci

The push refers to repository [docker-registry.scubbo.org:8843/scubbo/blog_nginx]

Get "https://docker-registry.scubbo.org:8843/v2/": x509: certificate signed by unknown authority

exit status 1

How should I go about providing the CA Certificate to my Drone Docker Plugin step to permit it to communicate over TLS with a secure Docker registry? This answer suggests simply reverting to insecure integration, which works but is unsatisfactory.


EDIT: After re-reading this documentation , I extended the copy-cert-into-place commands to copy all 3 certificate-related files:

    commands:
      - mkdir -p /etc/docker/certs.d/docker-registry.scubbo.org:8843
      - cp -L /custom-certs/live/docker-registry.scubbo.org/fullchain.pem /etc/docker/certs.d/docker-registry.scubbo.org:8843/ca.crt
      - cp -L /custom-certs/live/docker-registry.scubbo.org/privkey.pem /etc/docker/certs.d/docker-registry.scubbo.org:8843/client.key
      - cp -L /custom-certs/live/docker-registry.scubbo.org/cert.pem /etc/docker/certs.d/docker-registry.scubbo.org:8843/client.cert

but that did not resolve the problem - same x509: certificate signed by unknown authority error.


EDIT2: I directly confirmed (directly on a host, outside the context of a plugin or docker container) that adding the certificate to the path used above is sufficient to permit interaction with the registry:

$ docker pull docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci
Error response from daemon: Get "https://docker-registry.scubbo.org:8843/v2/": x509: certificate signed by unknown authority
$ sudo cp -L <path_to_directory_containing_pems>/live/docker-registry.scubbo.org/chain.pem /etc/docker/certs.d/docker-registry.scubbo.org\:8843/ca.crt
$ docker pull docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci
built_in_ci: Pulling from scubbo/blog_nginx
Digest: sha256:3a17f86f23050303d94443f24318b49fb1a5e2d0cc9228270678c8aa55b4d2c2
Status: Image is up to date for docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci
docker-registry.scubbo.org:8843/scubbo/blog_nginx:built_in_ci

This isn't a complete answer, but I was able to get secure registry access working by switching from mounting a directory, to mounting the file directly:

  • I changed the docker run option to --env=DRONE_RUNNER_VOLUMES=/var/run/docker.sock:/var/run/docker.sock,$(readlink -f <path_to_directory_containing_pems>/live/docker-registry.scubbo.org/chain.pem):/registry_cert.crt
  • I changed the commands in copy-cert-into-place to:
 - mkdir -p /etc/docker/certs.d/docker-registry.scubbo.org:8843
 - cp /registry_cert.crt /etc/docker/certs.d/docker-registry.scubbo.org:8843/ca.crt

I don't consider this a complete answer (and would love further input or advice!), because:

  • I don't know why copying the file out of the mounted directory into /etc/docker/... (as in the original question) didn't work, but mounting the file directly from the host filesystem worked. (Note that the check-cert-persists-between-stages stage confirms that the certificate is correct, so it's not a mistake of copying a wrong or empty file)
  • I don't know how to mount the file directly into an in-stage path that contains a colon - this answer indicates how to mount a path containing a colon directly into a container, but in this case we're passing the path to DRONE_RUNNER_VOLUMES

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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