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 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 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 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 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
- 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~
. - 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 hierAIAG7SESED2AAXGCGBNEVRUWPY======
. - 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 dannaiag7sesed2aaxgcgbnevruwpy
.
.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:
- Base32 Dekodierung der Hauptdomain (ohne TLD und Subdomains).
- Der binäre String, welcher daraus resultiert, wird dann in eine IPv6-Adresse umgewandelt.
3.
- 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. - 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 alsAAAA
sowie Subdomain möglich.
- Falls die TLD
Zooko’s Dreieck
Zooko’s 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.