---
layout: page
title: The meshname DNS system
permalink: /blog/meshname-en/
keywords: meshname,meship,dns,yggdrasil
description: What is meshname? How do you resolve .meshname and .meship domains? And how does it all work? What's behind it?
lang: en
feed: true
date: 2024-02-31 00:00:00 +0100
---

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](https://github.com/zhoreeq/meshname/) 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](https://notabug.org/acetone/mario-dns) 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](https://codeberg.org/mark22k/meshname/) 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](https://github.com/zhoreeq/meshname/blob/master/protocol.md) defines two top-level domains (TLDs):
- `.meshname`
- `.meship`

`.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](https://en.wikipedia.org/wiki/Zooko%27s_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:
- Domains secured with DNSSEC are both freely selectable and secure, but not decentralized, as their resolution depends on central root servers.
- .onion or .b32.i2p domains are decentralized and secure, but not freely selectable.

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.

## Links

- [What is correct SOA Record for .meshname domains](https://github.com/zhoreeq/meshname/issues/19)

