Autor: daniel

  • Traefik OIDC Plugin: OAuth2 ohne separate Container

    TL;DR: Das Traefik OIDC Plugin (traefikoidc) ersetzt OAuth2-Proxy Container durch eine native Middleware-Lösung. Nach initialen Herausforderungen läuft es jetzt stabil mit Keycloak.

    Das Problem

    Bisher nutzte ich für jeden Service, der OAuth2-Schutz benötigt, einen separaten OAuth2-Proxy Container:

    • container1-auth für Service 1
    • container2-auth für Service2
    • etc..

    Nachteile:

    • Ein Container pro geschütztem Service
    • Höherer Ressourcen-Verbrauch
    • Komplexere Konfiguration mit Forward Auth

    Die Lösung: Traefik OIDC Plugin

    Das Plugin github.com/lukaszraczylo/traefikoidc integriert OIDC direkt als Traefik-Middleware.

    Architektur-Vergleich:

    Vorher: User → Traefik → OAuth2-Proxy Container → Keycloak → Service
    Nachher: User → Traefik (OIDC Middleware) → Keycloak → Service
    

    Setup

    1. Plugin in Traefik aktivieren

    # traefik.yml
    experimental:
      plugins:
        traefikoidc:
          moduleName: github.com/lukaszraczylo/traefikoidc
          version: v0.8.17
    

    2. Middleware definieren

    # middlewares.yml
    http:
      middlewares:
        service1-oidc:
          plugin:
            traefikoidc:
              providerURL: "https://keycloak.example.com/realms/my-realm"
              clientID: "my-client-id"
              clientSecret: "my-client-secret"
              callbackURL: "/oauth2/callback"
              logoutURL: "/oauth2/sign_out"
              sessionEncryptionKey: "base64-encoded-32-byte-key"
              forceHTTPS: true
              logLevel: "info"
              scopes:
                - "openid"
                - "profile"
                - "email"
              allowedRolesAndGroups:
                - "service-user"
    

    3. Service konfigurieren

    # docker-compose.yml
    labels:
      traefik.http.routers.service1_web.middlewares: "service1-oidc@file"
    

    Stolpersteine & Lösungen

    1. Problem: excludedURLs nicht verwenden!

    Fehler: Ich versuchte initial, den Callback über excludedURLs zu schützen:

    excludedURLs:
      - "/oauth2/callback"  # ❌ FALSCH
    

    Symptom: 404 Error – Der Callback wurde an den Upstream-Service weitergeleitet statt vom Plugin verarbeitet.

    Lösung: excludedURLs komplett weglassen! Das Plugin handhabt den Callback intern korrekt.

    2. Problem: Keycloak Audience Mismatch

    Fehler-Log:

    ERROR: ACCESS_TOKEN token verification failed: invalid audience
    WARNING: Falling back to ID token validation
    
    INFO: TraefikOidcPlugin: 2026/01/05 20:37:12 ⚠️  SCENARIO 2 DETECTED: Access token validation failed due to audience mismatch: standard claim verification failed: invalid audience
    ERROR: TraefikOidcPlugin: 2026/01/05 20:37:12 ACCESS_TOKEN token verification failed: standard claim verification failed: invalid audience
    INFO: TraefikOidcPlugin: 2026/01/05 20:37:12 ⚠️⚠️⚠️  SECURITY WARNING: Falling back to ID token validation despite access token audience mismatch!
    INFO: TraefikOidcPlugin: 2026/01/05 20:37:12 ⚠️  This could allow tokens intended for different APIs to grant access
    INFO: TraefikOidcPlugin: 2026/01/05 20:37:12 ⚠️  Set strictAudienceValidation=true to enforce proper audience validation
    INFO: TraefikOidcPlugin: 2026/01/05 20:37:12 ⚠️  See: https://github.com/lukaszraczylo/traefikoidc/issues/74
    

    Ursache: Keycloak’s Audience Mapper war nicht eingetragen .

    Lösung: In Keycloak → Client → Dedicated Scopes → Audience Mapper einfügen und checken dass die Audience exakt der Client-ID entspricht.

    3. Session Encryption Key generieren

    dd if=/dev/urandom bs=32 count=1 | base64
    

    Ergebnis

    Nach den Fixes läuft das Plugin stabil:

    DEBUG: User authenticated and token valid
    DEBUG: Found role from roles claim: service1-user
    DEBUG: Request authorized for user daniel@example.com
    200 OK
    

    Vorteile:

    • ✅ Diverse OAuth2-Proxy Container eliminiert
    • ✅ Weniger Ressourcen-Verbrauch
    • ✅ Einfachere Konfiguration (nur Middleware-Definition)
    • ✅ Gleiche Security wie OAuth2-Proxy

    Fazit

    Das Traefik OIDC Plugin ist production-ready und eine elegante Alternative zu OAuth2-Proxy Containern. Die wichtigste Lektion: Keine excludedURLs für den Callback verwenden – das Plugin weiß selbst, was es tut.

    Setup-Zeit: ~30 Minuten (inkl. Debugging)


    Links:

    Getestet mit: Traefik v3, Keycloak 25, Plugin v0.8.17

  • Extrahiere Zertifikate aus einem Traefik Zertifikatsspeicher

    Bei meinen Projekten mit traefik kam es vor, dass man ein Zertifikat und einen priv. Schlüssel aus der Traefik Datei acme.json extrahieren muss, um sie für andere Zwecke zu verwenden. In meinem Fall musste ich ein Zertifikat für eine bestehende Domain abrufen und für meinen Mailserver verwenden.

    Es gibt eine Reihe komplexer Beispiele zum Auslesen aller Zertifikate und das offizielle Tool traefik-cert-dumper. Das ganze ist aber eher kompliziert.

    Man kann stattdessen auch nur das JSON-Tool jq (jq) in einem Einzeiler verwenden.

    Falls jq nicht installiert ist zunächst installieren mit:

    sudo apt update;
    sudo apt jq;

    Codeschnipsel Zertifikatsexport

    jq -r '.defaut.Certificates[] | select(.domain.main==\"beispiel.com") | .certificate' /data/acme.json | base64 -d > /out/tls_cert.pem

    Man extrahiert as Zertifikat für die Domain beispiel.com, wandelt den Output mit base64 um und schreibt ihn in eine Ausgabedatei.

    Codeschnipsel Schlüsselexport

    Wenn man den privaten Schlüssel extrahieren möchte lautet der Befehl entsprechend:

    jq -r '.defaut.Certificates[] | select(.domain.main==\"'beispiel.com'\") | .key' /data/acme.json | base64 -d > /out/tls_key.key

  • Hallo Welt!

    Hier beschreibe ich bei Gelegenheit was ich an Erfahrungen beim Aufsetzen meines privaten Servers machen konnte.