OAuth2-Proxy¶
Siehe auch
oauth2-proxy ist ein vorgeschalteter Reverse Proxy, der Authentifizierung an einen OAuth2- oder OpenID-Connect-Provider (z.B. Keycloak, Google, GitHub) delegiert. Ist ein Request nicht authentifiziert, lenkt der Proxy den Benutzer zum Login-Flow der konfigurierten IdP-Seite um; bei Erfolg setzt er ein Session-Cookie und reicht den Request (mit zusätzlichen Headern wie X-Forwarded-User) an das Backend weiter. Damit lässt sich praktisch jede Webapp ohne eigene Authentifizierungslogik hinter Single-Sign-On (SSO) stellen.
Die Redirect-URL für den OAuth-Flow lautet standardmässig https://<host>/oauth2/callback. Der Proxy selbst lauscht auf Port 4180/tcp hinter einem Reverse-Proxy (Apache/Nginx/HAProxy) oder direkt auf 443/tcp.
Begriffe¶
- Access Token
Kurzlebiges Token, das einen authentifizierten Zugriff auf eine Ressource erlaubt (typisch 5 bis 60 Minuten). In OAuth 2.0 ein intransparenter String, bei OIDC-Providern häufig ein JWT.
- Authorization Code Flow
Standardisierter OAuth-Ablauf für Web-Anwendungen: der Browser wird zum IdP umgeleitet, der User loggt sich ein, der IdP antwortet mit einem kurzlebigen Code, den der Proxy serverseitig gegen Tokens tauscht. Voraussetzung für das clientseitige Geheimnis (client_secret), das oauth2-proxy verwendet.
- Client
Eine beim IdP registrierte Applikation, hier oauth2-proxy selbst. Identifiziert sich mit client_id und client_secret. Bei Keycloak entspricht dem ein Eintrag unter Clients mit Access-Type confidential.
- ID Token
OIDC-spezifisches JWT mit Identitätsdaten des Benutzers (
sub,email,preferred_username, Gruppen, …). Wird zusammen mit dem Access Token ausgestellt und ist der Grund, weshalb OIDC im Unterschied zu reinem OAuth 2.0 für Authentifizierung genutzt werden kann.- OAuth 2.0
Protokoll für delegierte Autorisierung (RFC 6749). Ursprünglich nicht für Authentifizierung gedacht - dafür kam OIDC hinzu.
- OIDC (OpenID Connect)
Erweiterung auf OAuth 2.0, die Authentifizierung und Benutzerprofil standardisiert (ID Token,
/userinfo-Endpunkt, Discovery). Heute der De-facto-Standard für SSO zwischen Web-Anwendungen.- PKCE
Proof Key for Code Exchange (RFC 7636). Schützt den Authorization Code Flow gegen Code-Interception-Angriffe durch einen pro Request zufällig erzeugten code_verifier. Für oauth2-proxy seit 7.x per
--code-challenge-method=S256empfohlen.- Refresh Token
Langlebiges Token zum Erneuern eines abgelaufenen Access Tokens ohne erneuten User-Login. Wird serverseitig in der oauth2-proxy-Session abgelegt.
- Session
oauth2-proxy hält den Login-Zustand in einem verschlüsselten Cookie (cookie session store) oder in Redis. Der Default ist das Cookie; Redis wird notwendig, sobald Token-Grössen das Browser-Cookie-Limit (typisch 4 KB) sprengen oder mehrere Proxy-Instanzen horizontal skaliert werden.
Installation¶
Oauth2-proxy liegt als statisches Binary auf GitHub. Aktuelle Version prüfen und anpassen:
VER=7.7.1
cd /tmp
wget "https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v${VER}/oauth2-proxy-v${VER}.linux-amd64.tar.gz"
tar --extract --gzip --verbose --file "oauth2-proxy-v${VER}.linux-amd64.tar.gz"
mv "oauth2-proxy-v${VER}.linux-amd64" /opt/
ln --symbolic --force "/opt/oauth2-proxy-v${VER}.linux-amd64" /opt/oauth2-proxy
Konfigurationsdatei /etc/oauth2-proxy.cfg passend zum genutzten IdP-Provider anlegen (siehe Abschnitt Integration mit Keycloak). Start:
/opt/oauth2-proxy/oauth2-proxy --config=/etc/oauth2-proxy.cfg
Bemerkung
Die Konfigurationsdatei folgt einem abgewandelten Kommandozeilen-Format: alle Vorkommen von - im Argumentnamen werden durch _ ersetzt, und mehrfach angegebene CLI-Argumente werden in der Datei als Liste mit Pluralform notiert (z.B. CLI --email-domain entspricht dem Config-Key email_domains).
Die vollständige Liste der Kommandozeilen-Argumente zeigt:
/opt/oauth2-proxy/oauth2-proxy --help
systemd-Service¶
[Unit]
Description=oauth2-proxy
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=oauth2-proxy
Group=oauth2-proxy
ExecStart=/opt/oauth2-proxy/oauth2-proxy --config=/etc/oauth2-proxy.cfg
Restart=on-failure
RestartSec=5
# hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/oauth2-proxy
[Install]
WantedBy=multi-user.target
useradd --system --home-dir /var/lib/oauth2-proxy --shell /sbin/nologin oauth2-proxy
mkdir --parents /var/lib/oauth2-proxy
chown oauth2-proxy:oauth2-proxy /var/lib/oauth2-proxy
chmod 600 /etc/oauth2-proxy.cfg
chown oauth2-proxy:oauth2-proxy /etc/oauth2-proxy.cfg
systemctl daemon-reload
systemctl enable --now oauth2-proxy
Unterstützte Provider¶
Der Proxy kennt eine Reihe vordefinierter Provider-Module (Auswahl):
Azure AD / Microsoft Entra ID
Bitbucket
DigitalOcean
Facebook
GitHub
GitLab
Google
Keycloak (
keycloakundkeycloak-oidc)LinkedIn
Nextcloud
Okta
generischer OIDC-Provider (
oidc)
Die gepflegteste Variante für OIDC-konforme IdPs ist keycloak-oidc bzw. oidc, da sie automatisch Discovery (/.well-known/openid-configuration) verwendet und den /userinfo-Endpunkt korrekt behandelt.
Integration mit Keycloak¶
Keycloak-Seite: neuer Client „oauth2-proxy“ vom Typ openid-connect anlegen.
Clients → oauth2-proxy → Settings:
Client ID:
oauth2-proxyClient Protocol:
openid-connectAccess Type:
confidentialValid Redirect URIs:
https://internal.example.com/oauth2/callback
Clients → oauth2-proxy → Mappers → Create:
Name:
OAuth Group MembershipMapper Type:
Group MembershipToken Claim Name:
groups
oauth2-proxy-Seite: Konfiguration gegen Keycloak in der Datei /etc/oauth2-proxy.cfg:
provider="keycloak-oidc"
client_id="<client-id>"
client_secret="<client-secret>"
oidc_issuer_url="https://keycloak.example.com/realms/<realm>"
code_challenge_method="S256"
allowed_groups=["/admin", "/consultants"]
# any base64-encoded secret (32 bytes before base64)
cookie_secret="<base64-encoded-32-byte-secret>"
email_domains=["*"]
# listen address: HTTP behind a reverse proxy, or 443/tcp directly
http_address="203.0.113.76:4180"
# pass identity headers to upstreams
pass_access_token=true
set_xauthrequest=true
Das cookie_secret lässt sich z.B. so erzeugen:
python3 -c 'import os, base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'
Konfigurations-Optionen im Überblick¶
Ein paar wiederkehrende Parameter, die in produktiven Setups gesetzt werden:
allowed_groupsWhitelist von Gruppen aus dem IdP. oauth2-proxy leitet ausschliesslich User durch, die in einer der Gruppen Mitglied sind.
cookie_secureSetzt das Session-Cookie nur über HTTPS (Standard
true). In produktiven Deployments nicht auffalsesetzen, auch nicht hinter einem Reverse-Proxy, der selbst TLS terminiert - oauth2-proxy kennt dasX-Forwarded-Proto-Header, damit das Cookie auch in dieser Konstellation als Secure markiert wird.email_domainsWhitelist der akzeptierten E-Mail-Domains. Mit
"*"jede Domain; sinnvollerweise fachlich einengen (z.B.["example.com"]), um die Angriffsfläche auf Konten im IdP zu begrenzen.pass_access_token/pass_authorization_headerGibt das OAuth-Access-Token bzw. den Authorization-Header an das Backend weiter. Benötigt, wenn das Backend selbst gegen den IdP validiert.
session_store_typecookie(Default) oderredis. Redis ist ab Gruppen-Claims oder grösseren JWTs fast immer notwendig.skip_auth_regexListe von URL-Regexes, die ohne Authentifizierung durchgereicht werden - praktisch für Health-Checks (
^/healthz$) oder öffentliche statische Inhalte.upstreamURL des Backends, an das oauth2-proxy nach erfolgreicher Authentifizierung weiterleitet. Mehrere
upstream-Einträge erlauben pfadbasiertes Fan-out.
Identitäts-Header für das Backend¶
Mit set_xauthrequest=true setzt oauth2-proxy nach erfolgreicher Authentifizierung diese Header auf den Weg zum Backend:
X-Auth-Request-Access-Token(nur beipass_access_token=true)X-Auth-Request-EmailX-Auth-Request-GroupsX-Auth-Request-Preferred-UsernameX-Auth-Request-User(üblicherweise dersub-Claim)
Das Backend vertraut diesen Headern nur, wenn oauth2-proxy zwingend davor geschaltet ist und unbefugte Direktzugriffe unterbunden sind (Firewall-Regel oder Bindung des Backends auf 127.0.0.1).
Integration mit Reverse-Proxy¶
oauth2-proxy kann auf zwei Arten eingebunden werden:
- Auth-Subrequest
Apache (
mod_auth_openidcoder direkter Reverse-Proxy mitmod_auth_form) und Nginx (auth_requestDirective) rufen oauth2-proxy als Authentifizierungs-Subservice auf. Der Reverse-Proxy bleibt für das Request-Routing zuständig, oauth2-proxy liefert nur das Authentifizierungs-Ergebnis und Identity-Header.- Vollständiger Proxy-Durchlauf
oauth2-proxy empfängt den Request direkt (bzw. hinter einem TLS-terminierenden Reverse-Proxy, der nur durchreicht), führt die Authentifizierung durch und reicht bei Erfolg an das in
upstreamkonfigurierte Backend weiter. Einfacher aufzusetzen, aber weniger flexibel bei Routing-Anforderungen.
Für Keycloak-Deployments der Linuxfabrik ist der Auth-Subrequest-Weg der Standard; er lässt sich mit Apache-mod_proxy konsistent mit bestehenden VirtualHost-Konfigurationen kombinieren.
Troubleshooting¶
- Login-Loop
Häufigste Ursache:
cookie_domainspasst nicht zum Host oder das Cookie wird durchcookie_secure=truehinter einem HTTP-Reverse-Proxy nicht gesetzt. Mitoauth2-proxy --show-debug-on-errorund dem Browser-DevTools-Network-Tab nachvollziehen, ob das Cookie am Client ankommt.ErrEmailDomainoauth2-proxy weist den User ab, weil die E-Mail-Domain nicht in
email_domainssteht. Entweder Domain ergänzen oder den Zugriff explizit aufallowed_groupsbeschränken undemail_domains=["*"]setzen.- Cookie wird zu gross
Tritt auf, sobald das ID-Token viele Gruppen-Claims enthält. Abhilfe:
session_store_type=redismit lokaler Redis-Instanz.- User sieht Keycloak-Login trotz gültiger SSO-Session
--skip-provider-button=trueüberspringt die Zwischenseite von oauth2-proxy; dazu in Keycloak sicherstellen, dass der Client keinen expliziten Prompt benötigt (prompt=nonebei Bedarf im IdP-URL-Template).