2026-06-28 10:11:53 +02:00
---
marp: true
theme: gaia
class: invert
paginate: true
---
< style >
2026-06-28 10:59:46 +02:00
section { font-size: 25px; line-height: 1.28; }
h1 { font-size: 1.55em; margin-bottom: 0.3em; }
h3 { font-size: 1.05em; }
ul, ol { margin: 0.2em 0; }
li { margin: 0.12em 0; }
li > ul, li > ol { margin: 0.04em 0; }
pre { margin: 0.25em 0; }
pre code { font-size: 0.72em; line-height: 1.25; }
code { font-size: 0.82em; }
table { font-size: 0.62em; }
th, td { padding: 0.22em 0.55em; }
section.dense { font-size: 21px; }
section.dense table { font-size: 0.5em; }
2026-06-28 10:11:53 +02:00
.mermaid svg { max-width: 100% !important; height: auto !important; }
< / style >
# Routing TaPPaaS through the VPS
### Split-horizon DNS · public exposure on a static IP
MakerFLOSS · June 2026 · _technical review_
---
## The goal
Publish selected **TaPPaaS** web services under `*.tappaas.makerfloss.eu` .
- **Public exposure** — A records point at the VPS static IP `88.99.32.236` ,
so the cluster's services are reachable from anywhere.
- **Split-horizon DNS** — the _same_ hostname resolves to a **local** address
for internal clients, so they never round-trip to the VPS.
- **Isolation preserved** — nothing on the makerspace side egresses through
the VPS or reaches the homelab.
> We are not inventing anything — we clone a pattern already running.
---
## Building block: the proven `mf01` pattern
`mf01` already publishes `*.mf01.makerfloss.eu` exactly this way, live since
2026-06-09:
- TLS terminates on the **VPS** (wildcard cert, Gandi DNS-01).
- Plain HTTP rides the ** `wg1` ** WireGuard tunnel to an internal reverse proxy.
- The internal proxy routes by **Host** to the right container.
**TaPPaaS = the same shape**, with Caddy as the internal proxy instead of an
internal Traefik. Low risk, known gotchas already solved.
---
## External request flow
```mermaid
flowchart LR
C["Browser< br / > (off-site)"] -->|"https · *.tappaas< br / > DNS → 88.99.32.236"| T["VPS Traefik :443< br / > wildcard cert< br / > TLS ends here"]
T -->|"plain HTTP< br / > inside wg1"| K["FLOSSFirewall / Caddy< br / > 10.13.0.9:80"]
K -->|"route by Host"| S["TaPPaaS service< br / > srv01 / srv02 / srv03"]
```
TLS terminates at the VPS; the backend hop is plain HTTP but **encrypted on the
wire inside WireGuard**.
---
## Internal flow — two views, one name
```mermaid
flowchart TD
N["< svc> .tappaas.makerfloss.eu"]
N -->|"public DNS (Gandi)"| V["VPS 88.99.32.236< br / > VPS wildcard cert"]
N -->|"internal DNS (FLOSSFirewall)"| L["Caddy local IP< br / > Caddy's own LE cert"]
```
A client only ever sees the cert for the IP it resolved — **VPS wildcard
externally, Caddy's own cert internally**. The two views never collide.
---
<!-- _class: invert dense -->
## Key decisions
| Decision | Choice | Why |
|---|---|---|
| Transport | New ** `wg1` ** WireGuard peer | Mirrors mf01; both ends self-owned; static hub-and-spoke |
| TLS (external) | **Terminate at the VPS** | Cert issuance while isolated kills passthrough; Gandi DNS-write key stays on the VPS; keeps edge routing/middleware |
| Naming | **Wildcard** `*.tappaas.makerfloss.eu` | One cert + one route; add services with zero VPS change; no apex clash (`forgejo.tappaas…` ≠ `forgejo.makerfloss.eu` ) |
| Internal DNS | **FLOSSFirewall** (already runs DNS), cluster first | LAN view deferred — depends on third-party router |
---
## Components — VPS side
All additive in `AnsibleBaobabV4/host_vars/makerfloss.yml` , mirroring mf01:
1. **wg1 peer** — FLOSSFirewall, `allowed_ips: 10.13.0.9/32` .
2. **Wildcard cert** — add `tappaas.makerfloss.eu` + `*.tappaas` to
`traefik_wildcard_sets` → ACME anchor issues it via Gandi DNS-01.
3. **Catch-all route** — `tappaas-delegate.yml` :
`HostRegexp(...tappaas...)` → `http://10.13.0.9:80` , `passHostHeader: true` .
4. **Public DNS** — `tappaas` + `*.tappaas` A → `88.99.32.236` .
After this, **new services need zero VPS change** — exposure is decided at Caddy.
---
## Components — TaPPaaS / Caddy side
1. **WireGuard client** — peer to the VPS hub, interface `10.13.0.9/32` ,
`AllowedIPs = 10.13.0.0/24` only → **split-tunnel** (no general egress
through the VPS).
2. **Caddy plain-HTTP backend** — Host-routed listener on the wg interface
(`10.13.0.9:80` ), **HTTPS-redirect OFF** . Caddy keeps serving `:443` with its
own certs to internal clients, unchanged.
3. **Firewall** — allow `tcp/80` **only from `10.13.0.1`** (the VPS) on the wg
interface.
---
2026-06-28 10:59:46 +02:00
## Phasing — VPS edge (steps 1– 3)
2026-06-28 10:11:53 +02:00
2026-06-28 10:59:46 +02:00
1. **Tunnel** — FLOSSFirewall up as `wg1` peer; ping
`10.13.0.1 ↔ 10.13.0.9` .
2026-06-28 10:11:53 +02:00
2. **Caddy backend** — from the VPS,
2026-06-28 10:59:46 +02:00
`curl -H 'Host: …tappaas…' 10.13.0.9:80` .
2026-06-28 10:11:53 +02:00
3. **VPS edge** — add cert + route + DNS; off-site
2026-06-28 10:59:46 +02:00
`curl https://<svc>.tappaas.makerfloss.eu` returns a valid cert.
---
## Phasing — internal & later (steps 4– 5)
4. **Internal DNS** — add the `*.tappaas` override on the FLOSSFirewall; a
cluster node resolves to Caddy's local IP and gets Caddy's own cert (no
VPS round-trip).
5. ** (Later)** makerspace LAN view — conditional-forward + firewall pinhole
on the OrangeMakers router.
2026-06-28 10:11:53 +02:00
---
## Isolation — the hard requirement
- **Split-tunnel** (`AllowedIPs = 10.13.0.0/24` ) — the cluster never egresses
through the VPS; nothing on `wg1` reaches the makerspace or homelab.
- VPS→Caddy locked to `tcp/80 from 10.13.0.1` on the wg interface.
- Backend hop encrypted inside WireGuard.
- **No public-DNS-write credential leaves the VPS** — the reason TLS terminates
there, not via passthrough.
---
## Risks & open items
- **Caddy redirect** — the wg-interface listener must _not_ force HTTPS-redirect,
or the VPS hits a loop (mf01's known gotcha).
- **YAML safety** — a syntax error in `tappaas-delegate.yml` breaks the whole
VPS file provider; keep the regex single-quoted.
- **`10.13.0.9` free?** — confirm before assigning.
- **TaPPaaS config repo TBD** — the FLOSSFirewall/Caddy/DNS config home is not
yet identified.
- **Phase 5** depends on OrangeMakers router cooperation.
---
## Summary & next steps
- Reuse the **proven mf01 pattern** — terminate TLS at the VPS, proxy over
`wg1` to TaPPaaS Caddy, split-horizon DNS for the internal view.
- VPS side is a small, additive, **zero-new-tech** change.
- **Next:** identify the TaPPaaS config repo, then write the implementation plan
and execute phases 1– 4.
_Design: `MakerFLOSS_Troubleshooting/docs/superpowers/specs/2026-06-28-tappaas-vps-publishing-design.md` _