feat: kit-busrouter v2.0 — complete Synology + GL fleet router platform

Includes:
- package/ GL-XE3000 kit-busrouter (opkg)
- scripts/provision.sh (GL) and provision-synology.sh (Synology)
- syno-balance/ — new WAN balancer replacing aiwanbal (SmartWAN adapter)
- kit-connect/ — unified connectivity SPK (Tailscale + reverse SSH)
- docs/deployment/synology-rt2600ac-checklist.md — 62-point checklist
- docs/provisioning/device-identity.md — fleet identity spec
- docs/pilot/checklist.md — field pilot validation
- x4078_20260721.dss — reference config backup

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 00:07:14 +00:00
commit f15ac69925
41 changed files with 5083 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
#!/bin/sh
# wg-mgmt-diagnose.sh — READ-ONLY diagnosis of the WG mgmt tunnel on the bench router.
# Run ON THE ROUTER over LAN: ssh root@192.168.8.1 (pw kitPLANE1!!), then: sh wg-mgmt-diagnose.sh
# Safe: only reads state + captures packets. Mutates nothing.
# Context: docs/handoff/2026-07-01-wg-mgmt-incident-and-resume.md
set +e
HUB_WG=10.88.0.1
MGMT_SRC=10.88.0.2
HUB_PUB=167.172.237.162
echo "===== A. FULL WG state (THE missing datapoint — check persistent-keepalive + allowed-ips) ====="
wg show
echo
echo "===== routing / policy (should steer mgmt-sourced traffic into table 1001) ====="
echo "-- ip rule --"; ip rule
echo "-- table 1001 --"; ip route show table 1001
echo "-- default routes --"; ip route show | grep -E '^default'
echo "-- underlay path to hub --"; ip route get "$HUB_PUB"
echo "-- mgmt-sourced return path --"; ip route get "$HUB_WG" from "$MGMT_SRC" 2>/dev/null
echo "-- rp_filter (expect 0; NOT the cause) --"
for f in /proc/sys/net/ipv4/conf/all/rp_filter /proc/sys/net/ipv4/conf/eth0/rp_filter \
/proc/sys/net/ipv4/conf/rmnet_mhi0/rp_filter /proc/sys/net/ipv4/conf/wgclient1/rp_filter; do
[ -f "$f" ] && echo " $f = $(cat "$f")"
done
echo "-- iface MTUs --"
for i in eth0 rmnet_mhi0 wgclient1; do ip link show "$i" 2>/dev/null | sed -n 's/.*\(mtu [0-9]*\).*/ '"$i"': \1/p'; done
echo
echo "===== B. Live capture: watch fiber(eth0) WG + decrypted(wgclient1) while pinging the hub ====="
echo " [eth0] = encrypted WG on the fiber underlay ; [wg] = decrypted inner packets"
( timeout 12 tcpdump -ni eth0 udp port 51820 2>/dev/null | sed 's/^/[eth0] /' & )
( timeout 12 tcpdump -ni wgclient1 2>/dev/null | sed 's/^/[wg] /' & )
sleep 1
ping -c 8 -W 2 -I "$MGMT_SRC" "$HUB_WG"
echo "ping rc=$?"
wait 2>/dev/null
echo
echo "===== INTERPRET ====="
cat <<'EOF'
* wg show 'persistent keepalive: (none)' -> hypothesis #1 (NAT mapping expiry). Fix: keepalive.
* hub-peer 'allowed ips' lacks 10.88.0.1 -> hypothesis #2. Replies get cryptokey-dropped.
* [eth0] shows OUTBOUND + INBOUND :51820 -> hub replies DO arrive on fiber -> decrypt/inner issue.
* [eth0] shows OUTBOUND only -> router pkts not leaving OR hub not returning -> coordinate hub capture.
* [wg] shows echo-request but no echo-reply -> confirms replies not reaching inner iface.
Next: apply scripts/diag/wg-mgmt-fix.sh (keepalive first). See the handoff doc.
EOF
+58
View File
@@ -0,0 +1,58 @@
#!/bin/sh
# wg-mgmt-fix.sh — apply ONE mgmt-tunnel robustness fix at a time, then bounce wgclient1.
# Run ON THE ROUTER over LAN: ssh root@192.168.8.1 (pw kitPLANE1!!)
# sh wg-mgmt-fix.sh keepalive # set persistent_keepalive=25 (TRY FIRST)
# sh wg-mgmt-fix.sh mtu # set wgclient1 mtu=1280 (fixes PMTU black-holes / SSH data)
# sh wg-mgmt-fix.sh rpfilter # persist loose rp_filter (=2) + hotplug re-assert
# sh wg-mgmt-fix.sh all # keepalive + mtu + rpfilter
# MUTATING but reversible (each is a uci change). Bounces the tunnel ~5s; touches nothing else.
# After each: re-test ping -c3 -W2 -I 10.88.0.2 10.88.0.1 (expect replies).
# Rationale + goal (mgmt over EITHER WAN): docs/handoff/2026-07-01-wg-mgmt-incident-and-resume.md
set -e
IFACE=wgclient1
bounce() { echo ">> uci commit network; ifup $IFACE"; uci commit network; ifup "$IFACE"; sleep 5; }
do_keepalive() {
echo "== persistent_keepalive=25 on $IFACE (hold NAT mapping open on whichever WAN) =="
uci set network.$IFACE.persistent_keepalive='25'
bounce
}
do_mtu() {
echo "== mtu=1280 on $IFACE (safe under cellular + ATT-fiber/PPPoE path MTUs) =="
uci set network.$IFACE.mtu='1280'
bounce
}
do_rpfilter() {
echo "== persist loose rp_filter (=2) so multi-WAN policy-routed mgmt isn't dropped =="
grep -q 'busrouter: loose reverse-path' /etc/sysctl.conf 2>/dev/null || cat >> /etc/sysctl.conf <<'EOF'
# busrouter: loose reverse-path filtering for multi-WAN WG mgmt failover
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
EOF
# apply now
sysctl -w net.ipv4.conf.all.rp_filter=2 >/dev/null
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 2 > "$f"; done
# re-assert on WAN flaps (GL DHCP hooks may re-tighten per-iface)
mkdir -p /etc/hotplug.d/iface
cat > /etc/hotplug.d/iface/99-busrouter-rpfilter <<'EOF'
#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 2 > "$f" 2>/dev/null; done
EOF
chmod +x /etc/hotplug.d/iface/99-busrouter-rpfilter
echo " rp_filter now: all=$(cat /proc/sys/net/ipv4/conf/all/rp_filter)"
}
case "$1" in
keepalive) do_keepalive ;;
mtu) do_mtu ;;
rpfilter) do_rpfilter ;;
all) do_keepalive; do_mtu; do_rpfilter ;;
*) echo "usage: $0 {keepalive|mtu|rpfilter|all}"; exit 2 ;;
esac
echo
echo ">> Now verify: ping -c3 -W2 -I 10.88.0.2 10.88.0.1 (replies = mgmt tunnel healthy)"