b682344471
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XMForrE4c1wZxd9LukxYVt
125 lines
7.0 KiB
Markdown
125 lines
7.0 KiB
Markdown
# felhom.eu — task reports
|
|
|
|
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
|
|
|
|
## Tailscale on DooPlex + felhom-pve — make the N100 location-independent — 2026-07-19
|
|
|
|
**Not a code change.** Network/ops on two production hosts (DooPlex, felhom-pve). Run supervised,
|
|
normal permission prompts, one host at a time, verify-after-every-mutation. Baseline `felhom.eu`
|
|
`a771cda`.
|
|
|
|
### 1. Part 0 audit (verbatim highlights) + dependency classification
|
|
|
|
```
|
|
# felhom-pve host — STATIC, not DHCP (contradicted the operator's expectation)
|
|
iface vmbr0 inet static / address 192.168.0.162/24 / gateway 192.168.0.1
|
|
resolv.conf: search local / nameserver 192.168.0.250 (pi-hole)
|
|
|
|
# PBS is OFFSITE, not on 192.168.0.180 (contradicted the task premise)
|
|
storage.cfg: pbs felhom-pbs server 10.77.0.1 datastore felhom-offsite namespace demo-felhom
|
|
ip route get 10.77.0.1 -> dev wg-felhom src 10.77.0.2
|
|
wg-felhom endpoint = 167.233.158.164:443 (Hetzner, public); handshake fresh, 3.75 GiB sent
|
|
|
|
# guest 9201 — already DHCP; grep 192.168.0.x found the pinned control-plane endpoint
|
|
pct config 9201 net0: ...,ip=dhcp
|
|
9201:/etc/felhom-bootstrap/bootstrap.json "endpoint": "192.168.0.162:8443"
|
|
felhom-agent listen_addr = 192.168.0.162:8443 (LISTEN 192.168.0.162:8443 users:(("felhom-agent")))
|
|
|
|
# other
|
|
grep 192.168.0.x in /etc/pve /etc/cron /etc/systemd (excl .162): (none)
|
|
pve-firewall: disabled/running (no Tailscale allow-rule needed)
|
|
DooPlex ipv4 ip_forward = 1 (k3s), ipv6 = 0 ; both hosts Debian 13 trixie
|
|
```
|
|
|
|
| Dep | Where | Address | Survives the move? |
|
|
|---|---|---|---|
|
|
| PBS backup | host storage.cfg | `10.77.0.1` via `wg-felhom`→Hetzner:443 | **Yes** — offsite tunnel, internet-only |
|
|
| Default gateway | host | `192.168.0.1` | Yes — DHCP-derived once host is DHCP |
|
|
| DNS (pi-hole) | host + guest | `192.168.0.250` | Yes for general DNS; `gitea.dooplex.hu` split-horizon won't resolve off-LAN → **finding** |
|
|
| **Agent listen + guest endpoint** | agent.json + guest bootstrap.json | **`192.168.0.162:8443`** | **NO** — hard-pinned to host LAN IP; L2-bridged → subnet routes don't help → **finding, record-not-fix** |
|
|
| `*.demo-felhom.eu` LAN forward | home pi-hole → box | inbound | LAN-local demo breaks off-LAN; Cloudflare Tunnel external access unaffected → note only |
|
|
|
|
### 2. Tailscale nodes
|
|
|
|
| Node | Tailnet IPv4 | Route advertised | Key expiry | How installed |
|
|
|---|---|---|---|---|
|
|
| `dooplex` | `100.107.87.53` | `192.168.0.0/24` (approved) | disabled | **pre-existing** k3s pod `admin-system/tailscale` (hostNetwork, GitOps) — *not* installed by this task |
|
|
| `felhom-pve` | `100.70.170.35` | — | disabled (operator-confirmed) | host apt package (trixie repo), `--accept-dns=false` |
|
|
|
|
`tailscale status` from the N100: both nodes listed/online. resolv.conf on felhom-pve **byte-identical**
|
|
after `tailscale up` (`CorpDNS:false`).
|
|
|
|
**Course correction:** the task assumed Tailscale had to be *installed* on DooPlex and that PBS lived
|
|
on `.180`. Both were wrong — DooPlex already ran Tailscale as a GitOps k3s pod (the operator was
|
|
right; my `which tailscale`/systemd probe was too narrow and missed it), and PBS is offsite. The
|
|
redundant host-level Tailscale I briefly installed on DooPlex was **fully purged** (package + repo +
|
|
keyring + sysctl file), verified: k3s `tailscale0` and the `dooplex` node stayed up, `ip_forward`
|
|
still 1.
|
|
|
|
### 3. accept-routes spike (§3.1) — CONFIRMED degradation, rolled back
|
|
|
|
Enabling `--accept-routes` on felhom-pve *while on `192.168.0.0/24`*:
|
|
|
|
```
|
|
PRE : ip route get 192.168.0.180 -> dev vmbr0 src 192.168.0.162 ; ping .180 avg 0.3 ms
|
|
POST: ip route get 192.168.0.180 -> dev tailscale0 table 52 src 100.70.170.35 ; ping .180 avg 68 ms (max 136)
|
|
table 52 contains: 192.168.0.0/24 dev tailscale0 ; ip rule 5270: from all lookup 52 (outranks main)
|
|
-> local subnet hijacked onto the tunnel; inbound SSH went asymmetric and STALLED
|
|
PBS (10.77.0.1 via wg-felhom) UNAFFECTED
|
|
ROLLBACK (via the tailnet path 100.70.170.35, which was immune): tailscale set --accept-routes=false
|
|
-> route to .180 back on vmbr0 direct
|
|
```
|
|
|
|
Verdict: keep `--accept-routes=false` at home; it is a **travel-only opt-in** (safe on a foreign
|
|
subnet). Documented with the reasoning in `documentation/operations/tailscale.md`.
|
|
|
|
### 4. SSH chain over the tailnet (§3.2)
|
|
|
|
`~/.ssh/config` on DooPlex: `Host felhom-pve` → `HostName 100.70.170.35`; added `Host felhom-pve-lan`
|
|
→ `192.168.0.162`. Proof:
|
|
|
|
```
|
|
ssh felhom-pve -> pve-manager/9.2.2 ; pct exec 9201 docker ps -> felhom-controller:0.148.0 Up (healthy)
|
|
tailscale ping 100.70.170.35 -> pong via 192.168.0.162:41641 in 1ms (DIRECT over LAN, not DERP)
|
|
ssh felhom-pve-lan -> OK (LAN fallback works)
|
|
```
|
|
|
|
### 5. Part 4 — host static→DHCP: **DONE** (operator at console, reservation set)
|
|
|
|
Reservation MAC `68:1d:ef:5d:a6:64`→`192.168.0.162` set by operator first (so the LAN-pinned agent
|
|
keeps working at home). Applied detached (`systemd-run … ifreload -a`); result:
|
|
|
|
```
|
|
ifreload rc=0 ; vmbr0 inet dhcp -> got 192.168.0.162 back (reservation)
|
|
default via 192.168.0.1 ; felhom-agent active, still bound 192.168.0.162:8443 (no restart)
|
|
guest 9201: 12 containers ; Tailscale still direct 1ms
|
|
```
|
|
|
|
Exact revert staged on the box: `/root/interfaces.static-revert-20260719`. resolv.conf is now
|
|
DHCP-managed (`.250` + `.1`) instead of the old static `search local` — expected (Tailscale didn't
|
|
touch it; accept-dns rule intact).
|
|
|
|
### 6. Off-LAN legs NOT validated at home → vacation-day checklist
|
|
|
|
Cannot be tested until the box is on a foreign LAN: PBS from a foreign subnet, DERP-relay fallback,
|
|
off-LAN `gitea.dooplex.hu` resolution. The step-by-step is in `documentation/operations/tailscale.md`
|
|
(§ *Vacation-day checklist*) — notably `ssh felhom-pve "pvesm status | grep -i pbs"` is the real
|
|
off-LAN PBS test.
|
|
|
|
### 7. Findings recorded, NOT fixed
|
|
|
|
1. **Control plane pinned to `192.168.0.162`** (HIGH for travel): `felhom-agent` `listen_addr` and
|
|
guest `bootstrap.json` `endpoint` both = `192.168.0.162:8443`. Off-LAN the agent can't bind →
|
|
agent down → controller can't reach it. Subnet routes don't help (L2 bridge). Needs a design
|
|
change (bind `0.0.0.0` + stable guest→host path). **The N100 is reachable and backs up off-LAN,
|
|
but its local operator plane is not yet portable.**
|
|
2. **Off-LAN gitea DNS**: `gitea.dooplex.hu` (pi-hole split-horizon) won't resolve on a foreign LAN;
|
|
image pulls while travelling need the travel `--accept-routes` toggle + a temporary `/etc/hosts`
|
|
entry. Contingency ("Plan B") documented, not armed.
|
|
|
|
### 8. Commit
|
|
|
|
Docs commit: `83c47ea` (felhom.eu). Files: `documentation/operations/tailscale.md` (new),
|
|
`CLAUDE.md` + `skills/felhom-build-deploy/SKILL.md` env-table notes, `CONTEXT.md` decision entry,
|
|
this `REPORT.md`. No secrets committed (tunnel keys/tokens/PBS fingerprint referenced out-of-band).
|