layout: page title: Einstieg in Meshtastic permalink: /blog/einstieg-in-meshtastic/ keywords: meshtastic,networking,ip tunneling,lora,rak wireless,rakwireless description: Meine erste Erfahrung mit Meshtastic und ob und wie es möglich ist IP-Tunneling über Meshtastic zu betreiben. lang: de
Neulich bin ich im Fediverse auf ein neues Projekt gestoßen: Meshtastic Bei Meshtastic handelt es sich um ein Peer-to-Peer Mesh-Netzwerk auf Basis von LoRa, einer proprietären Funktechnik.
Die Sache, welche mich besonders bei Meshtastic gelockt hat, ist, dass es IP-Tunneling unterstützt. Ich habe immer wieder Spaß neue Routing- und Netzwerk-Technologien kennenzulernen und ich Meshtastic als eine gute Möglichkeit gesehen, etwas Neues zu lernen.
Um dem Netzwerk beizutreten, braucht man entsprechend ein LoRa-fähiges Gerät mit Meshtastic-Unterstützung. Wenn man nun etwas an einen Knoten senden möchte, sendet man dies in Nachrichten. Jede Nachricht hat einen Channel, auf welchen sie gesendet wird, einen Port, ein TTL und einen Inhalt. Die Nachrichten werden mithilfe von Protobuf kodiert.
Meshtastic benutzt zur Separierung Channels. Dabei gibt es einen Standard Channel, welcher öffentlich ist. Es können beliebig viele weitere hinzugefügt werden (bedingt durch Hardware aktuell nur acht). Die Channels haben Namen und, wenn gewünscht, ein Password. Die Nachrichten werden dann mit AES256-CTR (manche Geräte haben dafür auch Hardware-Unterstützung) verschlüsselt. Jedes Gerät, welches an dem Channel teilnimmt und entsprechend auch das Password weiß, kann die Nachricht wieder entschlüsseln. Des Weiteren wird in einen "primären" und mehrere "sekundäre" Channels unterschieden. Der primäre Channel wird für das Verteilen von Knoteninformationen (Laufzeit, Standort, Akkustand, ...) und für IP-Tunneling verwendet. Auf den sekundären Channels können lediglich Nachrichten ausgetauscht werden.
Jede Meshtastic-Nachricht beinhaltet des Weiteren einen Port. Dieser gibt darüber Auskunft, was die Nachricht beinhaltet (Textnachricht, Knoteninformation, IP-Paket, ...)
Der Mesh-Algorithmus ist recht einfach und implementiert das Prinzip des "Floodings". Jeder Knoten sendet jedes Paket an seinen benachbarten Knoten. Dieser sendet das Paket dann entsprechend weiter. Bei der Weiterleitung des Paketes wird das TTL um eins reduziert. Das Standardmäßige TTL ist 3 - es kann aber bis auf 7 gesetzt werden. Ein Paket mit einer TTL von 0 wird nicht weitergeleitet.
Ich persönlich bin eher der Software-Mensch statt Hardware. Ich finde, Hardware kann recht unberechenbar sein und das Schlimmste von allem: Es zeigt nicht einmal Fehlermeldungen an. Ich brauchte also ein recht einfaches Gerät. Da ich IP-Tunneling machen wollte, brauchte ich sogar mindestens zwei. Da ich aktuell Student bin, müssen die beiden Geräte auch günstig sein. Und da ich ein recht unordentlicher Mensch bin, brauche ich auch eine Hülle bzw. ein Gehäuse für die Geräte. Meshtastic bietet auf ihrer Website eine Liste mit Geräten an. Ich habe mir die Geräte angeschaut und mich schlussendlich für das Meshtastic Starter Kit von RAKwireless entschieden.
Danach kam die Herausforderung des Zusammenbauens. Glücklicherweise bietet RAKwireless eine Dokumentation dafür an.
Nachdem ich die Antennen an dem Board befestigt hatte und in das Gehäuse verschraubt hatte, stellte ich allerdings fest, dass am Gehäuse Schutzfolien waren. Davon war nichts in der Dokumentation erwähnt. Dies bedeutete für mich also, dass ich alles noch einmal abschraubte und wieder zusammenschrauben musste.
Des Weiteren waren nicht genug Schrauben mitgeliefert. Für das Gebäude mit allen möglichen Add-ons braucht man 12 Schrauben, mein Setup ohne Batterie-Halterung braucht 8 Schrauben - mitgeliefert waren aber nur 6 Schrauben.
Ein weiteres Hindernis war die Befestigung der Antennen am Gehäuse. Die Bluetooth-Antenne hat ein kleines Pad mit Kleber, jedoch nicht die LoRa-Antenne. Nachdem ich jedoch wegen der Schutzfolien alles neu zusammengeschraubt war, konnte ich das Klebepad der Bluetooth-Antenne auch nicht mehr verwenden. Ich habe mich dazu entschieden, etwas Heißkleber zu verwenden und die Antennen damit zu verfestigen. Da ich mich nicht mit Hardware auskenne, weiß ich nicht, wie gut diese Idee war - ich weiß nur, dass es bei mir glücklicherweise nichts kaputt gemacht hat.
Danach war die Einrichtung der Geräte dran. Meshtastic bietet dazu ein in Python geschriebenes Kommandozeilen-Tool, eine Weboberfläche (die funktionierte bei mir nicht) und eine Android-App. Ich habe mich für das Kommandozeilen-Tool entschieden. Das Gerät wurde jedoch nicht richtig durch das Tool erkannt. Die Android-App konnte mir auch den Grund erklären: Die Firmware ist zu alt.
Ich habe daraufhin ein "Factory Reset" gemacht und danach die aktuelle Firmware hochgeladen. Mit dem "Factory Reset" wollte ich sicherstellen, dass keine alten Konfigurationsschnipsel von RAKwireless da waren.
Nachdem ich alles eingerichtet habe, war es an der Zeit, die IP-Tunneling-Funktion auszuprobieren:
$ sudo meshtastic --tunnel
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address None.180.153
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address None.253.197
sh: line 1: ifconfig: command not found
Aborting due to:
Auf meinem Computer war ifconfig nicht installiert. ifconfig ist ein altes Tool, welches früher zur Netzwerkkonfiguration verwendet wurde. Heutzutage wird allerdings empfohlen, ip
zu verwenden.
Nachdem ich ifconfig installiert hatte, habe ich das Ganze noch einmal ausprobiert:
$ sudo meshtastic --tunnel
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address None.180.153
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address None.253.197
None.180.153: Unknown host
ifconfig: `--help' gives usage information.
Aborting due to: ifconfig command failed.
Scheinbar wird ifconfig aufgefordert die IP-Adresse None.180.153
zu konfigurieren. Dies liegt daran, dass die App fehlerhaft ist. Hintergrund ist, dass das Kommandozeilenargument zur Festlegung des Subnets verwendet wird. Wenn man allerdings kein Subnet angibt, ist das Argument None
.
Ein möglicher Workaround ist:
$ sudo meshtastic --tunnel --subnet 10.115
Daraufhin konnte das Interface gestartet werden:
$sudo meshtastic --tunnel --subnet 10.115
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address 10.115.253.197
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address 10.115.180.153
$ ip address show mesh0
22: mesh0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 200 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 10.115.253.197/16 scope global mesh0
valid_lft forever preferred_lft forever
Ich habe zur Behebung des Fehlers daraufhin eine PR gestellt.
Das Subnet 10.115.0.0/16
ist im privaten Bereich und kann daher eigentlich ohne Probleme verwendet werden. Da das dn42 und die damit verbundenen Netzwerk jedoch auch Netze in diesem Bereich verwenden, habe ich nach Kollisionen gesucht und leider eine gefunden. Das Freifunk Cuxhaven verwendet ungünstigerweise auch diesen Netzbereich. Da diese jedoch nicht mehr im IC-VPN sind, habe ich eine PR erstellt, um das Netzwerk zu entfernen. Mein eigenes dn42-Netzwerk habe ich angewiesen, den Bereich 10.115.0.0/16
als ungültig zu betrachten und damit nicht zu routen.
Ein weiteres Hindernis beim IP-Tunneling mit Meshtastic ist das kleine MTU von 200 Bytes. Dies verhindert automatisch IPv6, da IPv6 eine MTU von mindestens 1280 Bytes erfordert. Es ist jedoch möglich, IPv6 über IPv4 zu tunneln (GRE, WireGuard, ...).
Für das IP-Tunneling wird immer der primäre Channel verwendet. Eine Änderung ist aktuell nicht geplant. Dies bedeutet jedoch, dass eine Verschlüsselung schwierig wird:
Ein Weiteres Problem beim IP-Tunneling über Meshtastic die die hohe Latenz und der Paketverlust:
$ time ping 10.115.253.197 -c 20 -W 600
PING 10.115.253.197 (10.115.253.197) 56(84) bytes of data.
64 bytes from 10.115.253.197: icmp_seq=1 ttl=64 time=12612 ms
64 bytes from 10.115.253.197: icmp_seq=2 ttl=64 time=15457 ms
64 bytes from 10.115.253.197: icmp_seq=4 ttl=64 time=14536 ms
64 bytes from 10.115.253.197: icmp_seq=5 ttl=64 time=14669 ms
64 bytes from 10.115.253.197: icmp_seq=6 ttl=64 time=14803 ms
64 bytes from 10.115.253.197: icmp_seq=8 ttl=64 time=17756 ms
64 bytes from 10.115.253.197: icmp_seq=9 ttl=64 time=19245 ms
64 bytes from 10.115.253.197: icmp_seq=10 ttl=64 time=19234 ms
64 bytes from 10.115.253.197: icmp_seq=11 ttl=64 time=19280 ms
64 bytes from 10.115.253.197: icmp_seq=12 ttl=64 time=19564 ms
64 bytes from 10.115.253.197: icmp_seq=14 ttl=64 time=21571 ms
64 bytes from 10.115.253.197: icmp_seq=16 ttl=64 time=21286 ms
64 bytes from 10.115.253.197: icmp_seq=17 ttl=64 time=21525 ms
64 bytes from 10.115.253.197: icmp_seq=20 ttl=64 time=29039 ms
--- 10.115.253.197 ping statistics ---
20 packets transmitted, 14 received, 30% packet loss, time 19209ms
rtt min/avg/max/mdev = 12611.611/18612.706/29038.582/4040.933 ms, pipe 16
real 0m50.196s
user 0m0.007s
sys 0m0.068s
Auch eine UDP-Übertragung war auch problemlos möglich:
$ ncat --verbose --wait 10m --udp 10.115.180.153 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Connected to 10.115.180.153:8886.
Hello World!
^C
$ ncat --listen --verbose --udp --source-port 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:8886
Ncat: Listening on 0.0.0.0:8886
Ncat: Connection from 10.115.253.197:47920.
Hello World!
^C
Eine einfache TCP-Verbindung war jedoch nicht möglich. Somit kann Meshtastic auch nicht für das dn42 eingesetzt werden. Einfache Chat-Anwendungen, welche auf UDP basieren und hohe Latenzen vertragen, sollten allerdings möglich sein.
$ ncat --verbose --wait 10m 10.115.180.153 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Connection timed out.