dockersslcurldocker-registry

"docker pull" certificate signed by unknown authority


I was trying to pull a docker image from a docker registry but hit the following issue:

$ docker pull <docker registry>/<image name>/<tag> 
Error response from daemon: Get <docker registry>/v1/_ping: x509: certificate signed by unknown authority

I tried with "curl" and get a similar error message:

 curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.

So I downloaded the CA certificate and imported to the server (RedHat Linux 7) with the following commands:

cp root_cert.cer /etc/pki/ca-trust/source/anchors/
update-ca-trust

After the root cert is imported, I can see curl is working fine as it won't complain the cert error, however if I use docker pull I still have the same issue. Is docker using different ca-cert location than curl? How do I fix the issue with docker pull in this situation?


Solution

  • After updating OS certificates, you typically need to restart the docker service to get it to detect that change. This is usually done with:

    sudo systemctl restart docker
    

    or for non-systemd environments:

    sudo service docker restart
    

    Docker does have an additional location you can use to trust individual registry server CA. You can place the CA cert inside /etc/docker/certs.d/<docker registry>/ca.crt. Include the port number if you specify that in the image tag, e.g in Linux.

    /etc/docker/certs.d/my-registry.example.com:5000/ca.crt
    

    or for snap based installs:

    /var/snap/docker/~current/etc/docker/certs.d/my-registry.example.com:5000/ca.crt
    

    or in Windows 10:

    C:\ProgramData\docker\certs.d\ca.crt
    

    If you don't already have the certificate, you can extract it using openssl. Note that this implicitly trusts whatever the registry currently says their certificate is, exposing you to MitM attacks. This can be useful as a TOFU (trust on first use) if you are not in an ephemeral environment:

    openssl s_client -showcerts -connect my-registry.example.com:5000 < /dev/null \
      | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'