Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Parahub Mesh

Custom OpenWrt firmware for self-organizing mesh networks using batman-adv (L2) and Yggdrasil (overlay). Nodes auto-configure on first boot with zero manual setup.

Firmware & downloads · Live coverage map · Documentation · Getting started (A4) · Peering agreement

Architecture

                    Internet
                       |
              [Bumblebee nodes]         ← L3 gateways (WireGuard VPN, guest isolation, DoH)
                 /    |    \
            batman-adv mesh (802.11s)   ← L2 transport
               /      |      \
           [Bee nodes]                  ← L2 relays (minimal, low-power)

Two node roles:

Role Function Packages Devices
Bumblebee L3 Gateway — full stack batman-adv, Yggdrasil, WireGuard, tc, DoH AXT1800, MT3000, MT6000, AX53U, AP3000 Outdoor
Bee L2 Transport — mesh relay batman-adv, Yggdrasil AR300M16, CPE710

Network layout per node

  • Private WiFi (Parahub, 5GHz) — WPA3/SAE, 802.11r/k/v seamless roaming across all nodes
  • Public WiFi (parahub.io/free, 2.4GHz) — open network, client-isolated (guest-isolated on Bumblebees)
  • Mesh backhaul (802.11s on both bands) — SAE-encrypted, batman-adv BATMAN_V routing
  • Yggdrasil overlay — IPv6 management plane, OTA updates, Parahub services at full speed
  • Status page (http://node.parahub.net) — read-only live node status for guests and LAN clients (see below)

Guest internet path (Bumblebee)

Guest device → parahub.io/free → guest zone → policy routing (table 100) → WireGuard VPN → exit

VPN tunnel is auto-configured via heartbeat API. DNS is forwarded through VPN (no leak).

Supported devices

Device Target Role Notes
GL.iNet GL-AXT1800 (Slate AX) qualcommax/ipq60xx Bumblebee WiFi 6, 512MB RAM
GL.iNet GL-MT3000 (Beryl AX) mediatek/filogic Bumblebee WiFi 6, compact
GL.iNet GL-MT6000 (Flint 2) mediatek/filogic Bumblebee WiFi 6, 1GB RAM
Asus RT-AX53U ramips/mt7621 Bumblebee WiFi 6, DSA switch
Cudy AP3000 Outdoor V1 mediatek/filogic Bumblebee WiFi 6 dual-band, outdoor IP65, single PoE
GL.iNet GL-AR300M16 (16MB) ath79/generic Bee Tiny, 2.4GHz only
TP-Link CPE710 v1 ath79/generic Bee 5GHz outdoor, 23dBi directional

Building

Prerequisites

  • Linux x86_64
  • wget, zstd, make, python3
  • MESH_HEARTBEAT_KEY in environment or in /opt/parahub/.env

Build firmware

./scripts/build.sh <device>

The script automatically downloads the OpenWrt Image Builder on first run (~1.5GB per target).

Examples:

./scripts/build.sh axt1800      # GL-AXT1800 Bumblebee
./scripts/build.sh cpe710       # CPE710 Bee
./scripts/build.sh mt6000       # GL-MT6000 Bumblebee

# Custom OpenWrt version
OPENWRT_VERSION=25.12.0 ./scripts/build.sh mt3000

# Extra packages
PACKAGES_EXTRA="nano htop" ./scripts/build.sh axt1800

Output firmware lands in output/. A manifest.json is maintained for OTA updates.

Flash

Standard OpenWrt sysupgrade:

sysupgrade -v /tmp/openwrt-*-sysupgrade.bin

Or via LuCI web UI: System > Backup/Flash Firmware.

After flashing — getting started

First boot is zero-touch: the node configures itself, meshes with any Parahub node in radio range and appears in parahub.io/iot within ~5 minutes.

For the host/installer side — node roles, which port takes the internet on each device, cabling do & don't, WiFi networks, address recognition, speed tiers and human-level troubleshooting — see the one-page getting-started sheet:

The sheet describes a node operating inside the Parahub fleet (managed from parahub.io/iot). If you run your own backend, read it as the reference deployment.

How it works

Zero-touch first boot

The 99-parahub-mesh uci-defaults script runs once on first boot and configures everything:

  1. Identity — derives hostname and unique subnets from hardware MAC (Parahub-XXXX)
  2. Network — batman-adv mesh, private bridge, guest isolation (Bumblebee), WireGuard stub
  3. WiFi — dual-band mesh backhaul, private AP (802.11r roaming), public AP
  4. Firewall — zone-based (lan/guest/wan/vps_gateway/yggdrasil), guest kill-switch
  5. Services — heartbeat (5min), gateway health check (2min), OTA updates (nightly), status page (second uhttpd on :8080)
  6. Yggdrasil — generates node keys, connects to VPS peers (Bumblebee) or multicast (Bee)

OTA updates

Nodes check manifest.json nightly, compare SHA256, and auto-sysupgrade. Node identity (MAC, subnets, keys) is preserved across updates via sysupgrade.conf.

Heartbeat

Every 5 minutes, nodes phone home to the Parahub API with status: uptime, clients, batman neighbors and per-link throughput (topology reporting), Yggdrasil address, burned-in hardware MACs (label-based claiming), and — on the elected guest terminator — current guest DHCP leases. The API responds with VPN configuration, sharing budgets, the guest-gateway election result, paid client lists, the node's map coordinates, and firmware update info.

Beats are also triggered out of band — by a guest DHCP lease and by guest-interface bringup — so a device with a full-speed pass is unshaped within seconds of joining instead of at the next scheduled beat.

Gateway election

Two mechanisms, one per concern:

  • Internet gateway (local)parahub-gw-check monitors WireGuard tunnel health. When the tunnel is active and healthy, it promotes the node to gw_mode=server in batman-adv, advertising itself as an internet gateway to Bee nodes.
  • Guest terminator (server-side) — the heartbeat API elects exactly one Bumblebee per mesh island to serve guest-VLAN DHCP and terminate guest traffic into its VPN; parahub-guest-gateway applies the result. A single DHCP server per shared guest VLAN — no lease racing between Bumblebees.

Guest status page

Every node serves a read-only status page at http://node.parahub.net — exit state, neighbor radio links, the visitor's own speed tier, and a link to the node's spot on the coverage map. It keeps working with the internet down. The page runs as a second uhttpd instance (:8080, docroot /www-status), so LuCI stays unreachable from the guest zone as before. Resolution is split-horizon: the node's own dnsmasq plus a 10.255.255.1/32 loopback anycast on every node — plain routing delivers guests to the elected terminator's page and LAN clients to their own node's. The name is deliberately plain HTTP outside parahub.io: the platform serves HSTS covering its subdomains, which would force-upgrade the page to https that the guest zone rejects.

Scripts

Script Description
parahub-heartbeat Status reporting + VPN auto-config
parahub-autoupdate OTA firmware updates with SHA256 verification
parahub-gw-check Gateway health monitoring + batman-adv mode promotion
parahub-guest-gateway Applies the per-island guest-gateway election result — toggles guest-VLAN DHCP (called by heartbeat)
parahub-speed-control Per-client bandwidth shaping on guest network
parahub-vps-setup WireGuard tunnel configuration (called by heartbeat)
parahub-mullvad Optional Mullvad VPN for lower-latency guest exit
parahub-ygg-acl Yggdrasil inbound access control (nftables whitelist)

Peering Agreement

The firmware source is MIT licensed. The network — the free transit that nodes donate to each other and to guests — follows the Parahub Mesh Peering Agreement, adopted from the Pico Peering Agreement v1.0 (CC0).

That agreement is a draft pending legal review and is not yet in force: it states how the mesh is meant to work and how guest data is handled, and it binds no node owner until a final version is adopted. What a node reports about itself and about connected guests is described in section 5.7 and in the Privacy Policy.

License

MIT — firmware source code. See PEERING.md for the network peering terms.

About

OpenWrt mesh networking firmware — batman-adv + Yggdrasil + WireGuard

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages