iroh icon indicating copy to clipboard operation
iroh copied to clipboard

RFC: `_iroh` DNS records and pkarr signed packets

Open Frando opened this issue 1 year ago • 3 comments

This is a proposal for spec on how Iroh uses the Domain Name System (DNS) and Pkarr for node discovery.

Implementation in iroh is at #2045, and iroh-dns-server, and a first discussion on the design happened in n0-computer/iroh-dns-server#5.

This is a first draft without much focus on edge cases, but wanted to condense the discussion into something we can finalize.

Node discovery via DNS

When connecting to an unknown NodeId, the DNS discovery mechanism in Iroh will perform a DNS query to discover relays or addresses for the node. The DNS discovery is configured with a origin domain (which defaults to dns.iroh.link, a server run by n0). Iroh will then perform a DNS query through the DNS resolver (which defaults to using the host system's nameservers):

_iroh.<z32-node-id>.<origin-domain> TXT

  • _iroh is the record name defined in this spec
  • <z32-node-id> is the z32 encoding of the 32-byte long NodeId (which is a string of 52 characters)
  • <origin-domain> is the configured origin domain
  • TXT is the queried record type

The returned TXT records must contain a string value of the form key=value, as defined in RFC1464. If a record contains multiple character strings, they will be concatenated first. All characters after the first = character form the value string, and those before the first = are the key. The attributes from all valid TXT records will be merged, and each key can therefore have either one or multiple values.

This spec defines the following attributes:

  • relay=<url>: The home relay for this node, e.g. https://euw1-1.derp.iroh.network.
  • addr=<addr> <addr> .. A space-seperated list of socket addresses for this Iroh node. Each address is an IPv4 or IPv6 address with a port (e.g. 1.2.3.4:7367 or [::1]:3521

Node announces via pkarr

Nodes announce their address information in Pkarr signed packets. The TXT records, as described above, are added to the answers section of a DNS section as specified by pkarr. Their name must be _iroh.<z32-node-id>. The z32 encoded node ID must be the root name, no other origin but . (the single dot) is permitted.

Those packets can either be published to a Pkarr relay or to the mainline DHT, as specified by Pkarr.

DNS servers that support this spec will receive these Pkarr signed packets, check their signature and format validity, and then serve each contained record, with the DNS server's configured origin domain appended to all record names.

Further reading

See https://github.com/n0-computer/iroh-dns-server/pull/5#issuecomment-2034165030 for links to more resources.

Frando avatar Apr 04 '24 18:04 Frando

This seems pretty nice. It adheres to DNS conventions as far as I can see, also adheres to pkarr philosophy ("The z32 encoded node ID must be the root name, no other origin but . (the single dot) is permitted.").

The only thing debatable is whether the addr=<addr> <addr> .. format of combining multiple addrs won't exceed some size limit or should be separate records.

Why not

addr=<addr1>
addr=<addr1>

instead of

addr=<addr1> <addr2>

?

There is probably a good reason, just curious about that choice.

rklaehn avatar Apr 09 '24 07:04 rklaehn

I'm kind of surprised we add direct addrs in there. If we even publish those they could easily go in A and AAAA records, but I guess they'd be unsigned in that case.

flub avatar Apr 09 '24 14:04 flub

I'm kind of surprised we add direct addrs in there. If we even publish those they could easily go in A and AAAA records, but I guess they'd be unsigned in that case.

We need ip addr plus port, and A/AAAA does not have a port.

Signing is no issue, all records are from a single signed packet.

The current DNS PRs do not support addr yet, only relay. I do think it makes sense to support addr at least for resolving, that's why I added it to the spec draft here.

Frando avatar Apr 09 '24 15:04 Frando

Address format, I'd be fine with changing to single addr per record as @rklaehn suggests. It is simpler and more straightforward.

The space-separated list was an idea to save space. I think separate record per address would add around 16 bytes per address (vs space-separated list in a single attribute):

  • space separated: 16 + (n_addr * 24)
  • record each: (16 + 24) * n_addr

but there should only be a couple not lots, so doesn't matter in practice likely even with the 1024 byte limit by pkarr.

Frando avatar Apr 10 '24 23:04 Frando

This is now implemented

dignifiedquire avatar Apr 29 '24 08:04 dignifiedquire