The meshname DNS system

mk16.de

meshname is a decentralized DNS system. With meshname, decentralized means that it works without central servers such as root servers. Depending on the resolution method, no server is required at all.

History

The first implementation was published on January 19, 2020 by zhoreeq on GitHub and is written in Go. The reference implementation provides a command line tool for resolution/encoding and a simple DNS server. On October 24, 2021, the second implementation by acetone was released under the name mario-dns. This is written in C++ with Qt5 and offers a web interface with REST API. I wrote the third implementation and published it on January 4, 2022. I wrote it in Ruby and designed it as a library. It offers the possibility to perform meshname coding and simple resolutions.

Protocol

The meshname protocol defines two top-level domains (TLDs):

.meship domains can only be resolved to one IPv6 address. .meshname domains need an authoritative DNS server which has a reachable IPv6 address.

The resolution and complete creation of domains therefore differ depending on the TLD, but the basic procedure is the same.

Converting IP addresses into domains

  1. The first step is to convert the IPv6 address into its binary representation: In Ruby you can do this with the following command if you have imported ipaddr: IPAddr.new("200:6fc8:9220:f400:5cc2:305a:4ac6:967e").hton If you have the complete IPv6 address with leading zeros, you can also use POSIX tools: echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain The result is \x02\x00o\xC8\x92 \xF4\x00\\\xC20ZJ\xC6\x96~.
  2. This binary string is now converted into a human-readable string using base32: echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain | base32 The result here is AIAG7SESED2AAXGCGBNEVRUWPY======.
  3. Then remove the padding (the = sign) and write all letters in lower case: echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain | base32 | tr -d '=' | tr '[:upper:]' '[:lower:]' The result is then aiag7sesed2aaxgcgbnevruwpy.

.meship

Meanwhile, you can append .meship to the result just obtained. If a .meship domain is resolved, the procedure is reversed and the encoded IPv6 address is always returned as the AAAA record. Therefore, .meship do not require a central server, as the IP address is in the domain name itself.

.meshname

However, you can also append .meshname to the result obtained. In this case, this means that the encoded address is the IP address of the authoritative DNS server. So if the TXT record of aiag7sesed2aaxgcgbnevruwpy.meshname is queried, the IP address is decoded and the corresponding DNS server 200:6fc8:9220:f400:5cc2:305a:4ac6:967e is queried for a TXT record for the domain aiag7sesed2aaxgcgbnevruwpy.meshname.

Resolution

To resolve a meshname domain, the first step is to reverse the encoding:

  1. base32 decoding of the main domain (without TLD and subdomains).
  2. The resulting binary string is then converted into an IPv6 address. 3.
    1. If the TLD is .meship, the IPv6 address is returned as an AAAA record. If a different record or a subdomain is requested, nothing or an error message is returned.
    2. If the TLD is .meshname, the DNS server whose IP address is encoded in the domain is queried. Therefore, records other than AAAA and subdomain are also possible with this method.

Zooko’s triangle

Zooko’s triangle describes the trilemma that a domain can only ever have two of three properties: - Freely selectable: the domain name can be freely selected or very easily influenced. - Decentralized: The resolution of the domain is not dependent on a central server. - Secure: The records stored by the owner are returned and the records can be verified.

Examples:

meshname domains are not freely selectable as they depend on an IP address. A clever choice of IP address (for example, if you have a larger subnet) can generate simpler domains, but these are still heavily dependent on the IP address. In addition, meshname domains always have the same length. .meship domains are both decentralized (as they can be resolved without an external server) and secure (as the IP address is already encoded in the name itself). .meshname domains are decentralized because no central servers are required. Only a single external server is required for resolution. However, .meshname domains are only partially secure. Although the correct authoritative DNS server is always queried, the answer cannot be validated. This means that .meshname domains are vulnerable to man-in-the-middle attacks if someone controls the connection between the resolving server and the authoritative DNS server.

Practice

In order to build the reference implementation, it must first be downloaded:

$ git clone https://github.com/zhoreeq/meshname.git

Then you can build the program with make:

$ cd meshname/
$ make

You will then receive a file meshnamed in the same directory, which is executable. If you start this without any further arguments, a DNS server is started at [::1]:53535, which you can query:

$ ./meshnamed 
2024/01/31 11:04:13 Listening on: [::1]:53535
$ dig @::1 -p 53535 aiag7sesed2aaxgcgbnevruwpy.meship AAAA +short
200:6fc8:9220:f400:5cc2:305a:4ac6:967e

To convert an IP address into a domain, you can use the following command:

$ ./meshnamed -getname 200:6fc8:9220:f400:5cc2:305a:4ac6:967e
aiag7sesed2aaxgcgbnevruwpy

To convert the domain back into an IP address, you can do something like this:

$ ./meshnamed -getip aiag7sesed2aaxgcgbnevruwpy
200:6fc8:9220:f400:5cc2:305a:4ac6:967e

Area of application & conclusion

According to the protocol specification, meshname domains should primarily be used by machines - for example to connect to a peer or server. Nevertheless, I personally find it fun to use meshname domains in networks like Yggdrasil.