Files
allen f15ac69925 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>
2026-07-22 00:07:14 +00:00

3.5 KiB

Inbound management SSH over the WireGuard tunnel

How the busfleet hub reaches a GL-XE3000 router for management, and how to fix it when inbound SSH over the tunnel is broken.

How it works

The router runs a WireGuard client (wgclient1, proto=wgclient) that dials the hub at 167.172.237.162:51820. Once the tunnel is up the router holds 10.88.0.2/32 and the hub is 10.88.0.1. The hub SSHes inbound to 10.88.0.2:22 over that tunnel using the busfleet-hub-jump key.

The key detail: on OpenWrt the WG client interface is in its own firewall zone (wgclient1), which defaults to input='DROP'. Traffic arriving over the tunnel is evaluated by the zone_wgclient1_input iptables chain — not zone_wan_input. So the mgmt-SSH accept rule must have its source zone set to wgclient1, or it lands in the wrong chain and never matches (tunnel SSH silently hits the zone DROP).

Provisioning a router

  1. Confirm the WG client zone name (may differ per unit):

    uci show network | grep -i wgclient          # interface, e.g. network.wgclient1
    uci show firewall | grep -iE 'name=|\.network=|input='   # find its zone + input policy
    
  2. Allow inbound mgmt SSH over the tunnel. Bind the rule's src to the WG client zone (not wan), restricted to the hub subnet:

    uci add firewall rule
    uci set firewall.@rule[-1].name='Allow-WG-mgmt-SSH'
    uci set firewall.@rule[-1].src='wgclient1'        # the ACTUAL WG zone from step 1
    uci set firewall.@rule[-1].proto='tcp'
    uci set firewall.@rule[-1].dest_port='22'
    uci set firewall.@rule[-1].family='ipv4'
    uci set firewall.@rule[-1].src_ip='10.88.0.0/24'
    uci set firewall.@rule[-1].target='ACCEPT'
    uci commit firewall && /etc/init.d/firewall restart
    
  3. Install the hub jump key:

    echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMS842ZbXPXHbVd9IjyVGubq7M/yQA/cn/vHgB5R0/ZE busfleet-hub-jump' >> /etc/dropbear/authorized_keys
    chmod 600 /etc/dropbear/authorized_keys
    

Verifying

Use wg show as the source of truth for tunnel health — a recent latest handshake plus non-zero transfer counters means the data path is live:

wg show                                         # endpoint, latest handshake, transfer
iptables -S zone_wgclient1_input | grep 'dport 22'   # exactly one ACCEPT from 10.88.0.0/24

Gotchas:

  • BusyBox nc has no -v/-z flags (nc [IPADDR PORT] only), and 51820 is UDP — don't rely on nc -vz to test the tunnel. Use wg show.
  • The hub does not answer ICMP over the tunnel, so ping 10.88.0.1 shows 100% loss even when the tunnel is healthy. The definitive end-to-end test is the hub SSHing in.

Troubleshooting: hub can't SSH in

  1. wg show — is there a recent handshake? If not, the tunnel is down (check WAN/5G, the hub endpoint, and keys) before looking at the firewall.

  2. uci show firewall | grep Allow-WG-mgmt-SSH up through the rule — confirm src is the WG client zone (wgclient1), not wan. This is the most common misconfiguration:

    uci set firewall.<section>.src='wgclient1'
    uci commit firewall && /etc/init.d/firewall restart
    
  3. grep busfleet-hub-jump /etc/dropbear/authorized_keys — key present, file perms 600.

History

  • 2026-07-01 — Fixed inbound mgmt SSH on a unit whose Allow-WG-mgmt-SSH rule was bound to src='wan' instead of src='wgclient1', so tunnel SSH hit the wgclient1 zone DROP. Repointed the rule to wgclient1 and installed the busfleet-hub-jump key.