Native Encrypted Mesh Networking
The distributed sensor walkthrough on this blog demonstrates how Mycelium instances can be networked together using TCP_Send and TCP_Receive directives — a flexible approach that works well for forwarding decoded telemetry to a central collector. But configuring each socket, coordinating port numbers, and managing connection state across dozens of edge nodes adds friction at deployment time.
Mycelium now includes a native peer-to-peer encrypted mesh built into every instance. There is no mode to enable and no additional daemon to run — the mesh starts with the process. Nodes on the same LAN discover each other automatically within seconds using UDP broadcast beacons. Nodes across subnets or WAN links are added with a single command. Once connected, every node in the mesh can reach every other node for command routing, data forwarding, and live RF transport.
Identity and Security
Every Mycelium node has a persistent Ed25519 keypair stored at ~/.config/mycelium/node_key, generated automatically on first run. The 32-byte public key is the node's identity — globally unique and cryptographically unforgeable.
Each TCP connection between nodes goes through a full key exchange. X25519 ephemeral keys are derived from the Ed25519 seed, and ECDH produces a shared secret. That secret is fed into HKDF-SHA256 to derive an AES-256-GCM session key unique to that connection and direction. Every frame sent after the handshake is encrypted and authenticated.
Automatic Discovery
Nodes broadcast a UDP beacon to the LAN every 15 seconds. The beacon carries the node's TCP port and its Ed25519 public key. Any Mycelium instance that receives a beacon from an unknown node immediately initiates a TCP connection and handshake. From the operator's perspective, two Mycelium instances started on the same network will find each other without any configuration:
For cross-subnet or WAN connections, a single command is sufficient:
node add -h 10.0.1.5 -p 7556
Remote Command Routing
Once nodes are connected, any CLI command can be executed on a remote node by prefixing it with @NODE. The command is routed over the encrypted mesh, executed on the target, and the result is returned to the local shell. This works for every command in the Mycelium command set — tool configuration, directive management, execution control:
@node_b tool show @node_b execute -n ground_station @node_b stop -t aircraft_tool @node_b node show
The local shell blocks until the reply arrives, so remote commands feel synchronous. This makes it practical to script multi-node deployments from a single control point using standard .mycelium scripts.
Tool Data Routing — NODE:TOOL Addressing
The Send_To_Tool, Append_From_Tool, and Insert_From_Tool directive actions accept a NODE:TOOL address. When the node part names a remote node, the data is routed over the encrypted mesh and delivered directly to the target tool's inbox on the other side. No TCP socket configuration, no custom forwarding directives:
# Directive on node_a: forward decoded ACARS frames to node_b's aggregator tool directive create -t rx_tool -n forward -c Any -a Send_To_Tool directive set -t rx_tool -n forward -a Send_To_Tool -T node_b:aggregator
When the node part is omitted or matches the local node name, the delivery is local — the same action works for both cases without modification. This makes scripts portable: the same directive stack runs identically as a standalone sensor or as part of a multi-node pipeline.
MeshSDR — Simulating RF Links Over the Mesh
MeshSDR is a family of virtual SDR plugins that carry live IQ samples over the mesh instead of physical RF hardware. From the tool chain's perspective, a MeshSDR looks identical to a HackRF or RTL-SDR. Directives do not change. The only difference is the SDR type used at setup time:
Three MeshSDR types are available:
- MeshTx — transmit only; serializes IQ samples and routes them to a named tool on a remote node
- MeshRx — receive only; dequeues incoming IQ packets and presents them as SDR samples to the local tool chain
- MeshDuplex — bidirectional; combines both directions for full-duplex RF simulation between two nodes
Both ends must be tuned to the same frequency. The transmitter embeds its frequency in each IQ packet, and the receiver matches on it — the same mechanism used by physical SDRs for channel selection.
The Colony Map
The Mycelium web interface includes a Colony tab that renders a live SVG topology map of the mesh. The local node sits at the center. Direct neighbors appear in green with solid edges. Nodes reachable through multiple hops appear in cyan with dashed edges. Edge labels show hop count. The map updates live over WebSocket as nodes join and leave.
Putting It Together: ACARS Over Mesh
A practical demonstration of the mesh combines all three capabilities — remote commands, data routing, and MeshSDR — in a bidirectional ACARS simulation. One node runs a ground station. A second node runs a simulated aircraft. The two communicate over the mesh as if connected by a physical RF link at 129.125 MHz. No antennas, no attenuators, no lab hardware required.
The ground station script runs on node_a:
#!/usr/bin/Myce # Ground station — ACARS at 129.125 MHz over mesh sdr create -n gs_sdr -t MeshDuplex sdr set -n gs_sdr -M node_b:aircraft_tool tool create -p ACARS -n ground_station tool set -n ground_station -r gs_sdr -f 129125000 -m AM:MSK # Broadcast ground station presence and auto-acknowledge downlinks directive create -t ground_station -n squitter -c Always -a ACARS_Squitter_Start directive set -t ground_station -n squitter -a ACARS_Squitter_Start -p XA -i ORD -I KORD -N 1 directive create -t ground_station -n ack -c Always -a ACARS_Auto_Ack_Start directive create -t ground_station -n listen -c Null -a Receive directive create -t ground_station -n log -c Any -a Log -f /var/log/acars_ground.log -a execute -n ground_station
The aircraft script runs on node_b. Once started (either directly or via @node_b from the ground station node), it performs a logon sequence and begins exchanging messages with the ground station over the mesh link:
#!/usr/bin/Myce # Aircraft simulation — communicates with node_a ground station sdr create -n ac_sdr -t MeshDuplex sdr set -n ac_sdr -M node_a:ground_station tool create -p ACARS -n aircraft_tool tool set -n aircraft_tool -r ac_sdr -f 129125000 -m AM:MSK directive create -t aircraft_tool -n listen -c Null -a Receive directive create -t aircraft_tool -n respond -c Any -a Transmit directive create -t aircraft_tool -n log -c Any -a Log -f /var/log/acars_aircraft.log -a execute -n aircraft_tool
Both nodes decode each other's transmissions, log the exchange, and respond to uplinks automatically. The ground station and aircraft never directly share an IP address in the scripts — the mesh handles routing transparently.
Routing and Scale
The current mesh router uses flooding with TTL (default 8 hops) and message-ID deduplication to prevent loops. Every node in the mesh can reach every other node through the shortest available path. As nodes are added, the topology updates via heartbeat and route advertisement — no manual routing configuration is required at any scale.
For deployments where dozens of sensor nodes need to route data to a single aggregator, NODE:TOOL forwarding replaces the per-node TCP socket setup that the manual approach requires. The aggregator node's name is the only configuration that needs to be consistent across edge scripts.
← Back to Blog