diff --git a/docs/caddy-reverse-proxy.md b/docs/caddy-reverse-proxy.md new file mode 100644 index 0000000..2beb4f9 --- /dev/null +++ b/docs/caddy-reverse-proxy.md @@ -0,0 +1,190 @@ +# Caddy Reverse Proxy Setup + +Caddy sits in front of the SvelteKit app and handles all access methods: +- Internal network (LAN/Tailscale) +- Tor hidden service +- Yggdrasil mesh network +- Public domain with automatic HTTPS + +## 1. Install Caddy + +```bash +apt install -y debian-keyring debian-archive-keyring apt-transport-https curl +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list +apt update +apt install caddy +``` + +## 2. Install Tor + +```bash +apt install tor +``` + +Edit `/etc/tor/torrc`: + +``` +HiddenServiceDir /var/lib/tor/bflr/ +HiddenServicePort 80 127.0.0.1:8880 +``` + +Restart and get your .onion address: + +```bash +systemctl restart tor +cat /var/lib/tor/bflr/hostname +``` + +## 3. Configure Caddy + +Edit `/etc/caddy/Caddyfile`: + +```caddy +# ─── Shared config ─────────────────────────────────────────────────── + +(proxy) { + reverse_proxy 127.0.0.1:3000 { + header_up Host collection.newedge.house + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} + } +} + +(common) { + encode gzip + request_body { + max_size 50MB + } +} + +# ─── Public domain (automatic HTTPS via Let's Encrypt) ─────────────── + +collection.newedge.house { + import common + reverse_proxy 127.0.0.1:3000 { + header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto https + } +} + +# ─── Internal / LAN access (HTTP on port 80) ───────────────────────── + +:80 { + import common + import proxy +} + +# ─── Tor hidden service (HTTP on port 8880, Tor connects here) ─────── + +:8880 { + import common + import proxy + bind 127.0.0.1 +} + +# ─── Yggdrasil (HTTP on port 80, bind to Yggdrasil IPv6) ───────────── +# Replace with your actual Yggdrasil address from: yggdrasilctl getSelf + +http://[200:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]:80 { + import common + import proxy +} +``` + +**Important:** Replace `200:xxxx:...` with your actual Yggdrasil IPv6 address. + +The `(proxy)` snippet sets `Host: collection.newedge.house` on all non-public routes so SvelteKit's CSRF check passes regardless of how you access the app. + +## 4. Update the SvelteKit service + +Change the app to only listen on localhost since Caddy handles external access: + +```bash +nano /home/bflr/buildfor_life_repair/.env +``` + +``` +HOST=127.0.0.1 +PORT=3000 +``` + +Update systemd if HOST is set there too: + +```bash +nano /etc/systemd/system/bflr.service +``` + +```ini +Environment=HOST=127.0.0.1 +``` + +## 5. Firewall + +Only Caddy needs external access: + +```bash +# Allow HTTP/HTTPS from anywhere +ufw allow 80/tcp +ufw allow 443/tcp + +# Block direct app access from outside +ufw deny 3000/tcp +``` + +## 6. Start everything + +```bash +systemctl daemon-reload +systemctl restart bflr +systemctl enable --now caddy +systemctl restart tor +``` + +## 7. Verify + +```bash +# Public domain +curl -s -o /dev/null -w "%{http_code}" https://collection.newedge.house/login + +# Internal +curl -s -o /dev/null -w "%{http_code}" http://localhost/login + +# Tor (from Tor Browser) +# http://your-onion-address.onion/login + +# Yggdrasil (from a Yggdrasil peer) +# http://[200:xxxx:...]/login +``` + +## How it works + +``` +Internet ──► collection.newedge.house:443 ──► Caddy ──► :3000 (app) +LAN ──► server-ip:80 ──► Caddy ──► :3000 (app) +Tor ──► .onion:80 ──► tor ──► :8880 ──► Caddy ──► :3000 (app) +Yggdrasil──► [200:...]:80 ──► Caddy ──► :3000 (app) +``` + +All routes set `Host: collection.newedge.house` so SvelteKit CSRF passes. +Caddy handles TLS for the public domain automatically via Let's Encrypt. + +## Troubleshooting + +```bash +# Check Caddy status +systemctl status caddy +journalctl -u caddy -f + +# Check Tor status +systemctl status tor +cat /var/lib/tor/bflr/hostname + +# Check Yggdrasil address +yggdrasilctl getSelf + +# Test reverse proxy +curl -H "Host: collection.newedge.house" http://127.0.0.1:3000/login +```