skip to Main Content

My goal is to have a docker registry running on a raspberry pi (behind the rpi hostname), me being able to push images from my linux PC on the same network. I’m following this guide: https://docs.docker.com/registry/insecure/#use-self-signed-certificates

I did the following steps on my rpi:

  1. mkdir -p certs
  2. openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -addext "subjectAltName = DNS:rpi" -x509 -days 365 -out certs/domain.crt
  3. docker run -d --restart=always --name registry -v $HOME/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -p 443:443 registry

Steps on my PC:

  1. scp pi@rpi:certs/domain.crt ca.crt
  2. sudo mkdir -p /etc/docker/certs.d/rpi:5000/
  3. sudo mv ca.crt /etc/docker/certs.d/rpi:5000/

Now, when I try pushing an image docker push rpi:5000/test-image, it fails with the following:
Get "https://rpi:5000/v2/": dialing rpi:5000 with direct connection: connecting to 192.168.1.201:5000: dial tcp 192.168.1.201:5000: connect: connection refused

If I tag the image with the 443 port docker push rpi:443/test-image I get this error: Get "https://rpi:443/v2/": x509: certificate is valid for 227b7008fe5910b8b4b0563bb8ebcb9e.708221ab4c2f3a622587d123822b2328.traefik.default, not rpi

How to push docker images to a remote using self-signed certificates?

2

Answers


  1. Chosen as BEST ANSWER

    Another software running on my raspberry pi (k3s) took over the 443 port.

    docker push first makes a request to https://rpi.home/v2/ and validates the certificate, which is normally served by the registry container. However, if k3s server is running, it serves the /v2 url and provides a completely different certificate.

    The solution was to map a different port to 443 of the container.


  2. It appears that you are listening on port 443. For this to work, you need to change a few things:

    1. Add a domain, even if it’s localdomain, to the hostname on your network. This needs to resolve so make sure you can connect to something like rpi.localdomain. If there’s no domain in the beginning of the image path, and no port (which you don’t need for 443), then it’s treated as a username on Docker Hub.
    2. Rebuild your certificate with that name.
    3. Make sure you store the certificate in that name, not /etc/docker/certs.d/rpi:5000/ but /etc/docker/certs.d/rpi.localdomain/ or whatever the domain name is. Putting it in a directory named 5000 but connecting to 443 means it wasn’t used.
    4. Setup a self signed CA, separate from the key.

    For step 4, here’s an example of my own script for setting up certs:

    certdir="certs"
    cert_host="registry"
    cert_san="DNS:localhost,DNS:$(hostname)"
    for ip in $(ip a | grep inet | awk '{print $2}' | cut -f1 -d/); do
      cert_san="${cert_san},IP:$ip"
    done
    
    if [ ! -d "$certdir" ]; then
      mkdir -p "$certdir"
    fi
    
    # setup a CA key
    if [ ! -f "$certdir/ca-key.pem" ]; then
      openssl genrsa -out "${certdir}/ca-key.pem" 4096
    fi
    
    # setup a CA cert
    openssl req -new -x509 -days 365 
      -subj "/CN=Local CA" 
      -key "${certdir}/ca-key.pem" 
      -sha256 -out "${certdir}/ca.pem"
    
    # setup a host key
    if [ ! -f "${certdir}/key.pem" ]; then
      openssl genrsa -out "${certdir}/key.pem" 2048
    fi
    
    # create a signing request
    extfile="${certdir}/extfile"
    openssl req -subj "/CN=${cert_host}" -new -key "${certdir}/key.pem" 
       -out "${certdir}/${cert_host}.csr"
    echo "subjectAltName = ${cert_san}" >${extfile}
    
    # create the host cert
    openssl x509 -req -days 365 
       -in "${certdir}/${cert_host}.csr" -extfile "${certdir}/extfile" 
       -CA "${certdir}/ca.pem" -CAkey "${certdir}/ca-key.pem" -CAcreateserial 
       -out "${certdir}/cert.pem"
    

    In the above script, the ca.pem is what gets copied to /etc/docker/certs.d/${registry}/ca.crt.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search