Add WireGuard, DNS and more to the web UI and router-setup
Web UI: a WireGuard page (tunnels, peers, keys made on the router, client configs with a QR code, import of wg-quick configs, live status), a DNS page (records, wildcards, forward zones), interface dropdowns with VLAN devices, IPv6 options and a local domain. router-setup asks about VLANs, IPv6 and the domain. The router publishes its own name in DNS and hands the local domain to DHCP clients; wg and jq are on the router. Includes a script that takes over antigua's tunnels. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
Executable
+115
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env bash
|
||||
# Takes over antigua's three WireGuard tunnels (freifunk, family, mobile-clients)
|
||||
# on a router installed from the generic installer. Run as root on the router.
|
||||
#
|
||||
# import-antigua-wireguard.sh KEYDIR
|
||||
#
|
||||
# KEYDIR holds the secret files copied from antigua's /opt/wireguard:
|
||||
# freifunk.priv family.priv mobile-clients.priv troisdorf.psk mobile-clients.psk
|
||||
# e.g. from antigua:
|
||||
# tar -C /opt/wireguard -czf - freifunk.priv family.priv mobile-clients.priv \
|
||||
# troisdorf.psk mobile-clients.psk | ssh root@ROUTER 'mkdir -p /root/wg && tar -xzf - -C /root/wg'
|
||||
#
|
||||
# The keys are installed as 0600 files in /var/lib/router/wireguard; the tunnels
|
||||
# (public settings only), the firewall rules between them and the LAN are
|
||||
# merged into settings.json. Nothing is applied: look at the WireGuard page,
|
||||
# then `router-apply` and `router-confirm`. Never run both boxes with the same
|
||||
# keys at once: stop the tunnels on antigua first.
|
||||
#
|
||||
# The tunnels are those of examples/home, translated from antigua's
|
||||
# wireguard.nix: freifunk accepts 0.0.0.0/0 there but routes just the three
|
||||
# treasure-maps.com hosts (masqueraded); the road-warrior tunnel is called
|
||||
# `mobile` (the interface name wg-mobile-clients would be too long).
|
||||
set -euo pipefail
|
||||
|
||||
state=${STATE_DIR:-/var/lib/router}
|
||||
settings=${SETTINGS:-$state/config/settings.json}
|
||||
keys=${1:-}
|
||||
[ -d "$keys" ] || { echo "usage: $0 KEYDIR" >&2; exit 2; }
|
||||
[ "$(id -u)" -eq 0 ] || [ -n "${STATE_DIR:-}" ] || { echo "must run as root" >&2; exit 1; }
|
||||
command -v jq >/dev/null || { echo "jq is needed" >&2; exit 1; }
|
||||
[ -f "$settings" ] || { echo "no $settings" >&2; exit 1; }
|
||||
|
||||
# antigua's file -> the name it gets here.
|
||||
declare -A install=(
|
||||
[freifunk.priv]=freifunk.key
|
||||
[family.priv]=family.key
|
||||
[mobile-clients.priv]=mobile.key
|
||||
[troisdorf.psk]=family-troisdorf.psk
|
||||
[mobile-clients.psk]=mobile-laptop.psk
|
||||
)
|
||||
for f in "${!install[@]}"; do
|
||||
[ -s "$keys/$f" ] || { echo "missing $keys/$f" >&2; exit 1; }
|
||||
# A WireGuard key is 32 bytes in base64: 44 characters.
|
||||
[[ $(tr -d '[:space:]' < "$keys/$f") =~ ^[A-Za-z0-9+/]{43}=$ ]] || { echo "$f is not a WireGuard key" >&2; exit 1; }
|
||||
done
|
||||
if jq -e '.router.wireguard // {} | has("freifunk") or has("family") or has("mobile")' "$settings" >/dev/null; then
|
||||
echo "settings.json has a freifunk, family or mobile tunnel already; not touching it" >&2
|
||||
exit 1
|
||||
fi
|
||||
lan=$(jq -r '[.router.lans[]?.ipv4.address][0] // empty' "$settings")
|
||||
lan_zone=$(jq -r '[.router.lans // {} | to_entries[] | (.value.zone // .key)][0] // empty' "$settings")
|
||||
[ -n "$lan" ] && [ -n "$lan_zone" ] || { echo "settings.json has no LAN" >&2; exit 1; }
|
||||
|
||||
dest=$state/wireguard
|
||||
install -d -m 0700 "$dest"
|
||||
for f in "${!install[@]}"; do
|
||||
(umask 077; tr -d '[:space:]' < "$keys/$f" > "$dest/${install[$f]}"; echo >> "$dest/${install[$f]}")
|
||||
done
|
||||
|
||||
cp -a "$settings" "$settings.before-wireguard-import"
|
||||
jq --arg dest "$dest" --arg lan "$lan" --arg lanzone "$lan_zone" '
|
||||
.router.wireguard = ((.router.wireguard // {}) + {
|
||||
freifunk: {
|
||||
privateKeyFile: "\($dest)/freifunk.key",
|
||||
masquerade: true,
|
||||
addresses: ["10.255.1.8/32", "fd80:3ea2:e399:203a::8/128"],
|
||||
peers: { supernode: {
|
||||
publicKey: "5B/YTaDPVWVApUyHshJp899iXXlBy8rBqJUpYvKo+1s=",
|
||||
endpoint: "5.9.220.114:42001",
|
||||
persistentKeepalive: 15,
|
||||
allowedIPs: ["185.90.196.65/32", "185.90.196.97/32", "185.90.196.129/32"]
|
||||
} }
|
||||
},
|
||||
family: {
|
||||
privateKeyFile: "\($dest)/family.key",
|
||||
listenPort: 36432,
|
||||
allowManagement: true,
|
||||
dns: true,
|
||||
sourceAddresses: [$lan],
|
||||
peers: { troisdorf: {
|
||||
publicKey: "BsQODhcHnEN4tXn60t72iejZvgYvVNt5BDVK+69+RgM=",
|
||||
endpoint: "fw-tdf.stinnesbeck.com:36432",
|
||||
persistentKeepalive: 25,
|
||||
presharedKeyFile: "\($dest)/family-troisdorf.psk",
|
||||
allowedIPs: ["10.1.0.0/24", "fd73:f65e:6b64::/48"]
|
||||
} }
|
||||
},
|
||||
mobile: {
|
||||
privateKeyFile: "\($dest)/mobile.key",
|
||||
listenPort: 36433,
|
||||
allowManagement: true,
|
||||
dns: true,
|
||||
peers: { laptop: {
|
||||
publicKey: "Jts5u8zIs28v6RIEYCCufDDiWXf+gbElT63wUFWQxX4=",
|
||||
persistentKeepalive: 25,
|
||||
presharedKeyFile: "\($dest)/mobile-laptop.psk",
|
||||
allowedIPs: ["10.2.0.2/32"]
|
||||
} }
|
||||
}
|
||||
})
|
||||
# antigua trusted these interfaces completely; spelled out: the LAN and
|
||||
# Troisdorf reach each other, the LAN reaches the freifunk hosts, road
|
||||
# warriors reach the LAN. Nothing initiates from freifunk.
|
||||
| .router.firewall.rules = ((.router.firewall.rules // []) + [
|
||||
{ from: $lanzone, to: "family" },
|
||||
{ from: "family", to: $lanzone },
|
||||
{ from: $lanzone, to: "freifunk" },
|
||||
{ from: "mobile", to: $lanzone }
|
||||
])' "$settings.before-wireguard-import" > "$settings.new"
|
||||
chmod 600 "$settings.new"
|
||||
mv "$settings.new" "$settings"
|
||||
|
||||
echo "Imported freifunk, family and mobile (keys in $dest)."
|
||||
echo "Look at the WireGuard page, then: router-apply, and router-confirm when the LAN still works."
|
||||
echo "The previous settings are in $settings.before-wireguard-import. Remove $keys when done."
|
||||
Reference in New Issue
Block a user