Routers (OpenWrt / dd-wrt)
Run a relay / tunnel / VPN node on a router — which build for which CPU, and how to install it.
MeshHold ships a static, CGO-free binary for the CPU architectures that routers actually use, so you can park a node on the box that's already on 24/7 at the edge of your network. The natural role for a router node is infrastructure, not storage: a relay for the other protocols, a tunnel exit, TCP/UDP port forwards, or a VPN entry point.
The full daemon is the same one that runs on a server — nothing is cut out — so the media library, chat, agents and so on are all still present. You simply don't have to use them. What changes on a router is the deployment shape, and there are two hard constraints to plan around before you download anything.
Two constraints before you start
1. External storage is mandatory. The binary is ~50–85 MB on disk (the download is ~25 MB gzipped, it expands on unpack), and the state directory grows from there. That does not fit in a router's internal flash, which is typically 8–32 MB. Attach a USB stick or set up extroot, keep the binary there, and point the data directories at it (see Configure storage). This is true no matter which features you enable — it's the binary size, not the workload.
2. RAM is the real ceiling. A relay/tunnel/VPN node's memory use is
driven by how many libp2p peers and tunnels it carries, plus the
BadgerDB caches, not by binary size. On a 128 MB router a lightweight
relay is comfortable; on a 64 MB router keep the peer count and tunnel
fan-out modest and watch free after a day of uptime. If you mostly
want a VPN exit/entry for a handful of devices, even small boxes cope.
Which build for which router
Pick the tarball that matches your CPU. Run opkg print-architecture
on the device to see its OpenWrt arch name; the table maps that to the
Go arch in the filename.
| Download | OpenWrt arch | Typical hardware |
|---|---|---|
…-openwrt-arm64.tar.gz |
aarch64 |
ipq807x, mvebu Cortex-A53, Raspberry Pi, rockchip |
…-openwrt-armv7.tar.gz |
arm_cortex-a* |
ipq40xx, mvebu armv7, sunxi |
…-openwrt-mipsel.tar.gz |
mipsel |
ramips / mt7621, mt76x8 — most cheap consumer routers |
…-openwrt-mips.tar.gz |
mips |
ath79 / ar71xx (Atheros, big-endian) |
The MIPS builds use GOMIPS=softfloat because router SoCs have no
hardware FPU — a hardfloat binary would crash with an illegal
instruction. The binary is a raw static ELF, so it only has to match
the CPU; it does not have to match opkg's exact package-arch string,
and there's no .ipk to install.
Grab the builds from the Downloads page (current
stable) or the nightly page (bleeding edge). Each
tarball contains the meshhold binary, a procd init script
(meshhold.init), a config.yaml.default, and a README.
Install on OpenWrt
Unpack onto the external mount, not internal flash:
# 1. unpack onto the USB stick (adjust the mount + arch to yours)
tar -xzf meshhold-<ver>-openwrt-mipsel.tar.gz -C /mnt/sda1
# 2. binary + procd init script
install -m 0755 /mnt/sda1/meshhold /usr/sbin/meshhold
install -m 0755 /mnt/sda1/meshhold.init /etc/init.d/meshhold
# 3. config
mkdir -p /etc/meshhold
cp /mnt/sda1/config.yaml.default /etc/meshhold/config.yaml
Configure storage
Edit /etc/meshhold/config.yaml so the two state directories live on
the USB mount, not in flash:
node:
metadata_dir: "/mnt/sda1/meshhold/badger"
blocks_dir: "/mnt/sda1/meshhold/blocks"
Set a password and start
# the daemon must be stopped while set-password opens the store
# (-c defaults to /etc/meshhold/config.yaml when omitted)
meshhold set-password
service meshhold enable
service meshhold start
logread -f # watch it come up
The init script registers MeshHold with procd, so it restarts on crash
(with a back-off) and comes back after a reboot. Manage it with the
usual service meshhold {start,stop,restart,status}.
Install on dd-wrt
dd-wrt has no init system to hook into. Put the binary and config on the USB mount and add a startup command under Administration → Commands → Save Startup:
/opt/meshhold daemon -c /opt/meshhold-config.yaml --log-level=info &
Make sure the USB partition is mounted before that line runs; on dd-wrt the JFFS/USB auto-mount happens early enough for a startup command in most builds.
Firewall
Peers reach the node over the libp2p port (default 7777/tcp); open it. The Web UI / REST port (default 8080/tcp) only needs to be open if you want to reach the dashboard from another host — a headless relay / tunnel / VPN node doesn't need it exposed at all, and on a router you usually want it firewalled to the LAN.
What a router node is good at
- Relay for every transport (tcp / quic / websocket / webrtc / webtransport) — a router with a stable address and uptime makes an excellent always-on rendezvous and circuit relay for your other, NAT'd nodes.
- Tunnel exit — route a phone or laptop's traffic out through the router (see The Private Mesh VPN).
- TCP/UDP port forwards —
ssh -L/-R-style forwards on top of the mesh, inheriting multi-hop routing and libp2p Relay v2 for free. - VPN entry — bring up a system VPN on the router so the whole LAN behind it rides the mesh.
Vaults and the media features will work if you attach a disk, but a router is rarely the right place to store data — keep that on a node with real disk and let the router do the networking it's already good at. ```