Reverse Proxy (Caddy)
Host: services-proxy-01 — CT124 on pve0-core, 10.37.176.32, VLAN 176 (DMZ)
Access Model
Caddy runs Tailscale directly on the container. It is not reachable from LAN — you must be on the Tailnet to reach it. Being on the local network is not sufficient. This enforces true zero trust: every service request requires an authenticated Tailscale session with a signed device.
All services are served under *.home.pob.network. TLS certificates are obtained via DNS-01 challenge through Cloudflare (wildcard cert covers all subdomains).
TLS Configuration
- Protocols: TLS 1.2 and 1.3 only
- Key type: P-384
- Cipher suites: ECDSA only (AES-256-GCM, ChaCha20-Poly1305, AES-128-GCM)
- Certificate: Wildcard
*.home.pob.network via Cloudflare DNS challenge
- Resolvers:
1.1.1.1
| Header |
Value |
Strict-Transport-Security |
max-age=31536000; includeSubdomains |
X-Content-Type-Options |
nosniff |
X-Frame-Options |
SAMEORIGIN |
X-XSS-Protection |
0 (disabled — modern browsers handle this natively) |
Server |
Removed |
Permissions-Policy |
geolocation self only, microphone disabled |
Content-Security-Policy |
frame-ancestors 'self' *.home.pob.network |
Authelia Integration
Forward auth is configured as a reusable snippet. When applied, requests are forwarded to Authelia at 10.37.176.64:9091 before hitting the upstream. On success, Authelia headers (Remote-User, Remote-Groups, Remote-Email, Remote-Name) are passed to the backend.
Auth portal: https://auth.home.pob.network
Services
Authentication
| URL |
Backend |
Auth |
auth.home.pob.network |
authelia.pve.pob.network:9091 |
— (auth portal itself) |
Admin Only
| URL |
Backend |
Auth |
Notes |
n8n.home.pob.network |
n8n.pve.pob.network:5678 |
None |
|
beszel.home.pob.network |
beszel.pve.pob.network:8090 |
OIDC (native) |
Beszel uses Authelia as OIDC provider |
changedt.home.pob.network |
changedt.pve.pob.network:5000 |
Authelia |
|
bt.home.pob.network |
qbitorrent.pve.pob.network:8090 |
Authelia |
|
jackett.home.pob.network |
jackett.pve.pob.network:9117 |
Authelia |
|
mailarchiver.home.pob.network |
mailarchiver.pve.pob.network:5000 |
None |
|
Family Services
| URL |
Backend |
Auth |
Notes |
home.pob.network |
docker-prod-01.pve.pob.network:4030 |
None |
Homer dashboard |
ha.home.pob.network |
homeassistant.pve.pob.network:8123 |
None |
Home Assistant handles its own auth |
budget.home.pob.network |
docker-prod-01.pve.pob.network:4040 |
Authelia |
ActualBudget |
git.home.pob.network |
gitea.pve.pob.network:3000 |
None |
Gitea handles its own auth |
documents.home.pob.network |
paperless.pve.pob.network:8000 |
Authelia |
Paperless-ngx |
babybuddy.home.pob.network |
docker-prod-01.pve.pob.network:4010 |
Authelia |
|
| URL |
Backend |
Auth |
Notes |
jellyfin.home.pob.network |
jellyfin.pve.pob.network:8096 |
None |
Jellyfin handles its own auth |
sonarr.home.pob.network |
sonarr.pve.pob.network:8989 |
Authelia |
/api/* paths bypass auth (API token auth) |
invidious.home.pob.network |
docker-prod-01.pve.pob.network:4020 |
None |
Private YouTube frontend |
TeslaMate
| URL |
Path |
Backend |
Auth |
teslamate.home.pob.network |
/grafana/* |
docker-prod-01.pve.pob.network:4002 |
OIDC (native) |
teslamate.home.pob.network |
/api/* |
docker-prod-01.pve.pob.network:4003 |
HTTP Basic Auth |
teslamate.home.pob.network |
/* |
docker-prod-01.pve.pob.network:4001 |
Authelia |
Notes
- Catch-all rule is
abort — any unmatched request is terminated, no fallthrough
- Backend hostnames use internal DNS (
*.pve.pob.network) resolved by BIND
- Sonarr API paths bypass Authelia since automation tools use their own API token
- TeslaMate uses three different auth mechanisms across sub-paths of the same domain