Zum Inhalt

Technische Referenz

Zielgruppe: Provider (ISN Systems) — Deployment, Architektur, Debugging

Architektur

Browser → Traefik (443)
    auth-check Middleware (ForwardAuth)
    GET http://auth-service:8091/verify
    Auth-Service (PHP 8.4 + SQLite)
      ├── Route in protected_routes?
      │     ├── Nein → 200 OK (durchlassen)
      │     └── Ja → Cookie pruefen
      │           ├── Gueltig → 200 OK + X-Auth-* Header
      │           └── Ungueltig → 302 → auth.xynap.tech/login
    Backend-Service

Komponenten

Komponente Technologie Speicherort
Auth-Service PHP 8.4 (Built-in Server) /usr/local/xynap/auth-service/
Datenbank SQLite 3 /var/lib/xynap/auth-service/auth.db (Volume)
CSRF-Secret Datei /var/lib/xynap/auth-service/auth.db.csrf_secret
Templates HTML /usr/local/xynap/auth-service/templates/
Container Docker auth-service (Port 8091 intern)

Datenbank-Schema

Tabelle: users

Spalte Typ Beschreibung
id INTEGER PK Auto-Increment
email TEXT UNIQUE Login-Email (lowercase)
password TEXT bcrypt Hash (cost=12)
name TEXT Anzeigename
status TEXT pending / active / blocked
role TEXT user / admin
created_at DATETIME Registrierungsdatum
approved_at DATETIME Freischaltdatum
last_login DATETIME Letzter Login

Tabelle: sessions

Spalte Typ Beschreibung
token TEXT PK 64-Zeichen Hex-Token (Session-ID)
user_id INTEGER FK Referenz auf users.id
ip TEXT IP des Logins
user_agent TEXT Browser User-Agent
created_at DATETIME Session-Start
expires_at DATETIME Ablaufzeit (TTL: 24h)

Tabelle: protected_routes

Spalte Typ Beschreibung
id INTEGER PK Auto-Increment
host TEXT Domain (z.B. ai.xynap.tech)
path TEXT URL-Pfad (z.B. /)
description TEXT Kurzbeschreibung
required_role TEXT user oder admin
enabled INTEGER 1 = aktiv, 0 = inaktiv
created_at DATETIME Erstelldatum

Tabelle: login_attempts

Spalte Typ Beschreibung
ip TEXT Quell-IP
attempted_at DATETIME Zeitpunkt des Fehlversuchs

Traefik-Integration

Middleware-Definition

In der Docker-Compose (/etc/xynap/stack/docker-compose.yml) am auth-service Container:

labels:
  - "traefik.http.middlewares.auth-check.forwardauth.address=http://auth-service:8091/verify"
  - "traefik.http.middlewares.auth-check.forwardauth.trustForwardHeader=true"
  - "traefik.http.middlewares.auth-check.forwardauth.authResponseHeaders=X-Auth-User,X-Auth-Name,X-Auth-Role"

Middleware einbinden

Um einen Service zu schuetzen, auth-check in die Middleware-Chain aufnehmen:

labels:
  - "traefik.http.routers.mein-service.middlewares=crowdsec@file,security-headers@file,rate-limit-standard@file,auth-check"

Response-Header

Bei erfolgreicher Authentifizierung setzt der Auth-Service folgende Header, die an das Backend weitergereicht werden:

Header Inhalt Beispiel
X-Auth-User E-Mail des Benutzers admin@xynap.tech
X-Auth-Name Anzeigename Admin
X-Auth-Role Benutzerrolle admin

Backend-Services koennen diese Header auswerten, um benutzerbasierte Logik umzusetzen.

Eigenschaft Wert
Name __xynap_auth
Domain .xynap.tech
Path /
Secure true (nur HTTPS)
HttpOnly true (kein JavaScript-Zugriff)
SameSite Lax
Max-Age 86400 Sekunden (24 Stunden)

Cookie-Domain beachten

Der Cookie gilt nur fuer *.xynap.tech. Dienste unter anderen Domains (z.B. xynap.cloud, xynap.eu) koennen den Cookie nicht lesen und muessen die Route-Protection in der SQLite-DB nutzen, um bei /verify als geschuetzt erkannt zu werden. Der Login-Redirect funktioniert, aber der Cookie wird nach dem Login nur fuer .xynap.tech gesetzt — der Benutzer wird bei Diensten unter anderen Domains erneut zum Login weitergeleitet.

Endpoints

Pfad Methode Beschreibung
/verify GET ForwardAuth-Endpoint (Traefik ruft diesen auf)
/login GET/POST Login-Seite und Formular-Verarbeitung
/register GET/POST Registrierungs-Seite
/logout GET Session beenden, Cookie loeschen
/admin GET/POST Admin-Panel (nur role=admin)

Deployment

Container-Konfiguration

Der Auth-Service laeuft als Docker-Container im xynap-Stack:

# Container-Status pruefen
sudo docker ps --filter "name=auth-service"

# Logs anzeigen
sudo docker compose -f /etc/xynap/stack/docker-compose.yml logs -f auth-service

# Neustart
sudo docker compose -f /etc/xynap/stack/docker-compose.yml restart auth-service

# Rebuild (nach Code-Aenderungen)
sudo docker compose -f /etc/xynap/stack/docker-compose.yml up -d --build auth-service

Umgebungsvariablen

Variable Default Beschreibung
AUTH_COOKIE_DOMAIN .xynap.tech Cookie-Domain
AUTH_SESSION_TTL 86400 Session-Dauer in Sekunden
AUTH_DB_PATH /data/auth.db Pfad zur SQLite-Datenbank
AUTH_FIRST_USER_ADMIN true Erster User wird Admin

Datenbank-Zugriff (Debugging)

Da der Container kein sqlite3 CLI hat, Zugriff via PHP:

# Alle Benutzer auflisten
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
foreach(\$db->query('SELECT id, email, status, role, last_login FROM users') as \$r)
    echo implode(' | ', \$r) . PHP_EOL;
"

# Alle geschuetzten Routen anzeigen
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
foreach(\$db->query('SELECT host, path, required_role, enabled FROM protected_routes ORDER BY host') as \$r)
    echo implode(' | ', \$r) . PHP_EOL;
"

# Aktive Sessions zaehlen
sudo docker exec auth-service php -r "
\$db = new PDO('sqlite:/data/auth.db');
echo \$db->query(\"SELECT COUNT(*) FROM sessions WHERE expires_at > datetime('now')\")->fetchColumn() . ' aktive Sessions' . PHP_EOL;
"

Troubleshooting

Login-Redirect-Schleife

Symptom: Nach Login wird man sofort wieder zum Login weitergeleitet.

Ursachen:

  1. Cookie-Domain stimmt nicht: Dienst laeuft nicht unter *.xynap.tech
  2. Session abgelaufen: TTL pruefen (AUTH_SESSION_TTL)
  3. HTTPS-Problem: Cookie ist Secure=true, funktioniert nur ueber HTTPS

Diagnose:

# Verify-Endpoint direkt testen
curl -v -H "Host: ai.xynap.tech" http://auth-service:8091/verify

# Cookie manuell pruefen
curl -v -b "__xynap_auth=TOKEN_HIER" -H "Host: ai.xynap.tech" http://auth-service:8091/verify

403 Forbidden trotz Login

Ursache: Die Route erfordert admin, der Benutzer hat aber nur user.

Loesung: Route im Admin-Panel auf user umstellen oder dem Benutzer die Admin-Rolle zuweisen.

Dienst ist oeffentlich obwohl er geschuetzt sein sollte

Checkliste:

  1. Hat der Dienst auth-check in seiner Traefik-Middleware-Chain?
  2. Existiert eine aktive Route in protected_routes fuer die Domain?
  3. Ist die Route enabled = 1?

Wenn nur die Traefik-Middleware fehlt, wird /verify zwar nie aufgerufen — aber wenn nur die DB-Route fehlt, gibt /verify automatisch 200 OK zurueck (durchlassen).

Beide muessen konfiguriert sein: Traefik-Middleware und DB-Route.

Rate-Limiting greift zu frueh

Symptom: Benutzer wird nach wenigen Versuchen gesperrt.

Ursache: Mehrere Benutzer teilen sich eine oeffentliche IP (NAT/VPN).

Loesung: Rate-Limit-Einstellungen in config.php anpassen:

'rate_limit_window' => 300,   // Fenster in Sekunden
'rate_limit_max'    => 10,    // Max Fehlversuche