Internet-over-LoRa: A practical bridge between Meshtastic mesh networks and the Internet
Why This Exists · Getting Started · Hardware · Usage · Configuration · How It Works · Real-World Use Cases · Performance · Roadmap · Project Blog
Deadlight Meshtastic Proxy transforms LoRa mesh networks into practical Internet gateways. Built on the Deadlight Proxy foundation, it adds transparent mesh networking capabilities that let any device on a Meshtastic mesh access standard Internet protocols—HTTP/HTTPS, email, DNS, and more—as if they had normal connectivity.
What makes this different from other mesh solutions:
- Standard protocols work unchanged (browse websites, send email, use apps)
- Transparent to applications (no special client software needed)
- Automatic fragmentation and reassembly for mesh transport
- Full MITM proxy capabilities for traffic inspection/modification
- Works with existing Meshtastic hardware and networks
- Truly off-grid: solar-powered nodes can provide connectivity across kilometers
Think of it as giving your Meshtastic network the capabilities of a satellite terminal, but running on $30 hardware and zero monthly fees.
Meshtastic networks are incredible for messaging and telemetry, but they weren't designed for general Internet access. Each protocol (HTTP, SMTP, DNS) would need custom mesh-aware implementations. This creates a chicken-and-egg problem: applications won't add mesh support without users, users won't adopt mesh without applications.
Deadlight solves this by sitting in the middle:
- Mesh side: Speaks fluent Meshtastic (protobuf over LoRa serial)
- Internet side: Speaks every protocol your applications already use
- Bridges transparently: Fragments outgoing requests, reassembles incoming responses
Result: Your mesh network suddenly works with everything, email clients, web browsers, update tools, API services, all without modifying a single line of application code.
- Disaster Response: Coordinate rescue operations when cell towers are down
- Rural Connectivity: Share one satellite uplink across dozens of kilometers
- Censorship Resistance: Maintain communication during Internet blackouts
- Off-Grid Networks: Festival/protest/research networks that disappear when powered off
- Development Projects: Bring Internet services to areas with zero infrastructure
- Universal Protocol Support: HTTP/HTTPS, SMTP/IMAP, SOCKS5, WebSocket, FTP, DNS—if it runs over TCP/IP, it works
- Transparent TLS Interception: Inspect and cache HTTPS traffic to minimize mesh bandwidth
- Intelligent Fragmentation: Automatically chunks large requests/responses into ~220-byte Meshtastic packets
- Store-and-Forward: Delay-tolerant networking handles intermittent mesh connectivity
- Connection Pooling: Reuses upstream connections to reduce mesh overhead
- Plugin Extensibility: Add custom filters, caching, compression, or protocol handlers
- Hardware Flexibility: Works with USB serial, Bluetooth, or TCP-connected radios
- Zero-Config Detection: Auto-discovers Meshtastic devices on serial ports
Software:
- Linux system (Raspberry Pi, x86 server, or ESP32-S3 with adequate RAM)
- GLib 2.0+, OpenSSL 1.1+
- GCC or Clang
Hardware (see Hardware section for details):
- Meshtastic-compatible LoRa radio (ESP32-based recommended)
- Gateway node: Raspberry Pi or similar with Internet connection
- Client nodes: Any Meshtastic device (phone, handheld, custom)
-
Clone and build:
git clone https://github.com/gnarzilla/meshtastic.deadlight.git cd meshtastic.deadlight make clean && make UI=1
-
Install CA certificate (for HTTPS interception):
# The proxy generates these on first run: # /etc/deadlight/ca.crt (install on clients) # /etc/deadlight/ca.key (keep secret) # Debian/Ubuntu sudo cp /etc/deadlight/ca/ca.crt /usr/local/share/ca-certificates/deadlight-mesh.crt sudo update-ca-certificates
-
Connect your Meshtastic radio:
# Most devices appear as /dev/ttyACM0 or /dev/ttyUSB0 ls -l /dev/tty* # Give yourself permission (or run as root) sudo usermod -a -G dialout $USER
-
Run the proxy:
sudo ./bin/deadlight -c meshtastic.conf
-
Configure mesh clients to use the gateway's mesh address as their proxy (see Usage).
Option 1: Raspberry Pi Gateway (most versatile)
- Raspberry Pi 4/5 (2GB+ RAM)
- RAK WisBlock Meshtastic Starter Kit or Heltec LoRa 32 V3
- Connection: USB serial or GPIO UART
- Power: 5V/3A supply or 12V solar panel + battery
Option 2: ESP32-S3 All-in-One (compact)
- Lilygo T-Deck or T-Watch S3
- 8MB+ PSRAM required for Deadlight
- Built-in LoRa radio and display
- Power: LiPo battery + solar panel
Option 3: Industrial/Outdoor
- Heltec Wireless Tracker or Mesh Node T114
- Weatherproof enclosure
- High-gain directional antenna (5-8 dBi)
- Solar panel + LiFePO4 battery for 24/7 operation
Any Meshtastic-compatible device works:
- Android/iOS: Meshtastic app on phone (Bluetooth to radio)
- Handheld: RAK WisBlock, Lilygo T-Echo, Heltec LoRa 32
- Custom: ESP32 + LoRa module + Deadlight client build
For best Internet gateway performance:
# In Meshtastic app or CLI
meshtastic --set lora.region US --set lora.modem_preset LONG_FAST
meshtastic --set lora.tx_power 30 # Maximum (check local regulations)
meshtastic --set lora.hop_limit 3 # Adjust for network size
Edit meshtastic.conf:
[core]
port = 8080
max_connections = 50
log_level = info
[meshtastic]
enabled = true
serial_port = /dev/ttyACM0
baud_rate = 115200
mesh_node_id = 0x12345678 # Your gateway's Meshtastic ID
fragment_size = 220 # Max payload per packet
ack_timeout = 30000 # 30 seconds for mesh ACKs
max_retries = 3
[ssl]
enable_interception = true
ca_cert = /etc/deadlight/ca/ca.crt
ca_key = /etc/deadlight/ca/ca.key
[network]
pool_max_per_host = 5 # Reuse connections aggressively
pool_idle_timeout = 600 # Keep idle connections longer
upstream_timeout = 120000 # Allow slow mesh responsesOn mesh client devices, configure proxy settings:
# Linux/Mac
export http_proxy=mesh://gateway-node-id:8080
export https_proxy=mesh://gateway-node-id:8080
# Or in applications:
# HTTP Proxy: gateway-node-id port 8080
# SOCKS5: gateway-node-id port 8080On Android (using Meshtastic app + ProxyDroid):
- Install ProxyDroid
- Set proxy to gateway node's mesh ID
- Connect Meshtastic app via Bluetooth
# From mesh client node
curl -x mesh://gateway:8080 http://example.com
# Send email via mesh
curl -x mesh://gateway:8080 \
--mail-from sender@example.com \
--mail-rcpt recipient@example.com \
--upload-file message.txt \
smtp://smtp.gmail.com:587
# SOCKS5 for SSH over mesh
ssh -o ProxyCommand="nc -X 5 -x gateway:8080 %h %p" user@remote-serverBandwidth Conservation:
[plugins]
# Enable aggressive compression
compressor.enabled = true
compressor.min_size = 512
compressor.algorithms = gzip,brotli
# Cache aggressively to reduce mesh traffic
cache.enabled = true
cache.max_size_mb = 500
cache.ttl_hours = 24Latency Tolerance:
[meshtastic]
# Longer timeouts for multi-hop paths
ack_timeout = 60000
max_retries = 5
[network]
# Don't timeout on slow mesh responses
upstream_timeout = 300000 # 5 minutes
connection_timeout = 180000 # 3 minutesPriority Shaping:
[plugins]
ratelimiter.enabled = true
# Reserve bandwidth for critical services
ratelimiter.priority_high = smtp,imap,dns
ratelimiter.priority_low = http_video,http_imagesFor redundancy, run multiple gateways:
[meshtastic]
gateway_mode = true
announce_interval = 300 # Announce availability every 5 min
prefer_local = true # Route via nearest gateway
load_balance = true # Distribute across gateways┌─────────────┐ ┌──────────────┐ ┌──────────┐
│ Mesh Client │ │ Deadlight │ │ Internet │
│ (Phone) │ LoRa Packets │ Gateway │ TCP/ | IP │ Services │
│ ├─────────────────>│ ├───────────────>│ │
│ Meshtastic │ (868/915 MHz) │ - Fragment │ │ HTTP │
│ App │ │ - Reassemble │ │ SMTP │
│ │<─────────────────┤ - TLS Proxy │<───────────────┤ IMAP │
└─────────────┘ └──────────────┘ └──────────┘
│
│ Also bridges:
├─> Other mesh nodes
├─> Offline message store
└─> Satellite uplink (if available)
-
Request Fragmentation:
HTTP GET request (1500 bytes) └─> Split into 7 Meshtastic packets (~220 bytes each) └─> Each tagged with sequence number + session ID └─> Sent hop-by-hop through mesh to gateway -
Gateway Reassembly:
Gateway receives packets out-of-order └─> Buffers and sorts by sequence number └─> Detects missing packets, requests retransmit └─> Reassembles into original HTTP request └─> Proxies to Internet normally -
Response Fragmentation:
HTTP response (50KB HTML) └─> Gateway fragments into ~230 packets └─> Sends with flow control (wait for ACKs) └─> Client reassembles and delivers to application
Deadlight auto-detects protocols by inspecting initial bytes:
GET / HTTP/1.1→ HTTP handler → Fragment and forwardCONNECT example.com:443→ HTTPS tunnel → TLS interception optionalEHLO→ SMTP handler → Email relay\x05→ SOCKS5 handler → Transparent tunneling
Encryption layers:
- LoRa PHY: AES-256 encryption at Meshtastic layer
- TLS: End-to-end between client and final destination
- Proxy MITM (optional): Deadlight can terminate TLS for caching/inspection
Trust model:
- Gateway has root CA (can inspect HTTPS if enabled)
- Mesh uses Meshtastic's channel encryption (PSK)
- Clients trust gateway CA (install certificate)
Privacy: Mesh node IDs are pseudonymous. For operational security in sensitive deployments, use throwaway node IDs and rotate channel keys.
Scenario: Earthquake destroys cell infrastructure
Setup:
- Solar-powered Deadlight gateway at field hospital (has satellite uplink)
- Rescue teams carry Meshtastic handhelds (10km range)
- Coordinate via email, share maps, update databases
Result: Teams stay connected across 50+ square km with zero functioning infrastructure.
Scenario: Village 30km from nearest fiber connection
Setup:
- One gateway node at village center (WiMAX or satellite backhaul)
- Residents install Meshtastic radios on roofs
- Multi-hop mesh covers entire valley
Result: 100+ households share single Internet connection. Cost: ~$50 per household for radio, no monthly fees.
Scenario: Large gathering needs coordination without relying on government-controlled networks
Setup:
- Organizers carry Deadlight gateways with LTE failover
- Attendees use Meshtastic app on phones (Bluetooth to radios)
- Network disappears when powered down (no logs, no traces)
Result: Thousands communicate freely. Network evaporates forensically when disassembled.
Scenario: Government shuts down Internet during protests
Setup:
- Journalist has Meshtastic radio + Deadlight on laptop
- Connects to mesh gateway run by colleague 15km away (who has working connection)
- Files stories via mesh SMTP relay
Result: Censorship bypassed. Reports reach editors despite blackout.
LoRa Physical Layer (LONG_FAST preset):
- Raw bitrate: ~5.5 kbps
- Effective throughput: ~3-4 kbps (after protocol overhead)
- Latency: 500ms - 5s per hop
Real-World Application Performance:
- Email: 10-20 emails/minute (text-heavy)
- Web browsing: 30-60 seconds per page (with caching)
- DNS: ~2 seconds per lookup (cache aggressively!)
- API calls: 5-10 seconds per request
- File transfer: ~400 bytes/sec (~1.4 MB/hour)
Optimization tips:
- Enable compression (3-10x improvement for text)
- Use image proxies (reduce image sizes before meshing)
- Cache everything possible (DNS, API responses, static assets)
- Batch requests (avoid chatty protocols)
Single Gateway:
- Handles 10-20 concurrent mesh clients comfortably
- Limited by LoRa airtime regulations (1% duty cycle in EU)
Multi-Gateway Mesh:
- Horizontally scalable (add more gateways = more capacity)
- Load balances automatically across available gateways
Bottlenecks:
- LoRa duty cycle (legal limit on transmission time)
- Mesh hop count (>4 hops = diminishing returns)
- Gateway uplink bandwidth (satellite is typically the constraint)
- Adaptive fragmentation (adjust packet size based on mesh conditions)
- Intelligent retry with exponential backoff
- Pre-fetching for common resources
- Android client app (native Deadlight on-device)
- Multi-gateway coordination protocol
- Offline message queue (store-and-forward when gateway unreachable)
- Bandwidth shaping per client/protocol
- WebRTC signaling over mesh (for peer-to-peer voice/video)
- Full IPv6 support
- Meshtastic firmware integration (run Deadlight directly on ESP32)
- Satellite backhaul optimization (Starlink, Iridium)
- Machine learning for mesh route prediction
This is a specialized fork of Deadlight Proxy. Contributions welcome:
- Protocol optimizations: Improve mesh efficiency
- Hardware testing: Validate on different radio platforms
- Real-world deployments: Share your use cases and lessons learned
- Documentation: Especially non-English guides for global use
See CONTRIBUTING.md for guidelines.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Matrix:
#deadlight-mesh:matrix.org - Development: ko-fi/gnarzilla
Radio Regulations: LoRa operates in license-free ISM bands, but transmission power and duty cycle are regulated. Ensure compliance with your local regulations (FCC Part 15 in US, ETSI EN 300-220 in EU).
Encryption Export: This software includes strong cryptography. Check export restrictions if deploying internationally.
Responsible Use: This tool can bypass censorship and provide communication in emergencies. It can also be misused. Use ethically and legally. The authors are not responsible for misuse.
Privacy Notice: Meshtastic mesh networks are pseudonymous, not anonymous. For operational security in high-risk environments, use proper opsec practices (rotate node IDs, use ephemeral keys, avoid PII in mesh metadata).
MIT License – see LICENSE
Includes:
- Meshtastic Protobufs (GPL v3)
- nanopb (zlib license)
Status: testing-ready v1.0.0 | Maintained by: @gnarzilla
