Technical Documentation: n0-computer/iroh
βΉοΈ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference
Overview (`README.md`)
[](https://iroh.computer)
less net work for networks
What is iroh?
Iroh gives you an API for dialing by public key.
You say βconnect to that phoneβ, iroh will find & maintain the fastest connection for you, regardless of where it is.
Hole-punching
The fastest route is a direct connection, so if necessary, iroh tries to hole-punch.
Should this fail, it can fall back to an open ecosystem of public relay servers.
To ensure these connections are as fast as possible, we continuously measure iroh.
Built on [QUIC]
Iroh uses noq to establish QUIC connections between endpoints.
This way you get authenticated encryption, concurrent streams with stream priorities, a datagram transport and avoid head-of-line-blocking out of the box.
Compose Protocols
Use pre-existing protocols built on iroh instead of writing your own:
- iroh-blobs for BLAKE3-based content-addressed blob transfer scaling from kilobytes to terabytes
- iroh-gossip for establishing publish-subscribe overlay networks that scale, requiring only resources that your average phone can handle
- iroh-docs for an eventually-consistent key-value store of iroh-blobs blobs
Getting Started
Rust Library
It's easiest to use iroh from rust.
Install it using cargo add iroh, then on the connecting side:
const ALPN: &[u8] = b"iroh-example/echo/0";
let endpoint = Endpoint::bind().await?;
// Open a connection to the accepting endpoint
let conn = endpoint.connect(addr, ALPN).await?;
// Open a bidirectional QUIC stream
let (mut send, mut recv) = conn.open_bi().await?;
// Send some data to be echoed
send.write_all(b"Hello, world!").await?;
send.finish()?;
// Receive the echo
let response = recv.read_to_end(1000).await?;
assert_eq!(&response, b"Hello, world!");
// As the side receiving the last application data - say goodbye
conn.close(0u32.into(), b"bye!");
// Close the endpoint and all its connections
endpoint.close().await;And on the accepting side:
let endpoint = Endpoint::bind().await?;
let router = Router::builder(endpoint)
.accept(ALPN.to_vec(), Arc::new(Echo))
.spawn()
.await?;
// The protocol definition:
#[derive(Debug, Clone)]
struct Echo;
impl ProtocolHandler for Echo {
async fn accept(&self, connection: Connection) -> Result<()> {
let (mut send, mut recv) = connection.accept_bi().await?;
// Echo any bytes received back directly.
let bytes_sent = tokio::io::copy(&mut recv, &mut send).await?;
send.finish()?;
connection.closed().await;
Ok(())
}
}The full example code with more comments can be found at echo.rs.
Or use one of the pre-existing protocols, e.g. iroh-blobs or iroh-gossip.
Other Languages
If you want to use iroh from other languages, make sure to check out iroh-ffi, the repository for FFI bindings.
Links
Repository Structure
This repository contains a workspace of crates:
iroh: The core library for hole-punching & communicating with relays.iroh-relay: The relay client and server implementation. This is the code we run in production for the public relays (and you can, too!).iroh-base: Common types likeEndpointIdorRelayUrl.iroh-dns-server: DNS server implementation powering the DNS/Pkarr address lookup for EndpointIds, running at dns.iroh.link.
License
Copyright 2025 N0, INC.
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or
https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Overview (`docker/README.md`)
Iroh Docker Images
Intro
A set of docker images provided to easily run iroh in a containerized environment.
Features iroh-relay and iroh-dns-server.
The provided Docker files are intended for CI use but can be also manually built.
Building
- All commands are run from the root folder
- If you're on macOS run
docker buildx build -f docker/Dockerfile --target iroh-relay --platform linux/arm64/v8 --tag n0computer/iroh-relay:latest . - If you're on linux run
docker buildx build -f docker/Dockerfile --target iroh-relay --platform linux/amd64 --tag n0computer/iroh-relay:latest . - Switch out
--target iroh-relayforiroh-dns-server
Running
iroh-relay
- Provide a config file:
docker run -v /path/to/iroh-relay.conf:/config/iroh-relay.conf -p 80:80 -p 443:443 -p 3478:3478/udp -p 9090:9090 -it n0computer/iroh-relay:latest --config /config/iroh-relay.conf
iroh-dns-server
- Provide a config file:
docker run -v /path/to/iroh-dns-server.conf:/config/iroh-dns-server.conf -p 53:53/udp -p 9090:9090 -it n0computer/iroh-dns-server:latest --config /config/iroh-dns-server.conf
Overview (`iroh-base/README.md`)
iroh-base
This crate provides base types and utilities used throughout Iroh.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or
https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
Overview (`iroh-dns-server/README.md`)
iroh-dns-server
A server that functions as a pkarr relay and
DNS server.
This server compiles to a binary iroh-dns-server. It needs a config file, of
which there are two examples included:
config.dev.toml- suitable for local developmentconfig.prod.toml- suitable for production, after
adjusting the domain names and IP addresses
The server will expose the following services:
- A DNS server listening on UDP and TCP for DNS queries
- A HTTP and/or HTTPS server which provides the following routes:
/pkarr:GETandPUTfor pkarr signed packets/dns-query: Answer DNS queries over
DNS-over-HTTPS
All received and valid pkarr signed packets will be served over DNS. The pkarr
packet origin will be appended with the origin as configured by this server.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
Overview (`iroh-dns/README.md`)
iroh-dns
DNS-based endpoint discovery for Iroh.
This crate contains the core types for publishing and resolving iroh endpoint information via DNS, using the pkarr signed packet format.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or
https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
Overview (`iroh-relay/README.md`)
Iroh Relay
Iroh's relay is a feature within iroh, a peer-to-peer networking system
designed to facilitate direct, encrypted connections between devices. Iroh aims
to simplify decentralized communication by automatically handling connections
through "relays" when direct connections aren't immediately possible. The relay
server helps establish connections by temporarily routing encrypted traffic
until a direct, P2P connection is feasible. Once this direct path is set up,
the relay server steps back, and the data flows directly between devices. This
approach allows Iroh to maintain a secure, low-latency connection, even in
challenging network situations.
This crate provides a complete setup for creating and interacting with iroh
relays, including:
- Relay Protocol: The protocol used to communicate between relay servers and
clients - Relay Server: A fully-fledged iroh-relay server over HTTP or HTTPS.
Optionally will also expose a QAD endpoint and metrics. - Relay Client: A client for establishing connections to the relay.
- Server Binary: A CLI for running your own relay server. It can be configured
to also expose metrics.
Used in iroh, created with love by the n0 team.
Build the server
You can build an optimised release of iroh-relay by running cargo build
with the appropriate flags from the workspace parent directory as follows.
cd ../
cargo build \
--profile optimized-release \
--package iroh-relay \
--features serverYou will find the optimised binary at target/optimized-release/iroh-relay.
Access control
The relay server supports several access control modes, configured via theaccess field in the TOML config file.
Allow everyone (default)
access = "everyone"Allowlist / Denylist by endpoint ID
# Allow only specific endpoints
access.allowlist = ["<endpoint-id>", "<endpoint-id>"]
# Or block specific endpoints and allow everyone else
access.denylist = ["<endpoint-id>"]Shared token (local, no external service)
Requires connecting clients to present one of the configured shared secrets via anAuthorization: Bearer <token> header, or a ?token= URL query parameter.
access.shared_token = ["token-a", "token-b"]The token list can also be overridden by the IROH_RELAY_ACCESS_TOKEN environment
variable, which sets a single allowed token and takes precedence over the config file
value. A single value is used (rather than a comma-separated list) to avoid restricting
the character set of tokens.
The token list must not be empty, and no token may be an empty string; the server will
fail to start if either condition is violated.
On the client side, set the token usingRelayConfig::with_auth_token
orRelayMap::with_auth_token.
Note: this shared token does not support revocation other than updating the config and restarting the service.
HTTP callout (external auth service)
The relay calls an external HTTP endpoint for each incoming connection,
passing the connecting endpoint's ID. The token below authenticates the relay
to your auth service (machine-to-machine), not the connecting client.
access.http.url = "https://your-auth-service.example.com/relay-auth"
# Optional: authenticate the relay's outbound request to your service
access.http.bearer_token = "service-to-service-secret"The bearer token can also be set via the IROH_RELAY_HTTP_BEARER_TOKEN
environment variable.
For every connection, the relay sends a POST request with no body toaccess.http.url. The connecting endpoint's ID is sent in theX-Iroh-Endpoint-Id header. If a bearer token is configured, it is sent in anAuthorization: Bearer <token> header.
To allow the connection, your service must respond with status 200 and the
response body true.
Example request:
POST /relay-auth HTTP/1.1
x-iroh-endpoint-id: da1ee49ba54d124a2e2b0f043bac3d63ec086b0b40e7d0895914898b237e847e
x-iroh-nodeid: da1ee49ba54d124a2e2b0f043bac3d63ec086b0b40e7d0895914898b237e847e
authorization: Bearer service-to-service-secret
accept: */*
host: your-auth-service.example.comNote: the endpoint ID is also sent in the deprecated
X-Iroh-NodeId
header for backwards compatibility. It will be removed in a future release.
New services should useX-Iroh-Endpoint-Id.
Local testing
Advice for testing your application that uses iroh with a locally running iroh-relay server
dev mode
When running the relay server using the --dev flag, you will:
- only run the server over http, not https
- will NOT run the QUIC endpoint that enables QUIC address discovery
The relay can be contacted at "http://localhost:3340".
Both https and QUIC address discovery require TLS certificates. It's possible to run QUIC address discovery using locally generated TLS certificates, but it takes a few extra steps and so, is disabled by default for now.
dev mode with QUIC address discovery
So you want to test out QUIC address discovery locally?
In order to do that you need TLS certificates.
The easiest get that is to generate self-signed certificates using rcgen
- get rcgen (
git clone https://github.com/rustls/rcgen) - cd to the
rcgendirectory - generate local certs using
cargo run -- -o path/to/certs
Next, add the certificate paths to your iroh-relay config, here is an example of a config.toml file that will enable quic address discovery.
enable_quic_addr_discovery = true
[tls]
cert_mode = "Manual"
manual_cert_path = "/path/to/certs/cert.pem"
manual_key_path = "/path/to/certs/cert.key.pem"Then run the server with the --dev flag, like you would when normally testing locally:cargo run --features="server" --bin iroh-relay -- --config-path=/path/to/config.toml --dev
The relay server will run over http on port 3340, as it does using the --dev flag, but it will also run a QUIC server on port 7824.
The relay will use the configured TLS certificates for the QUIC connection, but use http (rather than https) for the server.
Using iroh-relay as a library to run in-process relays in integration tests
When using iroh as a transport library in an application or other library, there is a simple way of running an in-process relay server:
- Enable
test-utilsfeature of theirohcrate
iroh = { version = "0.95", features = ["test-utils"] }- Spawn a relay server by calling
iroh::test_utils::run_relay_server().await
This will start a relay server with a self-signed TLS certificate, listening on a localhost port, and return the server's URL. - For the iroh endpoints to successfully connect to the relay, disable TLS certificate verification by calling
Endpoint::ca_tls_configwithCaRootConfig::insecure_skip_verify().
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or
https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
Overview (`iroh/README.md`)
less net work for networks
Iroh is a Rust library to establish direct connections between endpoints.
It gives you an API for dialing by public key. You say "connect to that
endpoint", and iroh finds and maintains the best connection for you.
Under the hood iroh establishes peer-to-peer QUIC connections between
endpoints. The fastest route is a direct connection, so iroh tries to
hole-punch one whenever it can. If that fails it falls back to using
relay servers.
Because iroh is built on QUIC, all connections are end-to-end encrypted and may
carry any number of concurrent streams. Dialing by public key also makes them mutually
authenticated, because each endpoint's public key is its TLS identity.
Overview
An iroh endpoint is created and controlled by the Endpoint. Each endpoint
has a unique SecretKey, whose public key is the endpoint's identity, theEndpointId. Connections are authenticated against this key, which means anEndpointId can't be impersonated.
A connection is usually established with the help of a relay server. When an
endpoint is created it connects to the closest relay and designates it as its
home relay. Other endpoints reach it first through this relay, then both
sides use QUIC NAT traversal to establish a direct connection. In the rare
cases where a direct connection is not possible, traffic keeps flowing over the
relay.
Relay servers only forward encrypted packets addressed to Endpoint IDs, they
cannot read any traffic between endpoints.
Endpoints can also connect directly without a relay, as long as the accepting
endpoint is directly reachable at one of its addresses.
To discover addressing information for an endpoint, iroh uses
address lookup services. With address lookup, you can connect to other
endpoints with only their EndpointId. Addressing information will then
be resolved on-demand.
The N0 preset installs the DNS/Pkarr address lookup service, which uses
servers hosted by n0 to provide global lookup for endpoints.
Example
This is an echo protocol: the accepting side copies back whatever it receives.
The full, commented version is in echo.rs.
/* Detailed source-code truncated for AI context efficiency. */More examples live in iroh/examples. Run them withcargo run --example NAME. Details for each are in the file itself.
Compose protocols
Instead of writing your own, you can build on protocols that already exist on
top of iroh:
- iroh-blobs for BLAKE3-based content-addressed blob transfer, scaling from
kilobytes to terabytes. - iroh-gossip for publish-subscribe overlay networks that scale down to what
an average phone can handle. - and many more.
To use iroh from other languages, see iroh-ffi.
Development
For notes on iroh's structured events and how to build the documentation, see
DEVELOPMENT.md.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or
https://www.apache.org/licenses/LICENSE-2.0) - MIT license (LICENSE-MIT or
https://opensource.org/licenses/MIT)
at your option.
Contribution
See CONTRIBUTING.md
for how to get involved.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
Iroh Docs Local Relays (`iroh/docs/local_relays.md`)
Using a local iroh-relay
It's easy to set up a iroh-relay that runs locally on your machine.
Using cargo:
$ cargo run --bin iroh-relay --features="iroh-relay" -- --devThis will bind the iroh-relay to [::]3340 and run it over HTTP.
To connect to this iroh-relay when doing your normal iroh commands, adjust the iroh configuration file to read:
# iroh.config.toml:
[[relays]]
url = "http://localhost:3340"If you want to give a specific port for the iroh-relay to bind to, you can create a iroh-relay config file and pass that file in using the --config_path flag. You need to retain a secret_key, so it is recommended to run iroh-relay --config-path [PATH] once to generate a secret key and save it to the config file before doing further edits to the file.
To change the port you want to listen on, change the port in the addr field:
# iroh-relay.toml
secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
addr = "[::]:12345"
hostname = "my.relay.network"
enable_relay = trueCheck the iroh-relay file's Config struct for documentation on each configuration field.
If you change the local iroh-relay server's configuration, however, be sure to adjust the associated fields in your iroh config as well.
Iroh Docs Relays (`iroh/docs/relays.md`)
Relays
When an Iroh endpoint starts up, it does a latency test to see which known relay endpoint it is βclosest toβ. That relay server is considered the Iroh endpoint's home relay server.
An endpoint may be connected to multiple relay servers, but it will advertise its home relay endpoint as the one best used to hole-punch or relay packets through.
You do not need to know an endpoint's relay server in order to connect to them directly, if there are no firewalls or NATs between the two endpoints trying to connect. However, to have any hole punching, you must know at least one relay server to which that endpoint is connected.
We currently run 3 relays.
--- METRICS ---
- Files Extracted: 9
- Estimated Token Budget: ~6084 tokens
- Canonical Reference: https://codewiki.google/github.com/n0-computer/iroh