---
layout: page
title: Das meshname DNS-System
permalink: /blog/meshname-de/
keywords: meshname,meship,dns,yggdrasil
description: Was ist meshname? Wie löst man .meshname und .meship-Domains auf? Und wie funktioniert das Ganze? Was steckt dahinter?
lang: de
feed: true
date: 2024-12-04 00:00:00 +0100
---

meshname ist ein dezentrales DNS-System. Dezentral bedeutet bei Meshname, dass es ohne zentrale Server wie Root-Server auskommt. Je nach Auflösungsmethode wird auch überhaupt kein Server benötigt.

## Geschichte

Die [erste Implementierung](https://github.com/zhoreeq/meshname/) wurde am 19. Januar 2020 von zhoreeq auf GitHub veröffentlicht und in Go geschrieben. Die Referenzimplementierung stellt lediglich ein Kommandozeilentool zur Auflösung bzw. Kodierung sowie einen einfachen DNS-Server bereit.
Am 24. Oktober 2021 kam die [zweite Implementierung](https://notabug.org/acetone/mario-dns) von acetone mit dem Namen `mario-dns` auf. Diese wurde in C++ mit Qt5 geschrieben und bietet ein Web-Interface mit REST API an.
Die [dritte Implementierung](https://codeberg.org/mark22k/meshname/) habe ich geschrieben und am 4. Januar 2022 erstmalig veröffentlicht. Ich habe diese in Ruby geschrieben und als Bibliothek konzipiert. Sie bietet die Möglichkeit an, meshname Kodierungen und einfache Auflösungen durchzuführen.

## Protokoll

Das [Meshname-Protokoll](https://github.com/zhoreeq/meshname/blob/master/protocol.md) definiert zwei Top-Level-Domains (TLDs):
- `.meshname`
- `.meship`

`.meship`-Domains können nur auf eine IPv6-Adresse aufgelöst werden. `.meshname`-Domains brauchen einen autoritativen DNS-Server, welcher eine erreichbare IPv6-Adresse hat.

Die Auflösung und vollständige Erstellung von Domains unterscheiden sich daher nach TLD, jedoch ist das grundsätzliche Verfahren das Gleiche.

### IP-Adressen in Domain umwandeln

1. Der erste Schritt besteht darin, die IPv6-Adresse in ihre binäre Darstellung umzuwandeln:
  In Ruby kann man dies mit folgendem Befehl machen, wenn man `ipaddr` importiert hat: `IPAddr.new("200:6fc8:9220:f400:5cc2:305a:4ac6:967e").hton`
  Wenn man die vollständige IPv6-Adresse mit führenden Nullen hat, kann man auch POSIX-Werkzeugen verwenden:
  `echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain`
  Das Ergebnis ist `\x02\x00o\xC8\x92 \xF4\x00\\\xC20ZJ\xC6\x96~`.
2. Diesen binären String konvertiert man nun mithilfe von base32 in einen menschenlesbaren String:
  `echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain | base32`
  Das Ergebnis ist hier `AIAG7SESED2AAXGCGBNEVRUWPY======`.
3. Danach entfernt man das Padding (also `=`-Zeichen) und schreibt alle Buchstaben klein:
  `echo "0200:6fc8:9220:f400:5cc2:305a:4ac6:967e" | tr -d ':' | xxd -revert -plain | base32 | tr -d '=' | tr '[:upper:]' '[:lower:]'`
  Das Ergebnis ist dann `aiag7sesed2aaxgcgbnevruwpy`.

### .meship

An das eben gewonnene Ergebnis kann man indessen `.meship` anhängen. Wenn eine `.meship`-Domain aufgelöst wird, wird das Verfahren umgekehrt und immer die kodierte IPv6-Adresse als AAAA-Rekord zurückgegeben. `.meship` benötigen daher keinen zentralen Server, da die IP-Adresse im Domainnamen selber ist.

### .meshname

Man kann an das gewonnene Ergebnis jedoch auch `.meshname` anhängen. In diesem Fall bedeutet dies, dass die kodierte Adresse, die IP-Adresse des autoritativen DNS-Servers ist. Wenn also der TXT-Rekord von `aiag7sesed2aaxgcgbnevruwpy.meshname` abgefragt wird, wird die IP-Adresse dekodiert und der entsprechende DNS-Server `200:6fc8:9220:f400:5cc2:305a:4ac6:967e` nach einem TXT-Rekord für die Domain `aiag7sesed2aaxgcgbnevruwpy.meshname` befragt.

### Auflösung

Um eine meshname-Domain aufzulösen, wird als Erstes die Kodierung umgekehrt:
1. Base32 Dekodierung der Hauptdomain (ohne TLD und Subdomains).
2. Der binäre String, welcher daraus resultiert, wird dann in eine IPv6-Adresse umgewandelt.
3.
    1. Falls die TLD `.meship` ist, wird die IPv6-Adresse als AAAA-Rekord zurückgegeben. Wird ein anderer Rekord oder eine Subdomain angefragt, wird nichts bzw. eine Fehlermeldung zurückgegeben.
    2. Falls die TLD `.meshname` ist, wird der DNS-Server befragt, dessen IP-Adresse in der Domain kodiert ist. Daher sind bei dieser Methode auch andere Rekords als `AAAA` sowie Subdomain möglich.

## Zooko's Dreieck

[Zooko's Dreieck](https://de.wikipedia.org/wiki/Zookos_Dreieck) beschreibt das Trilemma, dass eine Domain immer nur zwei von drei Eigenschaften haben kann:
    - Frei wählbar: Der Domainname ist frei wählbar oder sehr leicht beeinflussbar.
    - Dezentral: Die Auflösung der Domain ist nicht von einem zentralen Server abhängig.
    - Sicher: Es werden die vom Eigentümer hinterlegten Rekords zurückgegeben und dies kann sichergestellt werden.

Beispiele:
- Mit DNSSEC gesicherte Domains sind sowohl frei wählbar als auch sicher, jedoch nicht dezentral, da ihre Auflösung von zentralen Root-Servern abhängt.
- .onion oder .b32.i2p-Domains sind dezentral und sicher, jedoch nicht frei wählbar.

meshname-Domains sind nicht frei wählbar, da sie von einer IP-Adresse abhängen. Durch eine geschickte Wahl der IP-Adresse (beispielsweise, wenn man ein größeres Subnetz hat) kann man zwar einfachere Domains generieren, jedoch hängen diese immer noch stark von der IP-Adresse ab. Darüber hinaus haben meshname-Domains immer dieselbe Länge.
`.meship`-Domains sind sowohl dezentral (da man sie ohne externen Server auflösen kann) als auch sicher (da die IP-Adresse bereits im Namen selber kodiert ist).
`.meshname`-Domains sind dezentral, da keine zentralen Server benötigt werden. Es wird lediglich ein einziger externer Server zur Auflösung benötigt. Jedoch sind `.meshname`-Domains nur bedingt sicher. Es wird zwar immer der richtige autoritative DNS-Server befragt, jedoch kann die Antwort nicht validiert werden. `.meshname`-Domains sind also für Man-in-the-Middle-Angriffe anfällig, wenn jemand die Verbindung zwischen Server, der auflöst und dem autoritativen DNS-Server kontrolliert.

## Praxis

Um die Referenzimplementierung zu bauen, muss diese als erstes heruntergeladen werden:
```
$ git clone https://github.com/zhoreeq/meshname.git
```

Danach kann man das Programm mit `make` bauen:
```
$ cd meshname/
$ make
```

Danach erhält man im selben Verzeichnis eine Datei `meshnamed`, welche ausführbar ist. Startet man diese ohne weitere Argumente, so wird ein DNS-Server auf `[::1]:53535` gestartet, welchen man befragen kann:
```
$ ./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
```

Um eine IP-Adresse in eine Domain umzuwandeln, kann man folgenden Befehl nutzen:
```
$ ./meshnamed -getname 200:6fc8:9220:f400:5cc2:305a:4ac6:967e
aiag7sesed2aaxgcgbnevruwpy
```

Um die Domain wiederum in eine IP-Adresse umzuwandeln, kann man so etwas ausführen:
```
$ ./meshnamed -getip aiag7sesed2aaxgcgbnevruwpy
200:6fc8:9220:f400:5cc2:305a:4ac6:967e
```

## Anwendungsbereich & Schluss

meshname-Domains sollten laut Protokollspezifikation primär von Maschinen verwendet werden - beispielsweise um sich zu einem Peer oder Server zu verbinden. Dennoch finde ich es persönlich spaßig, meshname-Domains in Netzwerken wie Yggdrasil zu verwenden.

## Links

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

