Bridge Your LoRa Island to the Internet
This is Part 9 of a 12-part series on building private, resilient communication networks with Reticulum, LoRa, and associated tools.
A local LoRa mesh is powerful, but it's an island. Users on your LoRa network can only reach each other. In this guide, we'll build a gateway node that bridges your LoRa island to the wider Reticulum network over the internet — so your off-grid users can reach destinations anywhere in the world.
The Architecture
[Phone + RNode] --LoRa--> [Gateway Node] --TCP/Internet--> [Global Reticulum Network]
|
[Laptop + RNode] --LoRa------+
|
[Another Phone] --WiFi-------+
The gateway node has: - An RNode interface facing the local LoRa mesh - A TCP interface connecting to the internet (one or more remote transport nodes) - An AutoInterface for local WiFi/Ethernet devices - Transport enabled to relay traffic between all interfaces
This is essentially the transport node from Part 8, but with deliberate attention to how the interfaces interact and how to manage the bandwidth mismatch between LoRa and the internet.
The Bandwidth Problem
This is the most important thing to understand about bridging: your LoRa link runs at ~1 kbps. Your internet link runs at megabits. If you naively connect them, the internet side will flood the LoRa side with announce traffic from thousands of destinations, consuming all your precious airtime with network overhead.
Reticulum handles this automatically through announce caps and rate limiting, but you should configure your interfaces thoughtfully to help it along.
Step 1: Configure the Gateway
Edit ~/.reticulum/config on your gateway device (Raspberry Pi, old laptop, etc.):
[reticulum]
enable_transport = yes
share_instance = yes
respond_to_probes = yes
[logging]
loglevel = 4
[interfaces]
# Local WiFi/Ethernet clients
[[Default Interface]]
type = AutoInterface
enabled = yes
mode = gateway
# LoRa radio facing local mesh users
[[RNode LoRa Interface]]
type = RNodeInterface
enabled = yes
port = /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge-if00-port0
frequency = 867200000
bandwidth = 125000
txpower = 7
spreadingfactor = 8
codingrate = 5
mode = access_point
# Limit announce traffic on the slow LoRa link
announce_cap = 2
announce_rate_target = 3600
announce_rate_grace = 4
announce_rate_penalty = 7200
# Regulatory airtime limits
airtime_limit_long = 1.5
airtime_limit_short = 33
# Internet uplink to the wider Reticulum network
[[RNS Testnet Dublin]]
type = TCPClientInterface
enabled = yes
target_host = dublin.connect.reticulum.network
target_port = 4965
mode = boundary
# Optional: second internet uplink for redundancy
[[RNS Testnet Frankfurt]]
type = TCPClientInterface
enabled = yes
target_host = frankfurt.connect.reticulum.network
target_port = 4965
mode = boundary
Key Configuration Choices
mode = access_point on the LoRa interface:
- The interface stays quiet until clients actually connect
- Announces are not automatically rebroadcast on this interface
- Path requests from LoRa clients are resolved on their behalf (gateway behavior)
mode = boundary on the TCP interfaces:
- Tells Reticulum this interface connects to a significantly different network segment
- Helps Reticulum make smart decisions about what traffic to forward across the boundary
mode = gateway on the AutoInterface:
- Resolves unknown paths on behalf of local WiFi clients
- Provides full connectivity for devices on your LAN
Announce rate limiting on the LoRa interface:
- announce_cap = 2 — only 2% of bandwidth for announce traffic
- announce_rate_target = 3600 — don't rebroadcast any destination's announce more than once per hour
- announce_rate_grace = 4 — allow 4 violations before enforcing
- announce_rate_penalty = 7200 — violators get throttled to once every 3 hours
This prevents the LoRa link from being overwhelmed by announce traffic from the internet side.
Step 2: Enable Interface Discovery (Optional)
If you want your gateway to be discoverable by other Reticulum nodes on the internet, you can make your TCP listener discoverable:
# Instead of connecting to others, let others connect to you
[[Public Gateway]]
type = BackboneInterface
enabled = yes
mode = gateway
listen_on = 0.0.0.0
port = 4242
discoverable = yes
discovery_name = My Community Gateway
announce_interval = 720
reachable_on = your.public.ip.or.hostname
This requires a public IP address or port forwarding. If you don't have one, just use outbound TCP connections as shown in Step 1.
Step 3: Run and Verify
Start the daemon:
sudo systemctl start rnsd
Check interfaces:
rnstatus
You should see all interfaces Up. The TCP interfaces will start receiving announce traffic from the wider network. The LoRa interface will be quiet until a local client connects.
Test from a LoRa client: have someone with an RNode and Sideband send an announce. It should propagate through your gateway to the internet, and they should start seeing destinations from the wider network.
Step 4: Firewall Considerations
If your gateway is on a home network behind a router:
Outbound TCP connections (connecting to remote transport nodes): No firewall changes needed. Outbound connections work through NAT.
Inbound connections (if hosting a public gateway): You'll need to forward the listening port (e.g., 4242) through your router to the gateway device.
AutoInterface: Requires UDP ports 29716 and 42671 to be open for local peer discovery.
LoRa: No firewall involvement — it's radio.
Managing the Bridge
Monitoring Traffic Flow
# Watch traffic in real-time
rnstatus -m
# See which destinations are known
rnpath -t
# Check announce statistics
rnstatus -A
# View traffic totals per interface
rnstatus -t
Blackhole Management
If a destination on the internet is spamming announces and wasting your LoRa airtime:
# Block a specific identity
rnpath -B <identity_hash> --reason "Announce spam"
# View blocked identities
rnpath -b
# Unblock
rnpath -U <identity_hash>
You can also subscribe to community-maintained blackhole lists:
[reticulum]
blackhole_sources = <trusted_transport_identity_hash>
Multiple Uplinks for Resilience
Don't rely on a single internet connection. Configure multiple TCP interfaces:
[[Uplink 1]]
type = TCPClientInterface
enabled = yes
target_host = node1.example.com
target_port = 4965
mode = boundary
[[Uplink 2]]
type = TCPClientInterface
enabled = yes
target_host = node2.example.com
target_port = 4965
mode = boundary
Reticulum will use all available paths and automatically route around failures. If one uplink goes down, traffic flows through the others.
You can find community transport nodes at directory.rns.recipes and rmap.world.
The Result
With this gateway running, your local LoRa mesh is no longer an island:
- A user with a handheld RNode and Sideband can send an encrypted message to someone on the other side of the world
- The message hops: Phone → Bluetooth → RNode → LoRa → Gateway → Internet → Remote Transport Node → Destination
- Every hop is encrypted. No intermediate node can read the message.
- If the internet goes down, local LoRa communication continues uninterrupted
What's Next
Your network can now reach the world. In the next guide, we'll host a decentralized website using NomadNet — serving pages directly over Reticulum without any web servers, domain names, or cloud providers.
Previous: [Part 8 — Run a Transport Node] Next: [Part 10 — Host a Decentralized Website with NomadNet]
