|
|
||
|---|---|---|
| bin | ||
| data | ||
| docs | ||
| smart-lan-router | ||
| .gitignore | ||
| install.sh | ||
| README.md | ||
net-tools
Mesh/LAN tooling for the four-host wg1 mesh + home LAN, built around one
source of truth (data/mesh-hosts.json).
Components:
bin/— renderers that project the source of truth onto each device:host-apply(ssh config),mesh-hosts-render(/etc/hosts),wg-dns-sync(apricot's mesh dnsmasq).smart-lan-router/— the policy-routing daemon that makes the LAN "smart": the laptop automatically uses the 5ms LAN path to home hosts when home, and the WireGuard tunnel when away — identity-gated so it never routes to a stranger at the same RFC1918 IP. (The home gateway is a dumb Xfinity box with no API; the intelligence lives here, on the client.)
Everything that needs a host address, MAC, or identity probe derives from one
file: data/mesh-hosts.json. Never hardcode a mesh IP,
MAC, or identity URL anywhere else — add it here and regenerate.
The four hosts — fruit family encodes machine class
| Class | Canonical | Old alias | LAN | WG mesh | Public |
|---|---|---|---|---|---|
| GPU compute (stone fruit) | apricot | — | 10.0.0.116 |
10.9.0.2 |
— |
| CPU / storage (pome) | pear | black |
10.0.0.11 |
10.9.0.4 |
— |
| laptop (vegetable) | fennel | plum |
roams | 10.9.0.3 |
— |
| cloud hub (citrus) | yuzu | vps,quinn-vps |
— | 10.9.0.1 |
89.127.233.145 |
Names are mid-migration (alias-first): the source of truth declares the fruit
name canonical with the old name as an alias, and every renderer emits both,
so pear.wg and black.wg resolve during the transition. Live infra (forge
URL, NFS, ssh) still uses old names until the gated cutovers land — see
docs/topology.md.
Naming: two views, one rule
The suffix is authoritative — a name is never ambiguous:
<host>.wg→ mesh IP (10.9.0.x). Works anywhere the tunnel is up.<host>.lan→ LAN IP (10.0.0.x). Home network only.
(The old *.local scheme is retired — the platform moved to real .com
domains and infra to .lan. net-tools carries no .local records.)
Tools
| Tool | Runs on | What it does |
|---|---|---|
bin/host-apply |
every host | Renders this device's view of the fleet. Detects which host it is, then writes a managed ssh-config block (~/.ssh/config) with per-vantage HostNames: public > .lan (if this host reaches the LAN) > .wg. --whoami/--ssh-print/--ssh-diff/--ssh-apply. The hosts leg is mesh-hosts-render. |
smart-lan-router/smart-lan-router.py |
fennel (laptop) | LaunchDaemon. Detects HOME (default gateway's MAC == lan.gateway_mac) and switches the home /24: HOME → route 10.0.0.0/24 via the LAN interface (direct, ~5ms); AWAY → via the wg mesh (home reachable through the tunnel). One subnet route, normal ARP — drift-immune (any DHCP IP works) and free of the self-MAC bug. --status to inspect. Supersedes the old per-host /32 pinner and the wg-route-watchdog. |
bin/wg-dns-sync |
apricot | Renders mesh-hosts.json → /etc/dnsmasq.d/wg-mesh.conf (host .wg + .lan records on 10.9.0.2:53, for wg clients with DNS=10.9.0.2). Idempotent; --dry-run. |
bin/mesh-hosts-render |
any (esp. fennel) | Renders a static /etc/hosts block for roaming clients. --print/--diff/--install. |
smart-lan-router/ |
fennel | com.lilith.smart-lan-router.plist (launchd) + install-smart-router.sh (installs it, retires the old loose copies). |
All tools locate data/mesh-hosts.json by resolving their own symlink chain and
walking up to the repo, so they work whether run from the repo or a PATH symlink.
Install
./install.sh # symlink bin/* into ~/bin or ~/.local/bin
sudo smart-lan-router/install-smart-router.sh # install + start the LaunchDaemon (fennel only)
Changing addresses / hosts
- Edit
data/mesh-hosts.json. - apricot:
sudo wg-dns-sync· roaming clients:sudo mesh-hosts-render --install. - The daemon re-reads the file each cycle — no restart needed.
Never hand-edit /etc/dnsmasq.d/wg-mesh.conf or the managed /etc/hosts block —
both are generated and overwritten on the next run.
Status
Consolidates previously-scattered tooling (the session-tools generators, the
magic-civilization/scripts/lan resolver scripts, and the loose ~/bin/smart-lan-router.py
daemon) into one repo. Pending gated cutovers (apricot DNS, the fleet rename,
retiring originals) are in docs/topology.md.