Add Frusetik Access Architecture - Cloudflare/Pangolin/Authentik setup
This commit is contained in:
161
05_Resources/Frusetik Access Architecture.md
Normal file
161
05_Resources/Frusetik Access Architecture.md
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
# Frusetik Access Architecture
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Access architecture for `frusetik.com`. Public entry point is Cloudflare. Two targets behind the same Cloudflare Tunnel setup on the VPS: **Pangolin / Traefik** for app subdomains, and **Authentik** directly for `auth.frusetik.com`.
|
||||||
|
|
||||||
|
**Critical gotchas that broke the setup during setup:**
|
||||||
|
1. Pangolin internal TLS broke routing — must use HTTP internally
|
||||||
|
2. Immich iOS app breaks when Pangolin auth is enabled — must be "Not Protected"
|
||||||
|
3. `cloudflared` needed to be connected to `authentik_default` Docker network for `auth.frusetik.com` to work
|
||||||
|
4. Do NOT point Cloudflare web ingress at Gerbil for web app routing — Gerbil is part of Pangolin's tunnel system, not the normal HTTP routing target
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Public hostnames
|
||||||
|
|
||||||
|
| Hostname | Path |
|
||||||
|
|---|---|
|
||||||
|
| `pangolin.frusetik.com` | Cloudflare → Pangolin/Traefik on VPS |
|
||||||
|
| `immich.frusetik.com` | Cloudflare → Pangolin → home lab Immich |
|
||||||
|
| `glance.frusetik.com` | Cloudflare → Pangolin → home lab Glance |
|
||||||
|
| `baersolar.frusetik.com` | Cloudflare → Pangolin → home lab service |
|
||||||
|
| `auth.frusetik.com` | Cloudflare → Authentik directly on VPS (NOT Pangolin) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture diagram
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
U[User / Browser / Mobile App] --> CF[Cloudflare Edge / DNS / Tunnel Routing]
|
||||||
|
CF -->|auth.frusetik.com| CFL[cloudflared on VPS]
|
||||||
|
CF -->|*.frusetik.com app routes| CFL
|
||||||
|
subgraph VPS
|
||||||
|
CFL -->|http| AK[Authentik]
|
||||||
|
CFL -->|http| PT[Pangolin + Traefik]
|
||||||
|
PT --> PG[Pangolin control / resource routing]
|
||||||
|
end
|
||||||
|
PG -->|Pangolin tunnel / connector| NW[Newt in home lab]
|
||||||
|
subgraph Home Lab
|
||||||
|
NW --> IM[Immich]
|
||||||
|
NW --> GL[Glance]
|
||||||
|
NW --> BS[Baersolar]
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key design decisions
|
||||||
|
|
||||||
|
### 1. Cloudflare is the public entry point
|
||||||
|
Browser connects to Cloudflare over HTTPS. Cloudflare forwards through tunnel to VPS. Public TLS terminated at Cloudflare edge.
|
||||||
|
|
||||||
|
### 2. Pangolin and Authentik reached internally by HTTP
|
||||||
|
Internal TLS in Pangolin broke routing. Cloudflare already handles public HTTPS. Internal hop is HTTP on the VPS.
|
||||||
|
|
||||||
|
### 3. Authentik is NOT behind Pangolin
|
||||||
|
Authentik is routed directly to `auth.frusetik.com`. Pangolin is for app publishing only.
|
||||||
|
|
||||||
|
### 4. Immich must not be protected by Pangolin auth
|
||||||
|
iOS app breaks if Pangolin authentication is in front of Immich. Set to **Not Protected** in Pangolin.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding a new resource
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
1. **Make available on home network** — expose on some IP:PORT in the home lab
|
||||||
|
2. **Create public resource in Pangolin** — HTTP! If app access requires auth and supports OIDC, use Authentik as OpenID Provider; otherwise fall back to Pangolin's auth
|
||||||
|
3. **Create Cloudflare Tunnel route** — tunnel type HTTP, origin `http://gerbil:80` (or `https://gerbil:443` with NoTLSHandshake — untested)
|
||||||
|
4. **Wire up Authentik** — if app supports OIDC, add Authentik as OpenID Provider; else Pangolin auth handles it
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Networking
|
||||||
|
|
||||||
|
### Docker networks
|
||||||
|
- `authentik_default` — Authentik stack
|
||||||
|
- `pangolin` — Pangolin stack
|
||||||
|
- `edge` — **future**: shared network for cloudflared + public origins
|
||||||
|
|
||||||
|
### Current network fix (temporary)
|
||||||
|
```bash
|
||||||
|
docker network connect authentik_default cloudflared
|
||||||
|
```
|
||||||
|
Required for `cloudflared` to reach Authentik by Docker DNS name.
|
||||||
|
|
||||||
|
### Future cleanup
|
||||||
|
Create a shared `edge` network and attach `cloudflared`, Authentik server, and Pangolin/Traefik to it permanently.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentik access model
|
||||||
|
|
||||||
|
### Groups
|
||||||
|
- `family` — trusted family members (Immich, Nextcloud access)
|
||||||
|
- `movie-friends` — limited access (Jellyfin only, no Immich)
|
||||||
|
|
||||||
|
### Access matrix
|
||||||
|
| Application | family | movie-friends |
|
||||||
|
|---|---|---:|
|
||||||
|
| Immich | yes | no |
|
||||||
|
|
||||||
|
### Implementation
|
||||||
|
- One account per real person
|
||||||
|
- Application access controlled via Group bindings on the Application in Authentik
|
||||||
|
- If an application has no bindings, it may be accessible to all authenticated users — always bind explicitly
|
||||||
|
|
||||||
|
### Note on Immich
|
||||||
|
Current live state: Immich in Pangolin = **Not Protected** (for iOS app compatibility). Authentik access policy is the **desired target model**, not the currently enforced gate on the mobile path.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Operational checklist
|
||||||
|
|
||||||
|
### Pangolin resources stop working
|
||||||
|
1. Check whether TLS got re-enabled in Pangolin
|
||||||
|
2. Confirm resource still uses HTTP internally
|
||||||
|
3. Check resource hostname in Pangolin
|
||||||
|
4. Check whether auth was re-enabled for Immich
|
||||||
|
5. Confirm Pangolin/Traefik is still the Cloudflare tunnel target
|
||||||
|
|
||||||
|
### `auth.frusetik.com` breaks
|
||||||
|
1. Check `cloudflared` is still connected to `authentik_default`: `docker inspect cloudflared`
|
||||||
|
2. Test connectivity: `docker run --rm --network authentik_default curlimages/curl:8.6.0 curl -i http://server:9000`
|
||||||
|
3. Check Cloudflare tunnel mapping for `auth.frusetik.com`
|
||||||
|
|
||||||
|
### Immich mobile app breaks
|
||||||
|
1. Confirm `immich-prod` in Pangolin is still **Not Protected**
|
||||||
|
2. Confirm resource still uses HTTP inside Pangolin
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Reference
|
||||||
|
|
||||||
|
| Error | Cause | Fix |
|
||||||
|
|---|---|---|
|
||||||
|
| `404 page not found` on `immich.frusetik.com` | Pangolin internal TLS enabled | Disable TLS, enforce HTTP |
|
||||||
|
| `too_many_redirects` from `http://gerbil:80` | Wrong origin target | Use Pangolin/Traefik, not Gerbil directly |
|
||||||
|
| Cloudflare 502 on `auth.frusetik.com` | `cloudflared` can't resolve `server` hostname | `docker network connect authentik_default cloudflared` |
|
||||||
|
| Immich iOS app not working | Pangolin auth in front of Immich | Set Immich to **Not Protected** in Pangolin |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Useful commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List Docker networks
|
||||||
|
docker network ls
|
||||||
|
|
||||||
|
# Inspect cloudflared networks
|
||||||
|
docker inspect cloudflared
|
||||||
|
|
||||||
|
# Inspect authentik network
|
||||||
|
docker network inspect authentik_default
|
||||||
|
|
||||||
|
# Test auth.frusetik.com from authentik network
|
||||||
|
docker run --rm --network authentik_default curlimages/curl:8.6.0 \
|
||||||
|
curl -i -H "Host: auth.frusetik.com" http://server:9000
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user