Prerequisites
Software:
- Linux (Raspberry Pi, x86 server, or similar) — or WSL2 on Windows with USB/IP passthrough (see WSL)
- GLib 2.0+, OpenSSL 1.1+, json-glib-1.0
- GCC or Clang
- Python 3 + pip (for nanopb protobuf generation during build)
Optional (for Meshtastic CLI testing):
- Python meshtastic package (
pip install meshtastic)
Hardware (see Hardware for details):
- Meshtastic-compatible LoRa radio (ESP32-based or nRF52840 recommended)
- Gateway node: Raspberry Pi, x86 Linux box, or Windows PC running WSL2
- Client nodes: any Meshtastic device (phone, handheld, custom)

Quick Install
Install system dependencies:
# Debian/Ubuntu/Raspberry Pi OS sudo apt-get install build-essential pkg-config libglib2.0-dev \ libssl-dev libjson-glib-dev libmicrohttpd-dev protobuf-compiler xxdVerify they're all found:
pkg-config --modversion glib-2.0 openssl json-glib-1.0 # Should print three version numbers — if any fail, the build will failSet up Python environment for protobuf generation:
The nanopb generator that compiles Meshtastic protobufs requires specific Python packages. Use a venv to avoid conflicts with system Python:
python3 -m venv venv source venv/bin/activate pip install protobuf grpcio-toolsKeep this venv active for the build step. You can deactivate it after
makecompletes.Clone and build:
git clone https://github.com/gnarzilla/deadmesh.git cd deadmesh make clean && make UI=1 deactivate # exit venv after buildA successful build produces:
bin/deadmesh bin/plugins/adblocker.so bin/plugins/meshtastic.so bin/plugins/ratelimiter.so tools/mesh-simConnect your Meshtastic radio:
# Most devices appear as /dev/ttyACM0 or /dev/ttyUSB0 ls -l /dev/ttyACM0 /dev/ttyUSB0 2>/dev/null # Add yourself to the dialout group sudo usermod -a -G dialout $USER # Log out and back in for group change to take effectGenerate CA certificate (for HTTPS interception):
Create the cert directory first, then generate a local CA:
mkdir -p ~/.deadlight openssl genrsa -out ~/.deadlight/ca.key 4096 openssl req -new -x509 -days 3650 \ -key ~/.deadlight/ca.key \ -out ~/.deadlight/ca.crt \ -subj "/CN=deadmesh CA/O=deadlight/C=US" chmod 600 ~/.deadlight/ca.key chmod 644 ~/.deadlight/ca.crtInstall it system-wide so curl and other tools trust it:
sudo cp ~/.deadlight/ca.crt /usr/local/share/ca-certificates/deadmesh.crt sudo update-ca-certificatesCopying from another machine? If you already have a CA from a previous install (e.g. WSL), copy both
ca.crtandca.keyto~/.deadlight/on the new machine instead of generating new ones.Configure — create
deadmesh.conf:[core] port = 8080 max_connections = 50 log_level = info [meshtastic] enabled = true serial_port = /dev/ttyACM0 baud_rate = 115200 mesh_node_id = 0 ; 0 = auto-detect from device fragment_size = 220 ack_timeout = 30000 max_retries = 3 hop_limit = 3 [ssl] enabled = true ca_cert_file = /home/youruser/.deadlight/ca.crt ca_key_file = /home/youruser/.deadlight/ca.key [network] connection_pool_size = 5 connection_pool_timeout = 600 upstream_timeout = 120Important: Use absolute paths for
ca_cert_fileandca_key_file— replaceyouruserwith your actual username. The~shortcut expands to/root/when running withsudo, which is not where your certs are.Run the gateway:
./bin/deadmesh -c deadmesh.conf -vYou should see:
Configuration loadedandConfig applied— config is validMeshtastic: sent want_config handshake— serial API initializedMeshtastic: auto-detected local node ID: XXXXXXXX— device recognizedMeshtastic: NodeInfo update for XXXXXXXX— mesh nodes populating- Live packet stream:
POSITION,TELEMETRY,TEXT,NODEINFOfrom mesh
If you see
Configuration validation failed: Cannot read CA cert file— the path in your config doesn't match where you put the certs. Double-check the absolute path and that~/.deadlight/ca.crtexists.Open the dashboard at
http://localhost:8081to monitor gateway activity.Test the proxy:
# HTTP curl -x http://localhost:8080 http://example.com # HTTPS curl --cacert ~/.deadlight/ca.crt -x http://localhost:8080 https://example.com # SOCKS5 curl --socks5 localhost:8080 http://example.com
Client-side Proxy (send device/second radio)
The deadmesh-client binary runs a tiny local HTTP proxy that tunnels traffic over the mesh to your gateway.
Build note: Serial mode requires a compile-time flag
# Add -DCLIENT_TRANSPORT_SERIAL to client target in Makefile (see earlier instructions)
make clean client UI=1Run on client device (replace with your gateway's node ID):
./bin/deadmesh-client --gateway 14e7cdaf --device /dev/ttyACM0 -v
# or Bluetooth serial
./bin/deadmesh-client --gateway 14e7cdaf --device /dev/rfcomm0 -vOnce running (listens on localhost:8888):
export http_proxy=http://localhost:8888
curl http://example.com
Windows Subsystem for Linux
### WSL (Windows Subsystem for Linux)
deadmesh works under WSL2 with USB/IP passthrough for the Meshtastic radio. This is a fully supported configuration — the reference gateway setup during development runs this way.
# PowerShell (Admin) — install and attach USB device
winget install usbipd
usbipd list # Find your radio's BUSID
usbipd bind --busid <BUSID> # One-time bind
usbipd attach --wsl --busid <BUSID> # Attach to WSL (repeat after replug)# WSL — verify device
ls -l /dev/ttyACM0
sudo usermod -a -G dialout $USERNote: You must re-run
usbipd attachfrom PowerShell each time the radio is unplugged, the PC sleeps, or WSL restarts.
Be the first to comment on this post.