Authentik SSO + homepage naked domain
Auth layer (Authentik 2026.8.0): - compose: 3-service stack (authentik-postgres, authentik-server, authentik-worker), postgres health-gated, bind mounts under /home/dank/authentik - Caddyfile: auth.franksdank.cloud vhost; forward_auth on the no-auth vhosts (homepage, SearXNG, Hermes, Prometheus, RomM, Copyparty); outpost path proxied first in a route block - .env.example: AUTHENTIK_PG_PASS + AUTHENTIK_SECRET_KEY - deploy.sh: render only CADDY_BASICAUTH_HASH (the homepage per-user hashes are retired; grafana + pihole keep basicauth) - tests/authentik.bats (new) + updated homepage/caddyfile/pihole seams - docs: Authentik.md + per-service pages; Caddy.md + Homepage.md updated Homepage (naked domain): - Caddyfile: dankclaw.franksdank.cloud -> franksdank.cloud www.franksdank.cloud; dankclaw + dankserver redirect to it; bare-IP catch-all updated - addn-hosts: A records for the naked domain, www, and auth (all -> 143) - tests/pihole.bats: vhost_names handles multi-address blocks; TLD check allows the naked domain All 146 tests pass.
This commit is contained in:
1 parent
7ba1acdbc5
commit
3cc99d81cc
17 files changed
+634
-137
No files matched your search
+93
-55
@@ -11,16 +11,19 @@
|
||||
# (dankclaw/pihole/addn-hosts — every name resolves to 192.168.0.143)
|
||||
# and handed to LAN clients by the SURFboard G36 router.
|
||||
#
|
||||
# The basicauth hash below is a placeholder. deploy.sh renders the real
|
||||
# hash (CADDY_BASICAUTH_HASH from the host .env, git-ignored) into
|
||||
# /home/dank/Containers/caddy/Caddyfile, which the container mounts.
|
||||
# Authentication: Caddy forward_auth (Authentik SSO) protects the vhosts that
|
||||
# do not have their own application-level auth (homepage, SearXNG, Hermes,
|
||||
# Prometheus, RomM, Copyparty). The basicauth hash is a placeholder; deploy.sh
|
||||
# renders the real hash (CADDY_BASICAUTH_HASH from the host .env, git-ignored)
|
||||
# into /home/dank/Containers/caddy/Caddyfile, which the container mounts.
|
||||
# Apps with their own auth (Grafana, Gitea, OpenWebUI, Jellyfin, *arr, Pi-hole)
|
||||
# are not wrapped in forward_auth — they handle their own login.
|
||||
#
|
||||
# TLS: real Let's Encrypt certs. Site addresses carry no http:// prefix,
|
||||
# so Caddy serves HTTPS (and auto-redirects HTTP). Certs are wildcard
|
||||
# (dns-01) via the global acme_dns block below, using the Porkbun module
|
||||
# built into the franksdank/caddy-porkbun image (caddy/Containerfile).
|
||||
# That needs no inbound ports and works from the LAN, where dnsmasq
|
||||
# resolves these names to 192.168.0.143.
|
||||
# so Caddy serves HTTPS (and auto-redirects HTTP). Certs are issued via
|
||||
# dns-01 through the Porkbun module built into the franksdank/caddy-porkbun
|
||||
# image (caddy/Containerfile). That needs no inbound ports and works from the
|
||||
# LAN, where Pi-hole resolves these names to 192.168.0.143.
|
||||
|
||||
{
|
||||
# Admin stays ON: it binds to 127.0.0.1:2019 inside the container and the
|
||||
@@ -41,51 +44,61 @@
|
||||
|
||||
# --- Bare-IP access (health checks, convenience) ---
|
||||
:80 {
|
||||
redir https://dankclaw.franksdank.cloud/ 302
|
||||
redir https://franksdank.cloud/ 302
|
||||
}
|
||||
|
||||
# --- Homepage (password protected) ---
|
||||
dankclaw.franksdank.cloud {
|
||||
# --- Homepage (Authentik SSO) ---
|
||||
franksdank.cloud www.franksdank.cloud {
|
||||
root * /srv/homepage
|
||||
|
||||
# Operator-only admin page (Q19). Auth is checked on the original path,
|
||||
# before any rewrite, so the path matcher is reliable. Caddy sorts a
|
||||
# top-level 'rewrite' before 'basicauth'; that would change the path and
|
||||
# break the path-based auth matchers. 'handle' preserves order.
|
||||
handle /admin* {
|
||||
basicauth {
|
||||
frank REPLACE_WITH_ADMIN_HASH
|
||||
}
|
||||
try_files /admin.html
|
||||
file_server
|
||||
}
|
||||
route {
|
||||
# Authentik outpost (login UI + session management).
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
|
||||
# Shared data + assets: the family OR the operator, so both pages can load
|
||||
# them (the browser reuses the page's credential for these fetches). A
|
||||
# 'handle' inline matcher is a single token, so the multi-path match is a
|
||||
# named matcher.
|
||||
@data path /services.json /status.json /app.js /style.css /deployed.js
|
||||
handle @data {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HOMEPAGE_HASH
|
||||
frank REPLACE_WITH_ADMIN_HASH
|
||||
# Forward auth: check the Authentik session before serving the page.
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
file_server
|
||||
}
|
||||
|
||||
# Everything else (the user page): the homepage login (dankuser).
|
||||
handle {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HOMEPAGE_HASH
|
||||
# Operator-only admin page. Auth is checked on the original path,
|
||||
# before any rewrite, so the path matcher is reliable. 'handle'
|
||||
# preserves order.
|
||||
handle /admin* {
|
||||
try_files /admin.html
|
||||
file_server
|
||||
}
|
||||
|
||||
# Shared data + assets: fetched by both the user page and the admin
|
||||
# page. With forward_auth, any authenticated user can access them
|
||||
# (the browser's Authentik session covers these fetches).
|
||||
@data path /services.json /status.json /app.js /style.css /deployed.js
|
||||
handle @data {
|
||||
file_server
|
||||
}
|
||||
|
||||
# Everything else (the user page).
|
||||
handle {
|
||||
try_files /index.html
|
||||
file_server
|
||||
}
|
||||
try_files /index.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
|
||||
# --- Legacy name: the old homepage name redirects to the naked domain ---
|
||||
dankclaw.franksdank.cloud {
|
||||
redir https://franksdank.cloud/ 302
|
||||
}
|
||||
|
||||
# --- Legacy name: the media host has no Caddy of its own anymore ---
|
||||
dankserver.franksdank.cloud {
|
||||
redir https://dankclaw.franksdank.cloud/ 302
|
||||
redir https://franksdank.cloud/ 302
|
||||
}
|
||||
|
||||
# --- Authentik (SSO / OIDC provider) ---
|
||||
auth.franksdank.cloud {
|
||||
reverse_proxy authentik-server:9000
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
@@ -94,10 +107,15 @@ dankserver.franksdank.cloud {
|
||||
|
||||
# --- SearXNG (quadlet; behind the Gluetun tunnel, published 8081) ---
|
||||
search.franksdank.cloud {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HASH
|
||||
route {
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
reverse_proxy 192.168.0.143:8081
|
||||
}
|
||||
reverse_proxy 192.168.0.143:8081
|
||||
}
|
||||
|
||||
# --- ComfyUI ---
|
||||
@@ -112,10 +130,15 @@ chat.franksdank.cloud {
|
||||
|
||||
# --- Hermes ---
|
||||
hermes.franksdank.cloud {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HASH
|
||||
route {
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
reverse_proxy hermes:8090
|
||||
}
|
||||
reverse_proxy hermes:8090
|
||||
}
|
||||
|
||||
# --- Gitea (quadlet; published 3000) ---
|
||||
@@ -133,10 +156,15 @@ grafana.franksdank.cloud {
|
||||
|
||||
# --- Prometheus ---
|
||||
prometheus.franksdank.cloud {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HASH
|
||||
route {
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
reverse_proxy prometheus:9090
|
||||
}
|
||||
reverse_proxy prometheus:9090
|
||||
}
|
||||
|
||||
# --- Loki ---
|
||||
@@ -176,18 +204,28 @@ books.franksdank.cloud {
|
||||
|
||||
# --- RomM ---
|
||||
romm.franksdank.cloud {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HASH
|
||||
route {
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
reverse_proxy 192.168.0.235:8085
|
||||
}
|
||||
reverse_proxy 192.168.0.235:8085
|
||||
}
|
||||
|
||||
# --- Copyparty ---
|
||||
files.franksdank.cloud {
|
||||
basicauth {
|
||||
dankuser REPLACE_WITH_HASH
|
||||
route {
|
||||
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||
forward_auth authentik-server:9000 {
|
||||
uri /outpost.goauthentik.io/auth/caddy
|
||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
|
||||
trusted_proxies private_ranges
|
||||
}
|
||||
reverse_proxy 192.168.0.235:3923
|
||||
}
|
||||
reverse_proxy 192.168.0.235:3923
|
||||
}
|
||||
|
||||
# --- Jellyfin ---
|
||||
|
||||
Reference in new issue
Block a user