diff --git a/caddy.env.example b/caddy.env.example new file mode 100644 index 0000000..7c11e97 --- /dev/null +++ b/caddy.env.example @@ -0,0 +1 @@ +IONOS_AUTH_API_TOKEN=your_token_here diff --git a/hosts/hubris/Caddyfile b/hosts/hubris/Caddyfile new file mode 100644 index 0000000..6423a49 --- /dev/null +++ b/hosts/hubris/Caddyfile @@ -0,0 +1,234 @@ +import /etc/caddy/shared/* + +git.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + handle_path /_plantuml/* { + rewrite * /plantuml{uri} + reverse_proxy 192.168.8.205:8079 + } + handle { + reverse_proxy 192.168.8.121:3000 + } +} + +paperless.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + @api path /api/* + handle @api { + reverse_proxy 192.168.8.130:8000 + } + handle { + import authentik + reverse_proxy 192.168.8.130:8000 + } +} + + +pascal.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.100:3001 +} + +home.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.101:8123 +} + +cloud.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.224:80 +} + + +proxmox.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy https://192.168.8.77:8006 { + transport http { + tls_insecure_skip_verify + } + } +} + +docker.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy https://192.168.8.205:9443 { + transport http { + tls_insecure_skip_verify + } + } +} + + + + +blog.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.205:8080 +} + +photos.hubris.network { + # Mulimage 2.0 — PhotoPrism + Go sidecar + SvelteKit (LXC 120) + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + encode zstd gzip + # PhotoPrism API + static assets + share links + @pp path /api/v1/* /api/v1 /static/* /share/* + reverse_proxy @pp 192.168.8.136:2342 + # OIDC hand-off: PhotoPrism redirects to /library/login after SSO; + # bounce back to / so the SvelteKit SPA picks up the session. + redir /library / 302 + redir /library/* / 302 + # Go sidecar — marks, folder mutations, duplicates, heap convert + @sc path /api/sidecar/* + reverse_proxy @sc 192.168.8.136:8000 + # SvelteKit frontend (catch-all) + reverse_proxy 192.168.8.136:3000 +} + +prism.hubris.network { + # PhotoPrism — direct access for Prismatic mobile client (LXC 120) + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + encode zstd gzip + reverse_proxy 192.168.8.136:2342 +} + +auth.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy https://auth.hubris.network:443 { + transport http { + tls_server_name auth.hubris.network + } + header_up Host auth.hubris.network + } +} + +artifacto.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + # Public paths: share URLs, static assets, health — no SSO + @public path /p/* /static/* /healthz + handle @public { + reverse_proxy 192.168.8.205:3100 + } + # Admin + login surface: Authentik forward-auth + shared-secret header + # so the app can auto-login an Authentik-authenticated user. + handle { + import authentik + reverse_proxy 192.168.8.205:3100 { + header_up X-Artifacto-Gateway {env.ARTIFACTO_GATEWAY_SECRET} + } + } +} + +plato.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.190:8080 +} + +zimaos.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.195:80 +} + +# Homelab MCP server (read-only context + management tools). +# Mesh+LAN-gated by the service itself + nftables; no SSO so agent clients work. +sso.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy https://auth.hubris.network:443 { + transport http { + tls_server_name auth.hubris.network + } + header_up Host auth.hubris.network + } +} + + +# Matrix Synapse federation + client API. +# No authentik gate — Synapse handles its own auth. + + +trmnl.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.211:9851 +} + + +teddy.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy https://192.168.8.150:8443 { + transport http { + tls_insecure_skip_verify + } + } +} + + +# ─── Oikos (Go rewrite, Docker on mac-mini) ─── +# Phase 6 cutover — replaces apps/105 Python MCP + console. +# /api/v1/clients/enroll bypasses Authentik (IP-gated in the API handler). +# The SPA is its own container (:8091, compose/web/Dockerfile in the oikos +# repo) — not served by api itself, which no longer embeds it. +oikos.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + @enroll path /api/v1/clients/enroll /oidc-callback + handle @enroll { + reverse_proxy 192.168.178.182:8090 + } + @api path /api/v1/* /mcp /agent/* + handle @api { + reverse_proxy 192.168.178.182:8090 + } + handle { + import authentik + reverse_proxy 192.168.178.182:8091 + } +} + +mcp.hubris.network { + reverse_proxy 192.168.178.182:8090 +} + +hermes.hubris.network { + reverse_proxy 192.168.178.182:8092 +} + +tube.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.178.44:8082 +} diff --git a/hosts/strong/Caddyfile b/hosts/strong/Caddyfile new file mode 100644 index 0000000..5d5f9cd --- /dev/null +++ b/hosts/strong/Caddyfile @@ -0,0 +1,83 @@ +import /etc/caddy/shared/* + +media.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + # SSO plugin handles auth via OIDC redirect to Authentik. + # No forward-auth gate — Jellyfin login page shows SSO button directly. + reverse_proxy 192.168.8.246:8096 +} + +books.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.247:6060 +} + +roms.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.249:80 +} + +jellyseerr.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.245:5056 +} + +qbit.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + @api path /api/* + handle @api { + reverse_proxy 192.168.8.245:8080 + } + handle { + import authentik + reverse_proxy 192.168.8.245:8080 + } +} + +sab.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + handle { + import authentik + reverse_proxy 192.168.8.245:8082 + } +} + +matrix.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.242:8008 +} + +element.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.242:8080 +} + +house.hubris.network { +tls { +dns ionos {env.IONOS_AUTH_API_TOKEN} +} +reverse_proxy 192.168.8.244:3000 +} + +seanime.hubris.network { + tls { + dns ionos {env.IONOS_AUTH_API_TOKEN} + } + reverse_proxy 192.168.8.248:43211 +} diff --git a/shared/authentik b/shared/authentik new file mode 100644 index 0000000..a2bfa4c --- /dev/null +++ b/shared/authentik @@ -0,0 +1,34 @@ +# Internal forward-auth upstream proxy (no TLS between Caddy handlers) +:8099 { + @outpost path /outpost.goauthentik.io/* + reverse_proxy @outpost https://auth.hubris.network:443 { + transport http { + tls_server_name auth.hubris.network + } + header_up Host auth.hubris.network + } +} + +# Authentik forward-auth snippet (domain-level mode). +# Usage: add "import authentik" inside any site block to gate it. +(authentik) { + route { + reverse_proxy /outpost.goauthentik.io/* https://auth.hubris.network:443 + forward_auth http://127.0.0.1:8099 { + uri /outpost.goauthentik.io/auth/caddy + copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version + trusted_proxies private_ranges + header_up X-Forwarded-Host {host} + header_up X-Forwarded-Proto {scheme} + header_up X-Forwarded-Uri {uri} + } + } +} + +# Unless the file starts with a global options block, the first +# uncommented line is always the address of your site. +# +# To use your own domain name (with automatic HTTPS), first make +# sure your domain's A/AAAA DNS records are properly pointed to +# this machine's public IP, then replace ":80" below with your +# domain name.