Distribute darknet node addresses via DNS seeds using AAAA records #31062

issue virtu openend this issue on October 9, 2024
  1. virtu commented at 12:27 pm on October 9, 2024: contributor

    Please describe the feature you’d like to see added.

    Right now, Bitcoin Core can only receive IPv4 and IPv6 node addresses from DNS seeds. Adding support for darknet addresses would bring the advantages of using DNS seeds (more privacy, faster bootstrapping, etc.) for node discovery to darknet nodes.

    No response

    Describe the solution you’d like

    Before TorV2 addresses were deprecated, Bitcoin Core and seeds using sipa’s seeder (and maybe others) supported distributing such addresses by encoding them in AAAA records: Since TorV2 addresses used only 80-bit hashes, they neatly fitted into the 128-bit data field of an AAAA record, leaving plenty of room for a 48bit prefix (from the not publicly routable fc00::/7 subnet) to signal the custom encoding.

    TorV3 and I2p addresses use 256-bits of data, making them too large for single AAAA records. However, such addresses can be serialized using a trimmed BIP155 format (just the net id and address), concatenated, and broken into chunks that fit into AAAA record data fields.

    In addition to a prefix to signal the custom encoding, correct deserialization requires a sequence number since public resolvers may reorder records.

    To get a rough estimate for the numbers, consider the following: DNS messages should be at most 512B. The header has a fixed size of 12B. The question section has variable size because it contains the query domain. 30 chars should be sufficient for most seeds, which implies a size of 36B for the question section (32B for the 30 chars, plus 2B each for query type and class). This leaves 464B for the record section. Since AAAA records are 28B each (2B each for name pointer, type, class, length, 4B for TTL, and 128b/16B for data), a DNS reply for regular-length domains can at most contain 16 AAAA records. Hence four bits are required to encode sequence numbers.

    The publicly unroutable fc00::/7 prefix used in the past uses 7 bits. Extending these by e.g. five more bits for versioning to accommodate for future updates results in a signaling-prefix size of 12 bits, leaving 112 bit (or 14B) for payload:

    0 0         11 12       15 16                                                       127
    1+------------+----------+------------------------------------------------------------+
    2|  Prefix    |   Seq#   |                         Payload                            |
    3|  (12 bits) | (4 bits) |                        (112 bits)                          |
    4+------------+----------+------------------------------------------------------------+
    

    At 16 AAAA records per DNS message, 14B of payload per record and 33B per TorV3/I2P address (net id plus 256-bit data), six TorV3/I2P addresses can be encoded per message.

    CJDNS addresses, which are IPv6 addresses, could be encoded as well; at 17B per address (net id plus 128-bit data), 13 addresses could be encoded per message.

    To avoid interfering with legacy software, darknet addresses could only be distributed via special subdomains (similar to x used for version bits), e.g. ni, where n stands for network id and i for a particular network id specified in BIP155. Example x9.n4.seed.acme.com.

    Demo implementation: https://github.com/virtu/darkseed Demo DNS seed: dnsseed.21.ninja

    Describe any alternatives you’ve considered

    Originally, I considered using DNS NULL records, because their data fields allow for an arbitrary amount of binary data, resulting in a much better encoding efficiency than ~50% offered by the proposed AAAA encoding (14B of overhead-including payload per 28B record).

    This approach, however, has the following shortcomings (as pointed out by sipa in the forum):

    • Depend on external DNS library or extra code to create DNS request with NULL query type
    • Public recursive resolvers might not cache DNS NULL records

    Please leave any additional context

    No response

  2. virtu added the label Feature on Oct 9, 2024
  3. vasild commented at 6:57 am on October 11, 2024: contributor

    Concept ACK

    … from the not publicly routable fc00::/7 subnet …

    This overlaps with CJDNS which uses fc00::/8. This should be ok since those special AAAA records are going to be server by special DNS servers that are separate from the existent ones. Whoever queries them will be aware of the special encoding. Then maybe a special prefix is not needed at all?

    Since this is Bitcoin P2P specific and since that needs address+port, and in the light of #31036 maybe include 2 more bytes for a port as well.

  4. 1440000bytes commented at 7:19 am on October 11, 2024: none

    Concept NACK

    Onion and i2p nodes not dependent on DNS seeds is a feature. It’s better if only IPv4 and IPv6 nodes use it.

    Maybe we could experiment with GNS? Or use this approach for IPv4 nodes with non default port? https://github.com/bitcoin/bitcoin/issues/30900

  5. laanwj commented at 8:45 am on October 17, 2024: member

    Concept NACK

    It’s a clever trick, but we’ve considered this kind of thing before and it’s a really a deep rabbit hole.

    From what i heard it’s not generally a good idea to stash different data in AAAA records. Caching DNS servers can have checks to assume the addresses are routable and valid. Additionally, there’s also no guarantee that clients get all the addresses, so splitting the data is a bit brittle.

    This would also break the assumption that a random address returned from the DNS seed is connectable (because they might get a fragment instead). Bitcoin core peers fully behind Tor rely on this behavior.

    Also wonder, like @1440000bytes, what would be the motivation to have I2P and Tor addresses returned by DNS seeds? Mind that clients behind neither can do DNS queries (well, Tor has a SOCKS extension to do a DNS query, but it cannot return more than one result), and querying through clearnet through ISP’s DNS servers is a leak.

    One could return arbitrary data in TXT records but they’re much harder to query from C++ code, and suffer from the same above problem.

  6. virtu commented at 7:39 am on October 18, 2024: contributor

    From what i heard it’s not generally a good idea to stash different data in AAAA records. Caching DNS servers can have checks to assume the addresses are routable and valid. Additionally, there’s also no guarantee that clients get all the addresses, so splitting the data is a bit brittle.

    This would also break the assumption that a random address returned from the DNS seed is connectable (because they might get a fragment instead). Bitcoin core peers fully behind Tor rely on this behavior.

    I agree that all of these are problems. But I think we can work around all of them with DNSSEC (however, I’m not a DNS expert, so the following reasoning might not be entirely correct):

    • If this were to be though of v2 dns seeding and used dedicated subdomains (e.g. nX like described above), Bitcoin Core could make implicit assumptions about addresses, making the signaling prefix unnecessary; instead, one could choose a valid prefix to ensure each address is routable.
    • The RRSets’ ordering and completeness can be enforced by mandating the use of DNSSEC, which prohibits omission and reordering after RRset canonicalization to ensure a valid signature.

    Also wonder, like @1440000bytes, what would be the motivation to have I2P and Tor addresses returned by DNS seeds? Mind that clients behind neither can do DNS queries (well, Tor has a SOCKS extension to do a DNS query, but it cannot return more than one result), and querying through clearnet through ISP’s DNS servers is a leak.

    Apart from bringing the benefits of DNS seeds to non-IP nodes, this could also be a solution to #31036 if the scope were increased to also cover IP addresses and port numbers.

  7. vasild commented at 11:17 am on November 5, 2024: contributor

    I agree with the reasoning above. I am still Concept ACK if we can have the clients get all addresses from the response, without some addresses being omitted. I see no downsides if separate DNS seeds are used for the new encoding, leaving the existent ones as they are currently.

    Just to clarify - Tor only nodes do not use DNS seeds and the intention here is to keep it that way. The motivation is to help multi-homed nodes that use clearnet and Tor. They are currently only getting clearnet addresses from the DNS seeds.

    To include ports in the DNS seeds responses is a separate motivation for this.

  8. willcl-ark commented at 10:53 am on November 29, 2024: member

    Might it not make more sense to avoid hacking DNS responses for this, or using DNS at all, and simply include some native Tor (/I2P/CJDNS) addresses in the vSeeds chainparams list? These hard-coded addresses could still point to a DNS seeder which can respond to addr_fetch requests from its hidden service (or I2P equivalent) with addresses of that type only. @achow101 dnsseedrs already has onion, I2P and CJDNS results available to query, for example.

    This avoids any requirement to use DNS over Tor (which may not be available anyway), and, whilst we may lose some of the other benefits of using DNS (like caching of addrs in the DNS itself), the marginal privacy benefits of requesting addrs via DNS seeds, which someone using a recursive resolver might get, are already included as part of connecting via an anonymity network.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-26 21:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me