# How to Configure an Iroh Endpoint for Different Network Environments (NAT and Firewall)

> Configure your Iroh endpoint for NAT and firewall environments using the Builder type. Set bind addresses, relays, and proxies before binding for seamless network integration.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: how-to-guide
- Published: 2026-07-05

---

**You configure an iroh endpoint for different network environments by using the `Builder` type in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) to set bind addresses, relay modes, port-mapping behavior, and outbound proxies before calling `.bind().await`.**

The `n0-computer/iroh` library provides fine-grained control over network discovery and traversal through its endpoint builder API. Whether you are deploying on a home router behind NAT, a locked-down corporate network, or a public server with a static IP, you can adapt the endpoint's behavior to maximize connectivity. This guide covers the builder methods and source files that control how the crate handles NAT, firewalls, and address advertisement.

## Configuring the Iroh Endpoint Builder for Different Network Environments

The entry point for all network customization is the **`Builder`** type defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs). It accumulates transport, addressing, and traversal settings before materializing a bound `Endpoint` when you call `.bind().await`. By adjusting bind options, port mapping, relay selection, and proxy settings, you can precisely control how the node behaves across varying topologies.

## Binding to Local Interfaces and Subnets

To control which network interface the endpoint listens on, use **`bind_addr`** for a simple socket address or **`bind_addr_with_opts`** for advanced subnet control. The latter accepts a **`BindOpts`** struct that lets you specify a prefix length and mark the socket as the default route. This logic lives in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) under **`Builder::bind_addr_with_opts`**.

```rust
use iroh::endpoint::BindOpts;

// Bind to a LAN address with a /24 netmask
.bind_addr_with_opts("192.168.1.10:0", BindOpts::default().set_prefix_len(24))

```

## NAT Traversal and Firewall Bypass Options

Residential gateways and enterprise firewalls often block unsolicited inbound traffic. Iroh counters this with port mapping, explicit external address advertisement, and relay fallback. Each strategy is exposed as a builder method in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

### Automatic Port Mapping with `portmapper_config`

Iroh can negotiate port openings via UPnP, PCP, or NAT-PMP through the port-mapper subsystem in [`iroh/src/portmapper.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/portmapper.rs). Enable this behavior with **`portmapper_config`**, which is the default, or disable it to avoid SSDP multicast traffic that can trigger firewall alerts.

```rust
.portmapper_config(iroh::PortmapperConfig::Enabled {})

```

### Advertising External Addresses with `external_addr`

If you already know a public address from a STUN probe or static allocation, inject it with **`external_addr`**. These addresses are announced to peers and used during NAT traversal, as implemented in **`Builder::external_addr`** near line 444 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

```rust
.external_addr("203.0.113.42:0".parse().unwrap())

```

### Relay Selection with `relay_mode`

When direct hole punching fails, fall back to a relay server via **`relay_mode`**. You can pass **`RelayMode::Default`**, **`RelayMode::Staging`**, or a custom `RelayMap` to provide a rendezvous point for traffic behind symmetric NATs and strict firewalls.

```rust
use iroh::endpoint::RelayMode;

.relay_mode(RelayMode::Default)

```

## Proxy and Address Lookup Configuration

Corporate proxies and custom discovery layers require additional HTTP(S) routing and address resolution. The builder exposes **`proxy_url`** and **`address_lookup`** for these scenarios, both defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

### Routing Outbound HTTPS Through a Proxy

Route relay lookups and DNS-over-HTTPS through an outbound proxy using **`proxy_url`**, or automatically ingest standard environment variables with **`proxy_from_env`**. According to the source, **`Builder::proxy_url`** is located around line 889 of [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs).

```rust
.proxy_from_env()

```

### Pluggable Address Lookup Services

To help peers discover your endpoint even when NAT masks your address, plug in a lookup service with **`address_lookup`**. The default implementation supports DNS and pkarr, and you can supply custom logic through [`iroh/src/address_lookup.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/address_lookup.rs).

```rust
.address_lookup(my_custom_lookup_service)

```

## Environment-Specific Configuration Patterns

The following patterns assemble the individual builder methods into complete configurations for three common deployment scenarios. Each example is fully runnable and targets a specific network constraint.

### Home Router Behind NAT

Bind to the LAN interface so traffic stays on the correct subnet, keep port mapping enabled to open the router automatically, and advertise a public address if you already know it. This combination maximizes the odds of a direct connection while still allowing relay fallback.

```rust
use iroh::{Endpoint, endpoint::presets, endpoint::BindOpts};

async fn home_nat() -> n0_error::Result<()> {
    let endpoint = Endpoint::builder(presets::N0)
        .bind_addr_with_opts(
            "192.168.1.10:0",
            BindOpts::default().set_prefix_len(24),
        )?
        .external_addr("203.0.113.42:0".parse().unwrap())
        .portmapper_config(iroh::PortmapperConfig::Enabled {})
        .bind()
        .await?;

    Ok(())
}

```

### Corporate Firewall

In restrictive enterprise environments, SSDP discovery is frequently blocked and outbound ports are filtered. Disable the port mapper to avoid blocked multicast probes, force relay usage for connectivity, and send all HTTP(S) traffic through the corporate proxy.

```rust
use iroh::{Endpoint, endpoint::presets, endpoint::RelayMode};

async fn corporate_firewall() -> n0_error::Result<()> {
    let endpoint = Endpoint::builder(presets::N0)
        .bind()
        .await?
        .portmapper_config(iroh::PortmapperConfig::Disabled)
        .relay_mode(RelayMode::Staging)
        .proxy_from_env()
        .await?;

    Ok(())
}

```

### Public Server with Static IP

Publicly routable hosts do not need port mapping or relay fallback for inbound connections. Bind to all interfaces with `0.0.0.0:0` and explicitly inject the static public address so peers can reach you directly.

```rust
use iroh::{Endpoint, endpoint::presets};

async fn public_server() -> n0_error::Result<()> {
    let endpoint = Endpoint::builder(presets::N0)
        .bind_addr("0.0.0.0:0")?
        .external_addr("198.51.100.77:0".parse().unwrap())
        .bind()
        .await?;

    Ok(())
}

```

## Summary

- The **`Builder`** in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) is the central API used to configure an iroh endpoint for different network environments.
- Use **`bind_addr_with_opts`** to pin the endpoint to a specific interface or subnet.
- Enable **`portmapper_config`** for automatic NAT traversal on home routers, or disable it in firewall-sensitive environments.
- Set **`relay_mode`** and **`proxy_url`** when direct connectivity is blocked by symmetric NATs or corporate firewalls.
- Inject known public addresses with **`external_addr`** to accelerate peer discovery on servers with static IPs.

## Frequently Asked Questions

### What is the default relay mode for a new iroh endpoint?

By default, the builder uses **`RelayMode::Default`**, which connects to the standard n0-computer relay infrastructure. This mode provides automatic fallback for NAT and firewall traversal without requiring any explicit configuration. You can override it with a staging relay or a custom `RelayMap` if needed.

### Can I disable all automatic NAT traversal and rely solely on a static address?

Yes. Disable port mapping with **`portmapper_config(iroh::PortmapperConfig::Disabled)`**, skip relay configuration if desired, and supply your expected public address via **`external_addr`**. Peers will then attempt to reach you directly at that address instead of using automated discovery.

### How does the port mapper interact with corporate firewalls?

The port mapper sends SSDP multicast packets to discover local routers, which many corporate firewalls block or flag as suspicious. If your security team reports blocked outbound SSDP alerts, disable the port mapper and rely on a configured relay or proxy for outbound connectivity.

### Is there a way to test whether my endpoint is reachable before advertising it?

The [`iroh/src/net_report/mod.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/net_report/mod.rs) module contains network-report utilities that probe reachability. You can use these probes to determine whether your endpoint is publicly accessible and whether a relay or port mapping is actually necessary.