3.7 KiB
title, created, updated, type, namespace, tags, sources, confidence
| title | created | updated | type | namespace | tags | sources | confidence | |||
|---|---|---|---|---|---|---|---|---|---|---|
| WireGuard VPN — Eagle to Kraken | 2026-05-23 | 2026-05-23 | tech | personal |
|
|
high |
WireGuard VPN — Eagle to Kraken
Split-tunnel VPN connecting Eagle (Mac M4, home) to Kraken (RPi5, home) via a VPS relay. Enables SSH to Kraken from anywhere and routes Time Machine backups over the tunnel. Two VPS interfaces avoid hairpin forwarding.
Topology
Eagle (10.99.0.2) ←→ wg0 VPS (10.99.0.1) ←→ wg1 VPS (10.99.1.1) ←→ Kraken (10.99.1.2)
:51820 :51821
SNAT rewrites source address: Eagle packets arrive at Kraken with src
10.99.1.1 (VPS wg1), not Eagle's 10.99.0.2. FORWARD runs wg0→wg1
on the VPS with nftables.
VPN Addresses
| Node | VPN IP |
|---|---|
| VPS wg0 | 10.99.0.1 |
| VPS wg1 | 10.99.1.1 |
| Eagle | 10.99.0.2 |
| Kraken | 10.99.1.2 |
kraken hostname resolves via dnsmasq on VPS (DNS = 10.99.0.1 in Eagle's
wg0.conf). DNS is scoped to the kraken domain only (see DNS section).
Persistence
| Component | Node | How it survives reboot |
|---|---|---|
| wg-quick@wg0 + wg-quick@wg1 | VPS | systemd enabled |
| PostUp FORWARD + SNAT rules | VPS | embedded in /etc/wireguard/wg0.conf |
| nftables (10.99.0.0/16 forward) | VPS | /etc/nftables.conf, systemd enabled |
dnsmasq (kraken → 10.99.1.2) |
VPS | /etc/dnsmasq.d/vpn-hosts.conf, systemd enabled |
| wg-quick@wg0 | Kraken | systemd enabled |
| wg-auto LaunchDaemon | Eagle | /Library/LaunchDaemons/top.eagle.wg-auto.plist |
Auto-Connect on Eagle
/usr/local/bin/wg-auto.sh polls every 30 seconds via launchd
(StartInterval, not WatchPaths):
- At home (router MAC
f0:79:59:77:9b:70visible on ARP) →wg-quick down - Off home network →
wg-quick up
Why StartInterval and not WatchPaths: WatchPaths triggered a race —
wg-quick down changes DNS via networksetup, which writes to
/Library/Preferences/SystemConfiguration/, which re-fires launchd,
tearing the tunnel down immediately after connecting.
DNS (Scoped Resolver)
wg0.conf uses no global DNS =. PostUp/PostDown manage a
macOS scoped resolver for the kraken domain only:
PostUp = mkdir -p /etc/resolver && \
echo "nameserver 10.99.0.1" > /etc/resolver/kraken && \
killall -HUP mDNSResponder
PostDown = rm -f /etc/resolver/kraken && killall -HUP mDNSResponder
Result: only kraken resolves via VPS dnsmasq. Global DNS and Wi-Fi IP
are untouched — prevents address-bar breakage during tunnel transitions.
Time Machine
| Setting | Value |
|---|---|
| Old destination (broken) | smb://timemachine@kraken._smb._tcp.local./TimeMachine |
| New destination (working) | smb://timemachine@kraken/TimeMachine |
mDNS (_smb._tcp.local) doesn't work off the local LAN. VPN DNS (kraken
→ 10.99.1.2 via dnsmasq) works from anywhere. Container on Kraken:
mbentley/timemachine:smb, restart: unless-stopped.
Public Keys
| Node | Public Key |
|---|---|
| VPS wg0 | 6W6hSw0JFLm0BbyeNp1g7wF7dKKTZmGvPRdir68mz0w= |
| VPS wg1 | ssRV2497NQ3Lfzvx/FLO0jDlcCXdK/RReJQ36i0yuR8= |
| Eagle | dDgIjBUNguodOHWoz7iFsImvKhteodHcFWM8mMe4UiE= |
| Kraken | 8kIdCKMIoMsW09/aQX6+pU0SS/rN4PysJL59w17eGRg= |
Diagnostics
# Eagle — check tunnel state
sudo wg show
ping kraken
# VPS
ssh root@91.207.28.205 "wg show all"
# Kraken
ssh kraken "sudo wg show"
# Eagle auto-connect log
cat /var/log/wg-auto.log
Related
- tech/kraken-network — Kraken SSH access, media volume paths
- personal-os-architecture — Eagle hardware, home infra overview