Ga naar inhoud

Een nieuw service publiceren op *.savethemall.eu

Machinevertaling van het Franse origineel.

Volledige procedure om een service te publiceren onder een publiek domein, beschermd door Authentik. Reken op ongeveer 30 minuten, waarvan het grootste deel nodig is voor de DNS-propagatie.

In de volgende stappen, vervang monservice door het gewenste subdomein en monservice:8080 door de naam van de Compose-service en de poort.

Wat de procedure veronderstelt

  • De container draait en reageert via HTTP op infrastructure_network.
  • Controle: vanaf vm-docker, docker exec caddy wget -qO- http://monservice:8080/ | head -5. Als deze opdracht niets oplevert, stop dan hier: niets anders in de volgende stappen zal een stilstaande upstream compenseren.

De volgorde, en waarom dit niet onderhandelbaar is

flowchart TB
    A["1 · Record A chez OVH"]
    B["2 · Certificat acme.sh<br/>validation DNS-01"]
    C["3 · Provider + application<br/>Authentik"]
    D["4 · Bloc Caddy vm-docker"]
    E["5 · Bloc Caddy nas-caddy"]
    F["6 · Secrets, s'il y en a"]
    G["7 · decisions.md, commit"]

    A -->|"sans le record,<br/>la validation DNS-01 échoue"| B
    B -->|"sans le cert, `caddy validate`<br/>refuse et le reload COUPE<br/>les 76 autres sites"| D
    C -->|"l'app doit exister,<br/>sinon 404 au lieu de 302"| D
    D -->|"le cert doit être copié<br/>sur le NAS"| E
    E --> G
    F --> G

    B -.->|"rsync quotidien<br/>ou déclenché à la main"| E

    classDef risk stroke-width:3px
    class D risk

De enige stap die andere stappen kan beïnvloeden is stap 4: Caddy van vm-docker heeft 76 vhosts, en een herlaad op een ongeldige configuratie kan alle lagen beïnvloeden. Daarom is caddy validate en restart cruciaal, en het certificaat voor het blok.


1. DNS-registratie bij OVH

Altijd als eerste. acme.sh valideert de DNS-01: zonder registratie, mislukt de uitgifte van het certificaat, en het falen lijkt een probleem met de credentials.

ssh -p <port-ssh> <user>@vm-docker \
  "sudo /docker-mounts/homelab-vault/00-infra/scripts/ovh-record.sh \
     add savethemall.eu A monservice <IP publique> --apply"

Controle

dig +short monservice.savethemall.eu @1.1.1.1
# attendu : <IP publique>

Vooral niet de lokale resolver: de interne DNS reageert al op deze naam, en zou een valse bevestiging geven.

En ook niet de autoritatieve servers van OVH — ns.ovh.net en dns1.ovh.net reageren niet op directe verzoeken vanaf dit netwerk (gemeten op 2026-08-29 vanaf vm-claude en vanaf het VPS: communications error … timed out). Een publieke resolver heeft al het werk gedaan.


2. TLS-certificaat

Voeg het domein toe aan de lijst met uitgifte — dit is de lijst die wordt gelezen bij de volgende volledige implementatie — en geef vervolgens het certificaat zelf uit.

# 1. inscrire le domaine dans la liste
ssh -p <port-ssh> <user>@vm-docker \
  "grep -q 'monservice.savethemall.eu' /opt/docker/acme/issue-all.sh || \
   sed -i 's|^)|  monservice.savethemall.eu\n)|' /opt/docker/acme/issue-all.sh"

# 2. émettre ce seul certificat
ssh -p <port-ssh> <user>@vm-docker \
  "docker exec acme acme.sh --issue --dns dns_ovh -d monservice.savethemall.eu \
     --cert-file      /certs/monservice.savethemall.eu/cert.pem \
     --key-file       /certs/monservice.savethemall.eu/privkey.pem \
     --fullchain-file /certs/monservice.savethemall.eu/fullchain.pem \
     --reloadcmd      \"curl -sf -X POST http://127.0.0.1:2019/load \
                        -H 'Content-Type: text/caddyfile' \
                        --data-binary @/etc/caddy/Caddyfile\""

--dnssleep is hier verplicht, en dat is niet het geval bij OVH

Zonder dit, mislukt de uitgifte consequent op:

Timed out waiting for DNS.
Error checking DNS.

acme.sh controleert zijn TXT-registratie via DoH op cloudflare-dns.com, en AdGuard lost dit adres op naar 0.0.0.0: het DNS-omwegfilter van het systeem blokkeert zijn eigen emissie-tool. De TXT-registratie staat echter wel goed bij OVH, en wordt vervolgens correct verwijderd — wat resulteert in een mislukking die lijkt op een probleem met identiteiten of propagatie.

De controle die resulteert in een commando:

docker exec acme sh -c 'nslookup cloudflare-dns.com | tail -3'
# Address: 0.0.0.0  → c'est AdGuard, pas OVH

--dnssleep vervangt de controle door een vaste wachttijd. Dit is de omweg; de oplossing is om cloudflare-dns.com in AdGuard toe te staan.

Controle

ssh -p <port-ssh> <user>@vm-docker \
  "ls -l /opt/docker/acme/certs/monservice.savethemall.eu/fullchain.pem"

De NAS ontvangt zijn kopie op rsync dagelijks. Om niet te hoeven wachten, kan deze handmatig worden geactiveerd voor stap 5.


3. Toepassing en provider in Authentik

In het beheerinterface:

  1. Toepassingen → Providers → Nieuw → Proxy provider
    • Mode: Forward auth (single application) — niet Proxy, niet Domain level.
    • Externe host: https://monservice.savethemall.eu
    • Autorisatieflow: die van het park (impliciete toestemming).
  2. Toepassingen → Nieuw
    • Slug: monservice
    • Provider: die welke net is aangemaakt
    • Icon: zoek het officiële logo voordat je de toepassing maakt. In volgorde: het GitHub-repository van het project, het /favicon.svg van de officiële website, https://cdn.simpleicons.org/<nom>, en vervolgens de catalogus https://cdn.jsdelivr.net/gh/selfhst/icons/svg/<nom>.svg.
  3. Toepassingen → Outposts → authentik Embedded Outpost → Bewerken → Toepassingen
    • Voeg de toepassing handmatig toe.

De ingebouwde outpost haalt de toepassing niet automatisch op

Dit is de meest voorkomende fout bij deze procedure. Zonder deze expliciete toevoeging, is alles correct geconfigureerd aan de Authentik-kant, stuurt Caddy correct door naar de authenticatieflow, en mislukt de authenticatie toch — zonder een bericht dat de oorzaak aangeeft.


4. Caddy blok in vm-docker

10-stacks/caddy/Caddyfile Bewerken in de vault, en vervolgens synchroniseren. Het bestand van de vault is geen symbolische link: beide kopieën zijn echt en verschillen als je ze vergeet.

monservice.savethemall.eu {
    import tls_cert monservice.savethemall.eu
    # Endpoints de l'outpost embarqué (sign_out, start, callback) → Authentik
    handle /outpost.goauthentik.io/* {
        reverse_proxy authentik-server:9000
    }
    handle {
        import authentik
        reverse_proxy monservice:8080
    }
}

De volgorde van handle is niet decoratief: zie forward_auth moet vóór handle staan ( ../reseau/chaine-reverse-proxy.md#forward_auth-passe-avant-handle ).

Synchroniseren, verplicht na elke bewerking:

ssh -p <port-ssh> <user>@vm-docker \
  "cp /docker-mounts/homelab-vault/10-stacks/caddy/Caddyfile /opt/docker/caddy/Caddyfile && \
   docker compose -f /opt/docker/caddy/docker-compose.yml restart"

Controle – op het LAN, waar het DNS al naar vm-docker wijst

curl -s -o /dev/null -w '%{http_code}\n' https://monservice.savethemall.eu/
# 302 vers auth.savethemall.eu → le mur est en place

curl -s -o /dev/null -w '%{http_code}\n' \
  https://monservice.savethemall.eu/outpost.goauthentik.io/zzz
# 404 → la route de l'outpost existe (302 ici = le handle est mal placé)

5. Caddy-blok op nas-caddy – dit is de toegangspoort naar het WAN

Zolang deze stap niet is uitgevoerd, reageert de service op het LAN en het tailnet, en is het niet zichtbaar vanaf het internet. Het NAS is de edge.

Bestand: /volume3/docker/nas-caddy/Caddyfile op het NAS.

monservice.savethemall.eu {
    import tls_cert monservice.savethemall.eu
    import to_vmdocker
}

Anders: authenticatie en routing blijven achter, op vm-docker. Het snippet (to_vmdocker) bevat al header_up Host {host} – zonder dit, zou de upstream-kant Host: vm-docker ontvangen.

Variant: het service buiten het WAN houden

Om een service die intern moet blijven, voeg je import lan_only toe aan het blok, in plaats van het niet te declareren. Hier is remote_ip echt de client: nas-caddy is de edge, er is geen upstream-proxy om de bron te verbergen.

Controle – het echte publieke pad

curl -s -o /dev/null -w '%{http_code}\n' \
  --resolve monservice.savethemall.eu:443:<IP publique> \
  https://monservice.savethemall.eu/

Zonder --resolve gaat het commando via het interne DNS en test het WAN-pad niet.


6. Secrets, indien van toepassing

  • De waarden leven in /opt/docker/monservice/.env op de host, nooit in de vault in de open, nooit in het Compose-bestand.
  • De gecodeerde versie gaat in 00-infra/secrets/vm-docker/monservice.enc.env (SOPS + leeftijd). De boom is geïndexeerd per host: er zijn drie stack-namen op twee of meer hosts, en zonder deze specificatie overschrijft de tweede de eerste – zonder problemen.
  • Alleen het publieke sleutel leeftijd is nodig om te coderen. Er hoeft geen privé sleutel op de andere hosts te bestaan.
  • Alle API-tokens worden opgeslagen in Vaultwarden onmiddellijk, volgens de conventie <hôte>/<stack>·<NOM_DE_VARIABLE>.

De gecodeerde data blijft permanent

Deze bestanden worden ook op GitHub geplaatst. Het repository is privé, maar wat er op is geplaatst, blijft daar: een wijziging van het geheime sleutel maakt de reeds gepubliceerde codering niet meer leesbaar. Een wijziging betekent een wijziging van bovenaf, niet alleen het bestand herschrijven.

Geen geheimen in een URL

De foutmelding registreert de opgeloste URL, inclusief het token. Ook Caddy verwijdert automatisch alleen drie headers: Authorization, Cookie, Set-Cookie. Een eigen header (X-Mon-Token) komt onversleuteld voor in access.log, wat wordt gelezen door CrowdSec. Elke nieuwe header die een geheim bevat, moet tegelijkertijd worden toegevoegd aan de logfilter.


7. Schrijven van wat er is gedaan

  • Input ingevoerd in 10-stacks/monservice/decisions.md: reden, en hoe terug te gaan.
  • Update van de master tabel van de stacks.
  • Commit van de vault en push naar beide remote repositories.

Samenvatting

  • Registratie A bij OVH, geverifieerd op de autoritaire server
  • Certificaat uitgegeven, domein toegevoegd aan de lijst
  • Proxy-provider Authentik in forward auth (single application) modus
  • Applicatie gecreëerd, met zijn logo
  • Applicatie handmatig toegevoegd aan de ingebouwde outpost
  • Caddy blok vm-docker, in de vault en gesynchroniseerd op de host
  • Sonde /outpost.goauthentik.io/zzz → 404
  • Caddy blok nas-caddy, certificaat gekopieerd naar het NAS
  • Controle WAN met --resolve
  • Geheimen gecodeerd in de vault, token opgeslagen in de vault
  • decisions.md, commit, dubbele push

Dernière vérification de cette page : 2026-09-08