Home The Playbook
Learn
Settings Guide Field Guides & Resources Certifications
Get
Meshtastic Meshcore Reticulum Nodes About Contact
Node Star Field Guide · Vol. 2

Build a Multi-Interface
Reticulum Node Box

LoRa is just the beginning. This guide walks you through building a permanent, always-on node that speaks every interface Reticulum supports — and routes between all of them automatically.

Prerequisite Vol. 1 — RNode Build
Host Hardware Raspberry Pi 5 (recommended)
Interfaces LoRa + WiFi + TCP + I2P
Est. Cost $80 – $150
Interfaces
LoRa 915 MHz
LoRa 433 MHz
WiFi / LAN
TCP / Internet
I2P Overlay
rnsd · Transport
Raspberry Pi host
⚠ March 2026 Update Notice — Read Before Proceeding

This guide targets Reticulum 1.1.x (current stable: 1.1.4, released March 12, 2026). The install steps and config snippets treat the 1.0 era as the baseline, but if you are cross-referencing with older nodes or documentation, be aware of these breaking points:

Always cross-reference the official manual and changelog before deploying: reticulum.network/manual/ · github.com/markqvist/Reticulum — CHANGELOG

Why Multi-Interface

Your first RNode proved the concept. You got packets on the air, cryptographic identities working, and maybe a kilometer or two of real range. That single LoRa link is genuinely useful — but it's an island.

A multi-interface node changes what the device is. Instead of a radio that Reticulum happens to use, you're building a network junction — a point where LoRa radio, local WiFi, internet TCP, and optionally anonymous I2P tunnels all converge. Reticulum treats every interface as an equal peer and routes packets across all of them automatically. No special configuration. No routing tables to manage. You add interfaces; Reticulum figures out paths.

The Core Principle

Reticulum doesn't care what's underneath — LoRa radio, WiFi, TCP/IP, serial cable, I2P. If it can move bytes, Reticulum can use it. A multi-interface node is not a hack. It's the architecture the protocol was designed for.

Practically, here's what this unlocks:

Radio Coverage

Two LoRa bands (915 + 433 MHz) behave differently in different terrain. Having both means you're never stuck with a single propagation profile.

Internet Bridge

TCP over internet connects your local LoRa island to the global Reticulum network — Nomadnet servers, remote nodes, people using Sideband anywhere in the world.

Resilience

If internet goes down, the node keeps routing on radio. If radio congests, packets spill to WiFi. No single point of failure for the network function.

How Reticulum
Routes Between Interfaces

Reticulum's routing model is fundamentally different from IP routing. There are no routing tables you configure. Instead, every node maintains a path table — a live map of which interface a given destination hash was last heard from. When a packet needs to go somewhere, it goes out the interface where that destination was most recently announced.

This means adding an interface is genuinely as simple as adding it to your config. Reticulum will immediately start learning destinations from it and routing packets through it as paths are discovered.

[ Your Multi-Interface Node ] Raspberry Pi 5 (or 4) · rnsd | | | | | [RNode [RNode [WiFi / [TCP/IP [I2P 915 MHz] 433 MHz] LAN] Internet] Interface] | | | | | Local mesh Long range Local net Reticulum Anonymous 2-5 km 3-8 km devices backbone overlay

When a packet arrives on, say, the 915 MHz LoRa interface destined for a hash that was last seen via TCP/IP, Reticulum will re-transmit it on TCP. The interfaces are completely transparent to each other. The node running rnsd with enable_transport = True is the relay engine that makes this work.

Transport Mode is Required

For a node to relay packets between interfaces — not just receive them — it must have enable_transport = True in its config. Without this, packets received on one interface will not be forwarded to others. Always enable transport on your permanent infrastructure node.

Path Discovery

Destinations announce themselves periodically with a signed announce packet. When your node hears an announce on the 433 MHz interface, it records that destination hash → 433 MHz in its path table. Later, if another node on the 915 MHz side sends a packet to that destination, your node knows where to send it.

Paths time out if a destination goes silent. The network continuously re-discovers routes as announces propagate. There is no central authority and no static configuration needed.

Interface
Reference

Each interface type has a different role in the network stack. Most deployments use LoRa + TCP as their foundation, with WiFi and I2P added as needed. You do not have to run all of them — pick the combination that fits your situation.

📡
RNodeInterface · 915 MHz
Primary Radio · US / AU / NZ
The workhorse interface. Best compatibility with other nodes in North America. Balanced range and throughput. This should always be your first radio interface.
Range (SF8)~2–5 km urban
Range (SF12)~25+ km LOS
HardwareLilyGO T-Beam, RAK4631
Cost$25–$45
🔭
RNodeInterface · 433 MHz
Secondary Radio · Lower Band
Lower frequency means better wall penetration and different propagation characteristics. Useful as a fallback or for a distinct longer-range segment. Less common — fewer neighbors — but valuable in the right topology.
Range (SF8)~3–8 km urban
PenetrationBetter than 915
HardwareLilyGO T-Beam 433
Cost$25–$45
🌐
AutoInterface / UDPInterface
Local Network · WiFi or Ethernet
Bridges Reticulum across your LAN automatically using multicast discovery. Any device running Reticulum on the same network segment will peer with your node without any configuration on either side.
RangeLAN / WiFi coverage
BandwidthHigh (not a bottleneck)
Config neededMinimal
Cost$0 — Pi WiFi built-in
🔗
TCPClientInterface
Internet Backbone · Outbound TCP
Connects your node to a known Reticulum hub on the internet. This is how your local LoRa mesh joins the global network. Point at any public Reticulum node — or your own VPS. Packets flow both ways.
RangeGlobal
RequiresInternet connection
FallbackNode still works offline
Cost$0 (public hubs available)
🌑
I2PInterface
Anonymous Overlay · Optional
Routes Reticulum traffic through the I2P anonymous network. IP addresses are hidden on both ends. Traffic analysis is extremely difficult. Useful for high-sensitivity deployments. Note: I2P adds meaningful CPU and RAM overhead — budget at least 200–300 MB additional RAM and expect elevated CPU. A Pi 5 handles this comfortably; a Pi 4 with 4 GB is workable but tight. Not recommended on 2 GB RAM builds running full transport.
AnonymityHigh — IP hidden
LatencyHigher than TCP
Tunnel build (first run)20–60+ min
Requiresi2pd or I2P router
Cost$0 (open source)
Start Simple

For most builds: start with LoRa 915 + TCP + AutoInterface. That covers radio, internet backbone, and local LAN — three very different transports with minimal hardware. Add 433 MHz and I2P later if your use case demands it.

Hardware Bill
of Materials

The multi-interface node requires a proper host computer — not just a microcontroller. A Raspberry Pi 5 is the current recommended choice: fast enough for AES-256 crypto at wire speed, has USB 3.0 ports for multiple RNodes, built-in WiFi, an optional PCIe NVMe slot for SSD storage, and good thermal headroom for enclosed deployments. The Pi 4B remains a solid and cheaper alternative but should be considered the floor, not the target.

Core Hardware

Component Spec / Notes Source Cost
Raspberry Pi 5 Recommended Significantly faster crypto, PCIe for optional NVMe. 4 GB model preferred. Matters most if running I2P or heavy transport load. Active cooler recommended for enclosed installs. adafruit.com, pishop.us $60–$80
Raspberry Pi 4B Still a solid choice. 2 GB minimum for LoRa + TCP only; 4 GB if adding I2P (tunnel-build phase is RAM-hungry). Widely available used. adafruit.com, pishop.us $35–$55
MicroSD Card 16 GB minimum, Class 10 / A1 or better. Samsung Endurance or SanDisk Industrial preferred for always-on use. Amazon, B&H $8–$14
USB-C Power Supply Official Pi 4 PSU (5.1V / 3A). Under-powered supplies cause random reboots. Adafruit, Amazon $8–$12
LilyGO T-Beam Supreme (915 MHz) Preferred SX1262 chip — notably better receiver sensitivity than the older SX1276. The "Supreme" variant adds SX1262. Look for this specifically. LilyGO official store, AliExpress $35–$50
LilyGO T-Beam v1.1 (915 MHz) SX1276 chip — still works well, widely available, cheaper. Good fallback if Supreme is out of stock. AliExpress, Amazon, eBay $25–$35
RAK4631 (WisBlock) SX1262-based. More modular — the radio module snaps onto a base board. Well-documented and popular in 2025–2026 community builds. Slightly more involved to flash. RAKwireless store $30–$50
Heltec V3 / WiFi LoRa 32 SX1262, built-in OLED, compact. Popular for builds where space is tight. Confirmed working with RNode firmware. Heltec store, AliExpress $20–$35
LilyGO T-Beam (433 MHz) Second LoRa interface, lower band. Same family, different frequency variant. SX1276 on most models at this price point. AliExpress $25–$35
Powered USB 3.0 Hub Must be externally powered — RNodes draw enough current to brown-out bus-powered hubs. 4-port minimum. Anker, Amazon $15–$25
Short USB-A to USB-C cables × 2 Data-capable, not charge-only. 0.5m length keeps the build tidy. Any electronics retailer $8–$14

Antennas

Antenna Interface Notes Cost
915 MHz 5 dBi omni LoRa 915 SMA male. Significant upgrade over the stubby stock antenna. Mount outside if possible. $10–$18
433 MHz 3 dBi omni LoRa 433 SMA male. Longer physically — this band's wavelength is nearly 70 cm. Plan enclosure height accordingly. $8–$15
SMA pigtail extensions Both If boards are inside an enclosure, run coax to an external bulkhead connector. Keeps RF outside the box. $6–$12 each

Optional but Useful

Item Purpose Cost
UPS hat for Pi (e.g. UPS-Lite) Battery backup — keeps the node running through short power outages. Critical for infrastructure nodes. $18–$35
Case with DIN rail mount Clean installation in an electrical panel or comms rack. Keeps everything secure. $15–$30
Pi heatsink + fan kit Pi 4 runs warm under sustained load. Passive heatsinks fine for most installs; add fan if enclosed. $5–$12
Ethernet cable Wired LAN is more stable than WiFi for a fixed node. Frees the Pi's WiFi radio for other uses. $5–$10
Powered USB Hub — Non-Negotiable

Two RNodes plus a hub drawing from the Pi's USB bus will exceed safe current limits and cause intermittent resets. Always use an externally powered hub. Anker's 4-port models are well-tested for this use case.

Assembly

This assumes both T-Beam boards are already flashed as RNodes per Vol. 1. If not, flash them first before proceeding — it's easier to do on a laptop than to debug firmware on a Pi.

Full Config
File

This is the complete ~/.reticulum/config for a node with all five interface types. Edit the sections marked in comments to match your setup. You do not need all interfaces — comment out or remove any blocks you don't want.

# ~/.reticulum/config
# Multi-Interface Node — Node Star Field Guide Vol. 2
# ──────────────────────────────────────────────────

[reticulum]
  enable_transport        = True      # REQUIRED for multi-interface relay
  share_instance          = True
  shared_instance_port    = 37428
  instance_control_port   = 37429
  panic_on_interface_error = No       # Stay up if one interface fails

[interfaces]

  # ──────────────────────────────────────────────
  # INTERFACE 1: LoRa 915 MHz — Primary Radio
  # ──────────────────────────────────────────────
  [[LoRa 915 MHz]]
    type            = RNodeInterface
    enabled         = yes
    port            = /dev/rnode_915   # or /dev/ttyUSB0
    frequency       = 915000000        # 915.0 MHz — US/AU/NZ (ISM band)
    bandwidth       = 125000
    txpower         = 17               # 17 dBm — legal on 915 MHz ISM (US Part 15, max 30 dBm EIRP)
    spreadingfactor = 8                # SF8: good balance
    codingrate      = 5
    id_interval     = 1800             # Announce every 30 min — good for infra nodes
    id_callsign     = YOURCALL         # Optional: FCC callsign

  # ──────────────────────────────────────────────
  # INTERFACE 2: LoRa 433 MHz — Secondary Radio
  # Remove this block if not using a 433 board
  # ──────────────────────────────────────────────
  # ⚠ POWER LIMIT: In the US, 433 MHz (Part 15) is limited to 1 mW ERP (0 dBm).
  # 433 MHz is NOT an ISM band in the US — unlicensed use is strictly limited.
  # 17 dBm on 433 MHz requires an amateur radio license (Technician or higher).
  # EU/UK: 433 MHz is an ISM band — 10 mW ERP (10 dBm) allowed unlicensed.
  [[LoRa 433 MHz]]
    type            = RNodeInterface
    enabled         = yes
    port            = /dev/rnode_433   # or /dev/ttyUSB1
    frequency       = 433000000        # 433.0 MHz
    bandwidth       = 125000
    txpower         = 10               # 10 dBm — legal in EU/UK; reduce to 0 for US unlicensed
    spreadingfactor = 8
    codingrate      = 5
    id_interval     = 1800             # See airtime note below

  # ──────────────────────────────────────────────
  # INTERFACE 3: AutoInterface — LAN / WiFi
  # Peers automatically with other Reticulum nodes
  # on the same network segment via multicast
  # ──────────────────────────────────────────────
  [[LAN AutoInterface]]
    type        = AutoInterface
    enabled     = yes
    group_id    = Node StarLAN    # Arbitrary group name — nodes must match

  # ──────────────────────────────────────────────
  # INTERFACE 4: TCP Client — Internet Backbone
  # Connects outbound to a Reticulum hub on the internet.
  # PREFERRED: your own VPS (cheapest tier is fine) or a
  # regional community hub. reticulum.network:4242 is the
  # historic public entry point but has seen load and abuse
  # issues — don't point new infrastructure at it by default.
  # ──────────────────────────────────────────────
  [[Reticulum TCP Hub]]
    type            = TCPClientInterface
    enabled         = yes
    target_host     = your-vps-or-community-hub.example  # Replace — see note above
    target_port     = 4242
    kiss_framing    = False
    outgoing        = True   # Allow sending packets out this interface
    incoming        = True   # Accept incoming packets; set False to reduce abuse surface

  # ──────────────────────────────────────────────
  # INTERFACE 5: I2P — Anonymous Overlay
  # Requires i2pd running locally first:
  #   sudo apt install i2pd && sudo systemctl start i2pd
  # Then restart rnsd — it will auto-configure I2P
  # ──────────────────────────────────────────────
  [[I2P Anonymous Interface]]
    type    = I2PInterface
    enabled = yes
    peers   = # Leave blank — auto-discovers I2P Reticulum peersCONFIG
panic_on_interface_error = No

This setting is important for a multi-interface node. Without it, if any single interface fails to initialize (e.g., an RNode board is unplugged), rnsd will abort entirely. With it, the daemon keeps running on the interfaces that are working and logs the error.

Choosing a TCP Hub — Own VPS Preferred

The historic public entry point reticulum.network:4242 is fine for a quick smoke test, but new permanent infrastructure should point at either (a) your own VPS (any cheapest-tier Linux box works — rnsd is very light), or (b) a regional community hub run by someone you can coordinate with. The public hub has experienced congestion and occasional abuse; routing your infrastructure through it adds a dependency you don't control. Running a small VPS hub also lets you run a TCPServerInterface for others to connect to, strengthening the network.

Airtime Budget — id_interval Matters

Two LoRa interfaces both announcing at id_interval = 600 (10 min) with SF8 creates noticeable airtime consumption — and in dense areas, contributes to channel congestion. Infrastructure nodes should use 1800–7200 s (30 min to 2 hrs) unless fast path convergence is specifically required. The config above uses 1800 s as a reasonable middle ground. If you're on a busy community channel, push it to 3600 or higher.

⚠ 433 MHz Power Limits — Know Your Region

United States: 433 MHz is not an ISM band under FCC Part 15. Unlicensed operation is limited to 1 mW ERP (0 dBm) — enough for very short-range testing only. Running 433 MHz at 10+ dBm without an amateur radio license is illegal. If you hold a Technician license or higher, you can use higher power on 70 cm (430–450 MHz) under Part 97 rules, but you must transmit your callsign.

EU / UK: 433 MHz is an ISM band (ETSI EN 300 220). Unlicensed operation is permitted at up to 10 mW ERP (10 dBm) with a 10% duty cycle limit. The config above uses 10 dBm as the default — do not raise this without checking your local regulations.

If you're US-based and unlicensed, either skip the 433 MHz interface entirely (the 915 + TCP + AutoInterface build is fully capable) or reduce txpower to 0 and treat it as a short-range test interface only.

Verifying the Config

After writing the config, start rnsd in verbose mode and watch for each interface initializing:

$ rnsd -v

[rnsd] Loaded config from ~/.reticulum/config
[rnsd] RNodeInterface LoRa 915 MHz ready   [/dev/rnode_915]
[rnsd] RNodeInterface LoRa 433 MHz ready   [/dev/rnode_433]
[rnsd] AutoInterface  LAN AutoInterface    [multicast group Node StarLAN]
[rnsd] TCPClientInterface Reticulum TCP Hub [reticulum.network:4242]
[rnsd] I2PInterface   I2P Anonymous Interface [i2p:...]

# Check live interface status anytime:
$ rnstatusBASH

Transport Mode

Transport mode is what makes the node useful as infrastructure. Without it, your Pi receives packets on all interfaces but doesn't relay them — it's just a passive listener. With it, your node becomes an active router: it reads the path table, determines the best outbound interface, and re-transmits packets toward their destination.

Already Set in the Config Above

enable_transport = True is already included in the config from Section 06. This note is here to make sure you understand what that line does — don't disable it by accident on your infrastructure node.

What Transport Nodes Do

When a packet arrives from a node on the 915 MHz interface destined for a hash known to be reachable via TCP, the transport node:

This happens for every interface pair automatically. A packet can traverse LoRa → TCP → I2P without any manual configuration on any of the nodes involved.

Only Run Transport on Stationary Nodes

Transport nodes are infrastructure. Running transport on a mobile device (a phone, a handheld node) can cause routing instability as the device moves in and out of range while holding path table entries. Keep enable_transport = False on mobile or intermittently-connected nodes.

Antenna Selection
& Placement

The antenna is the most impactful hardware variable in your node's reach. A $12 5 dBi omni mounted at rooftop height will dramatically outperform the stubby stock antenna from inside a building. The radio physics are unforgiving: every obstruction between you and another node costs real dB.

Antenna Type Gain Pattern Best Use
Stock rubber duck (included) 0–2 dBi Omnidirectional Testing and development only. Not for deployment.
5 dBi fiberglass omni 5 dBi Omnidirectional Recommended Rooftop or pole-mount. Standard deployment antenna for most nodes.
8 dBi high-gain omni 8 dBi Compressed vertical Flat terrain, wide area coverage. Trade-off: narrower vertical angle — misses nearby nodes at different elevations.
Yagi directional 10–16 dBi Narrow beam Point-to-point backbone links. 10–30+ mile links between ridge nodes. Must be aimed precisely.
Magnetic base mobile 2–3 dBi Omnidirectional Portable setups. Vehicle-mount. Good for temporary deployment.

Placement Principles

For Backbone Links

If your multi-interface node is also serving as one end of a long-distance point-to-point link, pair a Yagi antenna with SF11 or SF12 on the relevant band. Two ridge-mounted nodes with directional Yagi antennas can bridge entire valleys, achieving 10–30+ mile links at high spreading factors.

Enclosure
& Power

An outdoor-capable node needs three things beyond the electronics: weatherproofing, reliable power, and thermal management. Cutting corners on any of these is the most common reason a node goes offline at the worst moment.

Enclosure Options

Enclosure Type IP Rating Best For Cost
Waterproof ABS Project Box IP65 Most outdoor deployments. Available on Amazon/AliExpress in sizes that fit a Pi + USB hub. $8–$20
Hammond Manufacturing enclosure IP65–IP67 Professional quality. Better tolerances, proper gaskets. Useful if the node will see extreme weather. $25–$60
NEMA 4X box IP66 Industrial / severe weather. Oversized but robust. Good for permanent rooftop installs. $20–$50
3D printed + conformal coating Depends on design Custom fit for your exact hardware. Files on Thingiverse. Coat with silicone conformal spray for weather resistance. $5–$15

Power Strategy

A Pi 4 with two RNodes draws approximately 4–7W under typical load. For a fixed indoor node, this is trivial. For outdoor or off-grid deployment, plan accordingly.

Thermal Considerations

A Pi 4 in a sealed enclosure in direct sun can reach temperatures that trigger thermal throttling. At minimum, install passive heatsinks on the SoC. If the enclosure is sealed or in sun, add a small 5V fan controlled by the Pi's GPIO. The RPi OS includes raspi-config settings for fan temperature thresholds.

Cable Entry Points

Every cable that enters the enclosure is a potential water intrusion point. Use cable glands (also called PG glands) with rubber seals for each cable entry. They're cheap, reliable, and sized for common cable diameters. A waterproof enclosure with unsealed holes is not waterproof.

Testing &
Verification

After assembly and configuration, verify each interface is working before calling the build done. A systematic test catches problems before the node goes into service.

Step 1 — Interface Status

$ rnstatus

Interface           Status   TX       RX       RSSI   SNR
LoRa 915 MHz        Up       1.2 kB   847 B    -92    9.1
LoRa 433 MHz        Up       0 B      0 B      —      —
LAN AutoInterface   Up       512 B    1.1 kB
Reticulum TCP Hub   Up       2.4 kB   1.9 kB
I2P Interface       Up       0 B      0 B

# All interfaces should show "Up"
# RX activity on LoRa 915 indicates you're hearing other nodes
# Zero RX on 433 is normal if no 433 nodes are nearbyBASH

Step 2 — Verify Cross-Interface Routing

# From another device on the LAN (with Reticulum installed),
# probe your node's local destination hash:
$ rnprobe <destination_hash>

Probing [abc123...] via LAN AutoInterface... OK  12ms
Probing [abc123...] via LoRa 915 MHz...       OK  430ms

# If routing works, you'll see responses arriving from different
# interfaces as the path table populatesBASH

Step 3 — Verify Transport is Working

# On a LoRa-only device (no internet), attempt to reach a
# Nomadnet node on the internet. If transport is working,
# packets will route: LoRa → your node → TCP → internet.

$ rnpath <nomadnet_destination_hash>

Path to [xyz789...] found via transport node [your_node_hash]
Hops: 2  First hop: LoRa 915 MHz  Next hop: TCPBASH

Step 4 — Confirm systemd Auto-Restart

# Simulate a crash and confirm the service restarts cleanly
$ sudo systemctl stop rnsd
$ sleep 10
$ sudo systemctl status rnsd

● rnsd.service — Reticulum Network Stack Daemon
   Loaded: loaded (/etc/systemd/system/rnsd.service; enabled)
   Active: active (running) since ...
   Restart: on-failureBASH

Ongoing Monitoring

For permanent infrastructure nodes, consider a simple monitoring loop via cron or a lightweight service that periodically runs rnstatus and alerts you if an interface goes down. A down interface won't crash rnsd (thanks to panic_on_interface_error = No), but you want to know about it.

Interface Access
Control (IFAC)

By default, any Reticulum node that hears your interface can send through it and participate in your network segment. For most community deployments this is fine — and desirable, since openness enables the mesh to grow. But there are scenarios where you want to restrict a specific interface to a known group: a private organizational network, a security-sensitive segment, or a community network that wants to prevent abuse.

IFAC adds a shared credential to a specific interface. Only nodes that know the credential can participate on that interface segment. The wider Reticulum network's cryptographic identity layer is still intact — IFAC operates below it, as interface-level access control.

Adding IFAC to an Interface

  [[LoRa 915 MHz]]
    type            = RNodeInterface
    enabled         = yes
    port            = /dev/rnode_915
    frequency       = 915000000
    bandwidth       = 125000
    txpower         = 17               # 17 dBm — legal on 915 MHz ISM (US)
    spreadingfactor = 8
    codingrate      = 5

    # IFAC — Interface Access Control
    ifac_size       = 8                # bytes of IFAC signature
    ifac_key        = your_shared_passphrase_hereCONFIG
All Nodes on the Segment Must Match

Every node that communicates on this interface must have the same ifac_key configured for that interface. A node without the key — or with the wrong key — will not receive or be able to send packets on this segment. They are cryptographically invisible to each other.

You can apply IFAC to some interfaces and not others. A common pattern: apply IFAC to the local LoRa radio interfaces for a private organizational network, while leaving the TCP and I2P interfaces open to the global Reticulum network. This creates a private radio segment that bridges to the public internet-connected network at your node.

Security Limitations — Read This

IFAC is access control, not encryption. There are important limits to understand:

  • The IFAC key is derived from a passphrase that is sent on the wire. It protects against passive listeners who don't know the passphrase, but does not provide confidentiality of traffic content.
  • IFAC is not end-to-end. If an attacker gains access to any node on the segment (e.g., compromises one physical device), they can see all segment traffic.
  • For genuinely sensitive deployments, rely on LXMF message encryption and verified destination hashes, not IFAC alone. LXMF provides end-to-end encryption regardless of what interfaces the traffic traverses.
  • Some experienced operators skip IFAC entirely and use trusted destination lists + application-layer authentication, which scales better on busy transport nodes with many paths.

Hardening &
Best Practices

A transport node sitting on LoRa + TCP is infrastructure. It stays up unattended, often in a location you can't quickly access. The following practices reduce attack surface, prevent the process from causing damage if something goes wrong, and make the system more observable.

Systemd Sandboxing

The service file in Section 05 included a few basic constraints. Here is a more complete hardened version. These options restrict what the process can do even if it's compromised.

[Unit]
Description=Reticulum Network Stack Daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=reticulum
Group=reticulum

ExecStart=/home/reticulum/.venv/reticulum/bin/rnsd
Restart=on-failure
RestartSec=5

# Privilege containment
NoNewPrivileges=yes
CapabilityBoundingSet=
AmbientCapabilities=

# Filesystem restrictions
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/home/reticulum/.reticulum
PrivateTmp=yes
PrivateDevices=no         # Must be no — needs /dev/ttyUSB* access

# Network and syscall restrictions
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=yes
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM

# Misc
ProtectKernelTunables=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
LockPersonality=yes

[Install]
WantedBy=multi-user.targetSYSTEMD
Dedicated Service User

The config above runs as a dedicated reticulum user rather than pi. Create it with: sudo useradd -r -m -s /sbin/nologin reticulum && sudo usermod -aG dialout reticulum. Then install the venv under /home/reticulum/. Running as a non-login system user limits what the process can touch even without full sandboxing.

Firewall Rules for TCP Server Interfaces

If you add a TCPServerInterface (so other nodes can connect to your node rather than you connecting out), expose only the specific port, not the machine broadly:

# Allow inbound Reticulum TCP on port 4242 only
$ sudo ufw allow 4242/tcp comment 'Reticulum TCP server'

# Allow SSH (don't lock yourself out)
$ sudo ufw allow ssh

# Enable — default deny everything else inbound
$ sudo ufw enable
$ sudo ufw status verboseBASH

For a node running only TCPClientInterface (outbound connections only), you don't need to open any inbound ports at all — outbound TCP connections work through standard NAT.

Path Table Bloat on Busy Transport Nodes

A transport node sitting at the intersection of a public TCP interface and multiple LoRa interfaces will accumulate path table entries quickly in active networks. Reticulum handles this gracefully — paths expire if unheard — but on very high-traffic nodes with hundreds of interfaces (e.g., a large community hub), the path table can grow significantly and impact memory usage.

Pi 5 — Recommended Hardware for Transport + I2P Nodes

The Raspberry Pi 5 is now the clear sweet spot for combined transport and I2P builds. Its faster ARM Cortex-A76 cores make a meaningful difference to AES-256 throughput (mandatory since ~1.0) and I2P's crypto-heavy tunnel establishment. The 4 GB model comfortably handles concurrent LoRa transport, TCP bridging, and an active i2pd instance. The optional PCIe NVMe slot lets you replace the MicroSD with a proper SSD — a significant reliability improvement for always-on nodes. The Pi 5 also has better thermal headroom than the Pi 4, which matters in enclosed outdoor deployments.

The Pi 4B remains a solid, widely-available fallback — use 4 GB RAM minimum if adding I2P. But all new builds should default to Pi 5 unless cost or availability forces otherwise.

Keeping Reticulum Up to Date

The 1.x series is under active development. Breaking changes between minor versions are infrequent but real — particularly around protocol compatibility with older clients. Best practice:

# Activate venv, update, restart service
$ source ~/.venv/reticulum/bin/activate
(reticulum) $ pip install --upgrade rns lxmf nomadnet
(reticulum) $ deactivate
$ sudo systemctl restart rnsd
$ sudo systemctl status rnsd

# Check what version you're now running
$ ~/.venv/reticulum/bin/rnsd --version

# Pin to a specific version on infrastructure (read changelog first)
(reticulum) $ pip install rns==1.1.4BASH
Before Updating on Infrastructure Nodes

Check the Reticulum changelog at github.com/markqvist/Reticulum before upgrading a node that other people depend on. Occasionally a release changes wire-level behavior in ways that temporarily breaks compatibility with nodes on older versions. Test updates on a secondary node first if you're running community infrastructure. On stable transport nodes, consider pinning to a known-good version (pip install rns==1.1.4) rather than always pulling latest.

RetiNet — Community Fork & Actively Maintained Alternative

In mid-2025, the original Reticulum repository added an anti-AI/no-harm clause to its license that made it incompatible with standard open-source definitions (AGPL/OSI). A significant portion of the community responded by forking the project as RetiNet — a drop-in compatible continuation under a clean AGPL license, with open contributions, F-Droid-compatible packaging, and a Zulip community. Many operators now run RetiNet on their infrastructure nodes in place of (or alongside) original RNS, particularly on builds destined for F-Droid or where license clarity matters.

Both the original RNS and RetiNet are interoperable on the wire as of early 2026. If you are deploying new infrastructure today, check the RetiNet project and its community to assess whether it fits your needs before committing to the original release track.

Troubleshooting

Symptom Cause Fix
One RNode shows Status: Error in rnstatus
Serial port path mismatch, or board unplugged
Verify the board is visible with ls /dev/ttyUSB*. Check that your udev symlink is still pointing to the right device. Replug and restart rnsd.
Both RNodes swap port numbers on reboot
udev rules not applied, or serial numbers not set correctly
Re-run udevadm info -a -n /dev/ttyUSB0 | grep serial for each board. Make sure the ATTRS{serial} values in your udev rules match exactly. Re-run udevadm control --reload-rules.
TCP interface fails to connect at startup
Network not yet available when rnsd starts
Add After=network-online.target and Wants=network-online.target to the [Unit] section of the systemd service file. Reticulum will also retry TCP connections automatically.
Packets arrive on LoRa but don't exit via TCP (or vice versa)
Transport mode not enabled
Confirm enable_transport = True is in the [reticulum] section of your config (not inside an interface block). Restart rnsd.
rnsd crashes on startup with one interface failing
panic_on_interface_error defaults to Yes
Add panic_on_interface_error = No to the [reticulum] section. Run rnsd -v to see which interface is failing, then fix it separately.
AutoInterface peers with LAN devices but no traffic flows
group_id mismatch between nodes
All nodes on the LAN segment that should peer must have the same group_id value in their AutoInterface config. An empty group_id uses the default and will still peer with other defaults.
I2P interface stays at 0 TX / 0 RX for a long time
i2pd not running, or tunnels still building
Check sudo systemctl status i2pd. On first run, I2P tunnel building takes 20–60+ minutes on a Pi 4 — sometimes longer on first boot. Do not assume it's broken until 1+ hour has passed. Watch rnsd -v — it logs when the I2P integration becomes ready. Also monitor RAM: free -h. I2P during tunnel build can spike to 300+ MB RAM; if the Pi OOMs, i2pd will silently die.
LoRa range worse than expected despite 5 dBi antenna
Antenna inside enclosure, or long lossy coax run
Mount the antenna outside the enclosure using a pigtail extension and weatherproof bulkhead. For runs over 5m use LMR-400 coax. Check that the antenna connector is fully seated — a loose SMA is a silent killer.
Node overheats and throttles in outdoor enclosure
Sealed enclosure + direct sun + no thermal management
Add a passive heatsink to the Pi SoC at minimum. For sealed enclosures in sun, mount a small 5V fan on the inside and use raspi-config to set a temperature threshold. Check CPU temp with vcgencmd measure_temp.