Jak chyba prawie każdy, kto pracuje przy procesach jako DevOps posiadam homelab. Jakieś tam mikrotiki, jakieś proxmoxy, kubernetesy, usługi chmurowe… wszystko spięte sieciami VPN. Taki ot standard.

Czego zawsze brakuje w fajnym homelab? A przynajmniej u mnie tego długo nie było, głównie z racji braku czasu, szczypty lenistwa… fajnego scentralizowanego PKI dla całego środowiska homelab. Mam vault pki, ale zarządzanie nim i przygotowanie wszystkich skryptów, które pozwalają na tworzenie cert chain dla różnych usług np. nginx, cert-manager, certy dla oprogramowania - sporo tego jest.

Pomyślałem, kurde, letsencrypt ma już 10 lat (jak ten czas leci, bo pamiętam moje pierwsze integracje z letsencryptem) i może warto by pójść tą drogą. ACME to już generalnie standard, autoryzacja via DNS, wszystko zautomatyzowane, bo większość oprogramowania ma wbudowanego klienta ACME, mamy certbot, mamy całą masę implementacji.

Poszperałem i znalazłem bardzo fajną usługę step-ca, instalacja jest banalnie prosta. Można wykorzystać cały ekosystem smallstep, jednak na moje potrzeby chciałem tylko ACME. Choć ich ekosystem to naprawdę ciekawe rozwiązanie, więc zachęcam do lektury Core concepts

No dobra, tyle słowem wstępu. Deko mięcha.

    flowchart

  subgraph PUBLIC["Mój HQ"]
    VPN[Headscale Server]
    DNS[(Headscale DNS<br/>*.para.net)]:::dns
    DNS --- VPN
  end

  subgraph LAB["Homelab"]
    subgraph MYSZKA["Serwer zarządzający<br/>(systemd/docker)"]
        SVC1[Usługi zarządcze / dashboard]
        SVC2[Inne serwisy self-hosted]
        STEPCA["Serwer step-ca"]
    end

    subgraph PMX["Serwer Proxmox"]
      subgraph VMS["VM-ki na Proxmox"]
        GL[VM: GitLab]:::vm
        GR[VM: GitLab Runner]:::vm
        K8S[VM: Kubernetes]:::vm
      end
    end
  end

  VPN <--> MYSZKA
  VPN <--> PMX
  VPN <--> GL
  VPN <--> GR
  VPN <--> K8S
  VPN <--> STEPCA

  STEPCA ==>|ACME/letsencrypt<br/>crt: gitlab.para.net| GL
  STEPCA ==>|ACME/cert-manager<br/>crt: k8s.para.net| K8S

  DNS ==> SVC1
  DNS ==> SVC2

  STEPCA ==> |ACME/certbot<br/>crt: yyy.para.net| SVC1
  STEPCA ==> |ACME/certbot<br/>crt: xxx.para.net| SVC2
  

Tak poglądowo wygląda infrastruktura rozwiązania. Realnie jest teko więcej, ale dla wizualizacji wystarczy.

Na serwerze zarządzającym mam postawionego Debiana, więc instalacja step-ca to zwyczajnie

apt-get update && apt-get install -y --no-install-recommends curl vim gpg ca-certificates
curl -fsSL https://packages.smallstep.com/keys/apt/repo-signing-key.gpg -o /etc/apt/trusted.gpg.d/smallstep.asc && \
    echo 'deb [signed-by=/etc/apt/trusted.gpg.d/smallstep.asc] https://packages.smallstep.com/stable/debian debs main' \
    | tee /etc/apt/sources.list.d/smallstep.list
apt-get update && apt-get -y install step-cli step-ca

Odsyłam na stronę producenta - Step-ca installation

Po instalacji uruchamiamy inicjalizację usługi, u mnie deko odpuściłem security, z racji laba i uroszczenia sobie tematu, oczywiście nie jest to koszerne, ale w labie czasami sobie folguję. :)

Z użytkownika root (choć lepiej to uruchomić na jakimś dedykowanym pod usługę)

step ca init \
  --name "Lab CA" \
  --dns "ca.para.net" \
  --address ":9000" \
  --provisioner "admin" \
  --deployment-type standalone \
  --password-file <(echo "SuperDuperHasło")

Ta komenda stworzy nam strukturę plików i katalogów w /root/.step/ znajdziecie tam, konfigurację, klucze, bazy etc…

Teraz service dla systemd /etc/systemd/system/step-ca.service:

[Unit]
Description=Smallstep CA for para.net
After=network.target

[Service]
User=root
Group=root
ExecStart=/usr/bin/step-ca --password-file /root/.step/secrets/password.txt /root/.step/config/ca.json
WorkingDirectory=/root/.step
Restart=on-failure
AmbientCapabilities=CAP_NET_BIND_SERVICE
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

w pliku /root/.step/secrets/password.txt odkładamy nasze hasło, które podaliśmy przy init

sudo systemctl daemon-reload
sudo systemctl enable --now step-ca
sudo systemctl status step-ca

Po instalacji nasz serwer step-ca nie posiada jeszcze provisionera acme, więc dodajemy:

step ca provisioner add acme --type ACME

Nasz root CA znajdziecie na https://ca.para.net:9000/roots.pem, przygotowałem na szybko install-root-ca.sh, który pozwala na szybką instalację root certyfikatu dla systemów debianowych i redhatowych.

To generalnie tyle w temacie instalacji, teraz przykład użycia dla certbot:

certbot --nginx \
  -d homepage.para.net \
  --server "https://ca.para.net:9000/acme/acme/directory" \
  --agree-tos -m admin@para.net --non-interactive

Przykładowo dla cert-managera:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: acme
  namespace: cert-manager
spec:
  acme:
    server: https://ca.para.net:9000/acme/acme/directory
    email: admin@para.net
    privateKeySecretRef:
      name: acme

Polecam się pobawić i mieć w pełni zautomatyzowany system zarządzania certyfikatami w przestrzeni homelab.