Docker self signed registry segítség

 ( zamek | 2019. január 23., szerda - 19:29 )

Sziasztok,

Egy docker registry-t szeretnék beüzemelni self signed certificate-tel. A lépéseket a docker oldala alapján csináltam:


#!/bin/sh
fqdn=xxx.hu
ip=nn.mm.xx.zz
#creating CA (ca-key.pem)
openssl genrsa -aes256 -out ca-key.pem 4096
#creating CA (ca.pem)
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
#creating server key (server-key.pem)
openssl genrsa -out server-key.pem 4096
#createing cert signing request (server.csr)
openssl req -subj "/CN=${fqdn}" -sha256 -new -key server-key.pem -out server.csr
#sign public key with CA (server-cert.pem)
echo subjectAltName = DNS:${fqdn},IP:${ip},IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
#create client key (key.pem)
openssl genrsa -out key.pem 4096
#create certificate signing request (client.csr)
openssl req -subj '/CN=client' -new -key key.pem -out client.csr

Ezután a doksi alapján a docker daemon-nal meg kellene etetni a certificate-et:

 dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H=0.0.0.0:2376

Mivel nekem registry kell nem ezt kellene használnom, hanem a docker registry-t kellene indítani:

docker run -d \
  --restart=always \
  --name registry \
  -v /srv/registry/security:/certs \
  -v /srv/registry/data:/var/lib/registry \
  -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem \
  -e REGISTRY_HTTP_TLS_KEY=/certs/server-key.pem \
  -p 5000:5000 \
  registry:2

Ez persze egy másik doksiból származik de csak két file-t kér. Ha elindítom és kérek egy logot, akkor azt mondja, hogy:
private key does not match public key

mit rontok el?

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem
De mindenhol server-cert.pem-et emlitesz.

Masreszt meg nezz ra erre, ha meg van prod kiserletezni: https://docs.docker.com/registry/recipes/nginx/
En kiszerveznem az SSL vegzodtetest a helyedben.

Igen, ettol kapok agyf*t, hogy minden doksiban mas fileneveket hasznalnak

"En kiszerveznem az SSL vegzodtetest a helyedben."

Ezt hogy erted?

nginx vegzodteti az SSL/HTTPS kapcsolatot, a registry localhoston figyel csak es ide proxyzza tovabb az nginx a bejovo kereseket.
Ami a link.

ok, de meg akkor az nginx-et is fel kell installni, ujabb szivas:(

Lehet, de arról fogsz találni csillió jó leírást, ellentétben ezzel a szarral.
Továbbmegyek: user authentikációt tök véletlenül nem akarsz? El van zárva az egész egy belső lanra, és nem fáj, hogy bárki bármit feltölthet?
Mert user authentikációt sem tudsz a docker registryben csinálni, ha nem fizetsz elő a pénzes verzióra. És akkor megintcsak kelleni fog valami eléje.

siman lehetett csinalni, egyszeru htpasswd-t de tud tobbfelet is.

config.yml:

version: 0.1
storage:
  filesystem:
    rootdirectory: /data/registry_data
  delete:
    enabled: true
http:
  addr: :5000
  net: tcp
  secret: asecretforlocaldevelopment
  tls:
      certificate: /certs/fqdn.crt
      key: /certs/fqdn.key
auth:
  htpasswd:
    realm: basic‑realm
    path: /etc/registry/registry_passwd

Mondjuk ettől még kliens oldalon bele kell majd még verni, hogy elfogadja a self signed certet a docker. Tapasztalataim szerint az is felér egy kisebb szopással.

letsencrypt erre a megoldás

főleg mióta ad wildcard certet :)

nem olyan nagy szopas, leszamitva, hogy a /etc/docker/certs/fqdn:port cimu konyvtarba be kell masolni a cert file-t, ca.crt neven.

ha gitlab-on generalod a docker-t, akkor igy nez ki:


image: docker:latest

cache:
  paths:
    - .m2/repository
    - target

services:
  - name: docker:dind
    command: ["--insecure-registry=fqdn:port"]

variables:
  DOCKER_DRIVER: overlay
  SPRING_PROFILES_ACTIVE: gitlab-ci

stages:
  - build
  - package
  
maven-build:
  image: maven:3-jdk-8
  stage: build
  script: 
    - "mvn package -B -DskipTests=true"
  artifacts:
    name: "jar"
    paths:
      - target/*.jar

docker-build:
  stage: package
  script:
    - docker login -u user -p *** fqdn:port
    - docker build -t fqdn:port/project .
    - docker push fqdn:port/project      

Évekkel ezelőtt játszottam vele, akkor a --insecure-registry nem annyira szerette a systemds rendszereket, mert... Nem teljesen emlékszem már, miért is.

Egyszerűbb (s valszeg olcsóbb is) volt venni egy certet, mint mindenkinél felconfigni, meg az egyedi dolgokra megoldásokat keresni.

igen, csakhogy az a gep amit hasznalok nincs nevesitve, igy a lets'encrypt szoba sem all vele, es nem sok eselyem van bejegyezni.
Ha mar itt tartunk, mi kell ahhoz, hogy a lets'encrypt elfogadja? A DNS-ben kell nevesiteni?

a) opció: a bejegyzendő névhez beraksz egy A rekordot a DNS-be, ami a gép kívülről elérhető IP címére mutat, a gépen pedig fut egy HTTP szerver - aminek a rootjába tudsz lerakni fájlt scriptből (http challenge)
b) opció: a bejegyzendő névhez scriptből tudsz TXT rekordot a DNS-be berakni - ekkor nem is kell kívülről elérhető HTTP szerver (dns challenge)

Koszi, sikerult, most hogy kitokoltem a self signed cert hasznalatat :) Nem baj, megvan ez is meg az is.

Asszem azóta lets encrypt oszt wildcard certet, szóval egy fokkal egyszerűbb a docker.foobar.hu ssl

kiprobaltam server-cert.pem-et ugyanaz: private key does not match public key

Ellenőrizted, hogy jó helyen vannak a fájlok? Esetleg jogosultság probléma?
/srv/registry/security/server-cert.pem
/srv/registry/security/server-key.pem

Érdemes biztosra menni és nézd meg a modulus-t, hogy tuti a kulcs és a cert egyezik, valamint így egyből kiderül hogy kér-e jelszót a kulcs véletlen:
# kulcs modulus:
openssl rsa -in server-key.pem -modulus -noout
# cert modulus:
openssl x509 -in server-cert.pem -modulus -noout

mind a kettő parancs eredményénél azonos Modulus=értéket kell kapnod, ha különbözik akkor valahol valami hiba történt és a kulcs nincs kapcsolatba az adott cert-el (pl véletlen újat generáltál stb).

Előfordulhat az is, hogy a -----BEGIN CERTIFICATE----- előtti sorokba van némi emberi olvasásra alkalmas szöveges rész, amitől egyes programok meghülyülnek... így érdemes "kitisztítani", hátha amiatt nem tudja betölteni a cert-et ugyan így a kulcs esetén is.

Illetve még egy ötlet, hogy előfordul hogy nem server-cert hanem server-with-cahain-cert kell. Azaz
cat server-cert.pem ca.pam > server-with-cachain-cert.pem

Üdv:
Csabka

Koszi, ez jo otlet volt, a modulus bizony teljesen mas :(
Nekifutok megegyszer...

Megoldodott, talaltam egy scriptet, ami persze megint mas filenevekkel operalt, de kimazsolaztam:

create-certs.sh

#!/usr/bin/env bash

# Installs/Configures:
#  - Docker
#  - Docker Registy Container with self-signed cert
#
# Tested on Ubuntu 14.04.1

# Must be executed with elevated privilages
if [ "$(id -u)" != "0" ]; then
  printf "This script must be ran as root or sudo!\n"
  exit 1
fi

# collect required information
# - C   Country
# - ST  State
# - L    Location
# - O    Organization
# - OU   Organizational Unit
# - CN   Common Name

BITS=2048
DAYS=365
COUNTRY=XX
STATE=XX
LOCATION=XXX
ORGANIZATION=XXX
OUNIT=XXX
COMMON=xxx.xxx.xx

# ... Certs ...
# ~~~~~~~~~~~~~
# ... prep certs ...
echo -e "\nGenerating certs ..."
mkdir certs
cd certs
# Generate a root key
openssl genrsa -out rootCA.key ${BITS}

# Generate a root certificate
openssl req -x509 -new -nodes -key rootCA.key -days ${DAYS}\
    -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${ORGANIZATION}/CN=${COMMON}" \
    -out rootCA.crt

# Generate key for host
openssl genrsa -out ${COMMON}.key ${BITS}

# Generate CSR
openssl req -new -key ${COMMON}.key \
    -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${ORGANIZATION}/CN=${COMMON}" \
    -out ${COMMON}.csr

# Sign certificate request
openssl x509 -req -in ${COMMON}.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -days ${DAYS} \
    -out ${COMMON}.crt

mkdir /usr/local/share/ca-certificates/${COMMON}
cp rootCA.crt /usr/local/share/ca-certificates/${COMMON}
update-ca-certificates

mkdir -p /etc/docker/certs.d/${COMMON}
cp rootCA.crt /etc/docker/certs.d/${COMMON}/ca.crt

# add ${COMMON} to /etc/hosts
echo -e "\nAdding ${COMMON} to /etc/hosts ..."
if [ ! `cat /etc/hosts | grep -o "${COMMON}"` ]; then
    echo "127.0.0.1 ${COMMON}" >> /etc/hosts
fi

# Restart Docker to pick up our certs
echo -e "\nRestarting Docker daemon ..."
sudo service docker restart

start-docker.sh

#!/bin/sh

HOST_PORT=nnnn
COMMON=xxx.xxx.xxx

docker run -d -p ${HOST_PORT}:5000 --restart=always --name registry -v `pwd`/certs:/certs \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/${COMMON}.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/${COMMON}.key \
    registry:2


create-client.sh

#!/bin/sh

COMMON=xxx.xxx.xxx

mkdir -p client

cp certs/rootCA.crt  client/ca.pem
cp certs/${COMMON}.crt  client/cert.pem
openssl genrsa -out client/key.pem 4096

cd client
tar -cvzf client.tgz *
cd ..

On the client machine:
- Add ${COMMON} entry to /etc/hosts with correct IP of server (if needed)
- Create cert directory
~ sudo mkdir -p /etc/docker/certs.d/${COMMON}:${PORT}

- Copy and rename the 'rootCA.crt' file (on the server in the certs directory) into the directory you ju
st created on the client:
- Full path on client: /etc/docker/certs.d/${COMMON}:${PORT}/ca.crt
- Restart the Docker daemon to pick up the cert - REQUIRED!!!