NAT traversal & relay
This page sets up the server’s reachability. A public server relays for peers behind NATs out of the box. A server that is itself behind a NAT needs a few settings in the YAML file to reach the network through another relay.
The pieces
Section titled “The pieces”| Feature | Key | Default | What it does |
|---|---|---|---|
| Relay transport | features.enable_relay |
on | Lets the host use Circuit Relay v2 at all. The three below require it. |
| Relay service | features.enable_relay_service |
on | Relays connections for other peers that reserve a slot on this server. |
| AutoRelay | features.enable_auto_relay |
off | Reserves slots on static relays so peers can reach this server through them. |
| Hole punching | features.enable_hole_punching |
off | DCUtR: upgrades a relayed connection to a direct one when both sides can. |
| AutoNAT | features.enable_autonat |
on | AutoNAT v2: asks peers to test which of this server’s addresses are reachable. |
| External addresses | server.external_addresses |
none | Addresses the server advertises in addition to its interface addresses. |
| Bootstrap peers | server.bootstrap_peers |
none | DHT bootstrap peers, and the relay candidates for AutoRelay. |
The server refuses to start if enable_auto_relay, enable_hole_punching or enable_relay_service is on while
enable_relay is off.
Which setup do you need?
Section titled “Which setup do you need?”| Your server | Setup |
|---|---|
| Has a public IP, UDP port open | Defaults, plus external_addresses if the interface address is not the public one |
| Behind a NAT you control, with the UDP port forwarded | Defaults, plus external_addresses set to the public IP and forwarded port |
| Behind a NAT you cannot forward through | AutoRelay and hole punching through another Ricochet server you run on a public address |
| Public, but should not carry traffic for others | Turn the relay service off |
Public server
Section titled “Public server”Nothing to turn on: the relay service is on by default. Advertise the public address so clients can reconnect:
server: external_addresses: - /ip4/203.0.113.10/udp/55223/udxOn the .deb install, set EXTERNAL_IP=203.0.113.10 in /etc/ricochet/env instead; run.sh passes it as
--external-addrs.
Behind a forwarded port
Section titled “Behind a forwarded port”Forward UDP 55223 (or your chosen port) from the router to the server, and set external_addresses to the
router’s public IP and the forwarded port. From the network’s point of view this is a public server.
Behind a NAT you cannot forward through
Section titled “Behind a NAT you cannot forward through”The server needs a relay with a public address: another Ricochet server you run, with the relay service on.
List it in bootstrap_peers with its full multiaddr, including /p2p/<peer-id>:
features: enable_relay: true enable_relay_service: false # see the note below enable_auto_relay: true enable_hole_punching: trueserver: bootstrap_peers: - /ip4/198.51.100.7/udp/55223/udx/p2p/12D3KooW...AutoRelay reserves a slot on the static relays it is given, which are your bootstrap peers, and the server then
advertises a /p2p-circuit address through that relay. Hole punching lets peers that reach it through the relay
try to upgrade to a direct connection. AutoRelay does nothing unless bootstrap_peers holds at least one valid
address with a peer ID.
The relay must be reachable over UDX, since that is the only transport either side runs.
Public, but not relaying for others
Section titled “Public, but not relaying for others”features: enable_relay_service: falseThe server still uses the relay transport for its own connections; it just stops accepting reservations.
Relay service limits
Section titled “Relay service limits”When the relay service is on, go-libp2p’s default limits apply: 128 reservations server-wide, 16 circuits per reservation, 1 reservation per peer, 8 per IP and 32 per ASN, reservations lasting one hour, and each relayed connection cut after 2 minutes or 128 KiB in each direction. These are deliberately small: relayed connections are meant for signalling and hole punching, not bulk traffic.
Override them only if this server carries relay traffic for others and you have measured what it costs:
relay_limits: max_reservations: 256 max_circuits: 16 buffer_size: 2048 # bytes max_reservations_per_peer: 1 max_reservations_per_ip: 8 max_reservations_per_asn: 32 reservation_ttl_min: 60 # minutes connection_duration_sec: 120 # seconds connection_data: 131072 # bytes per directionA zero or omitted value keeps the go-libp2p default. The units are in the key names. reservation_ttl and
connection_duration without the suffix are not keys, and the server refuses to start on them.
Check it works
Section titled “Check it works”At startup the server logs:
relay configuration, withenable_relay,enable_relay_service,enable_auto_relayandenable_hole_punchingas it parsed them.relay service created, withmax_reservationsandmax_circuits, when the relay service is on.registered protocols. With the relay service on, the list includes/libp2p/circuit/relay/0.2.0/hop.advertising external addresses, with the number of external addresses accepted.connected to bootstrap peerorfailed to connect to bootstrap peer, once per bootstrap peer.host advertised addresses, with the addresses advertised at that moment.
grep -E 'relay configuration|relay service created|advertis|bootstrap peer' /var/log/ricochet/stdout.logAn AutoRelay reservation is made after startup, so the host advertised addresses line usually predates it. For
more detail, start the server with --debug-dht, which also turns the relay and relaysvc loggers to DEBUG.
GOLOG_LOG_LEVEL sets the level for all libp2p subsystems.
The final check is from outside: a client on another network connecting with the address you published.
Troubleshooting
Section titled “Troubleshooting”- Clients connect once, then fail to reconnect: the server advertises only private addresses. Set
external_addresses(orEXTERNAL_IP). invalid config: enable_auto_relay requires enable_relay(or the same for hole punching or the relay service): turnenable_relayback on.- A NAT’d server with AutoRelay never becomes reachable: check that the relay service is off on it, that
bootstrap_peersentries end in/p2p/<peer-id>, and that the log showsconnected to bootstrap peer. The relay itself must have its relay service on. parse config file: ... field reservation_ttl not found: usereservation_ttl_minandconnection_duration_sec.- Relayed connections drop after two minutes: that is the default per-connection limit. Hole punching, where both sides support it, moves the peers to a direct connection.