Inhaltsverzeichnis

Wie konfiguriere ich einen Repeater

Repeater werden über die Kommandozeile konfiguriert. Das Template zeigt die Befehle, die Syntax der Befehle und was die Werte bedeuten wird darunter erklärt und die Rationale liefert die Begründung warum.

Typischerweise nutzen wir dafür die App auf dem Smartphone um via Fernwartung darauf zu zu greifen. Alternativ kann meshcore-cli genutzt werden um über USB/BT in der Kommandozeile zu arbeiten.

Terminologie

LoRa ist die Netzwerktechnologie die Meshcore nutzt (in der IT wäre LoRa-Wan vergleichbar mit 802.11 (LAN bzw WLAN)).

Firmware ist die Software die auf Repeatern/Companions läuft.

In meshcore gibt es 2 Wege der Zustellung: Flood=Ausbreitung im ganzen Netzwerk und Direct=Sender gibt den zu nehmenden Pfad vor.

In meshcore gibt es verschiende Pakete, besonders erwähnenswert sind dabei Adverts, Text und ANON.

Adverts bekunden die Präsenz eines Devices damit andere dieses Gerät erkennen und direkt kommunizieren können. Adverts werden typischerwiese on-demand oder in regelmäßigen Abständen ausgesendet. Adverts werden entweder als Flood oder 0-Hop ausgesendet. Flood-Adverts breiten sich im gesamten Netzwerk aus, 0-Hops werden nur von den direkten Nachbarn gehört aber nicht weitergeleitet.

Airtime bezeichnet ist die Zeit die ein Paket in der Luft bim Senden braucht. Diese Zeit ist deswegen so kritisch, weil sie nicht nur den Durchsatz regelt, sondern weil das ISM-Band auf dem Meshcore funkt stark regelmentiert ist. So darf auf LoRa-Wan in Österreich nur 10% der Zeit funken (Übersicht der Regelungen nach Land, ERC/REC 70-03). Diese Sendezeit nennt man im Englischen dutycycle. In alten Firmwareversionen wurde dies über „af“ aka „airtime factor“ gesteuert. Da dieser dutycycle ein hartes Limit ist, ist Sendezeit ein teures gut mit dem es sparsam zu haushalten gilt.

Config-Template

Anmerkung: # ist als Kommentar zu verstehen und keine Konfiguration

clock sync
 
set multi.acks 1
set path.hash.mode 2
 
set dutycycle 10
# Anmerkung vor Firmware v1.15.0 war das die Einstellung "af"
# set af 9 entspricht laut Dokumentation ca. 10% dutycycle.
 
set guest.password guest
# Frage in deiner Community nach üblichen guest passwords
 
password MY-SUPER-DUPER-SAFE-PASSWORD
# Anmerkung MY-SUPER-DUPER-SAFE-PASSWORD sollte durch ein eigenes Passwort ersetzt werden
# betrachte das Passwort als kompromittiert, es sollte nirgendwo sonst verwendet werden
# das Passwort sollte keine Zeichenfolgen enthalten die auch in der Owner-Info enthalten ist.
 
set name AT-KENNZEICHEN-NAME
# Die allgemeine Konvention ist [LAND]-[Kennzeichen/Bezirk]-[Name]
 
# Optional: set prv.key
# nutze set prv.key falls du ein bestimmtes ID-Präfix haben möchtest (https://gessaman.com/mc-keygen/)
 
get radio
# prüfe hier ob bereits beim Flashen die Radio-Optionen gesetzt wurden
# Du findest die aktuellen Empfehlungen unter: https://meshcore-austria.at/doku.php?id=start
# Beispiel-Ausgabe: 869.6179809,62.5,8,8
# sollte dies nicht so aussehen:
# set radio 869.618,62.5,8,8
set loop.detect moderate
 
# Konfiguriere welche Regionen du weiterleiten möchtest
# diese Konfiguration setzt v1.15.0 und darüber voraus.
region put europe
region put dach europe
region put at dach
 
region put at-ost at
region put at-w at-ost
region put at-noe at-ost
region put at-ooe at-ost
region put at-bgld at-ost
 
region put at-west at
region put at-sbg at-west
region put at-t at-west
region put at-vbg at-west
 
region put at-sued at
region put at-stmk at-sued
region put at-ktn at-sued
 
region save
# häufig wird auch at-<kennzeichen> wie at-p verwendet als region!
 
# delays
# Empfang --rxdelay--> Verarbeitung (dedup/regions) --rnd(txdelay)--> Senden
 
set txdelay 2 # Sekunden für random delay für Flood
# Empfehlung: 
#   0.5 für kleine Rooftop Repeater
#   1   für überregionale Repeater
#   2   für "backbone" wie auf Bergspitzen
 
set direct.txdelay 0.2 # Sekunden für random delay für Non-Flood
 
set rxdelay 8 # Faktor um Pakete basierend auf deren Empfangsqualität um zu reihen
 
# Adverts
set flood.advert.interval 72 # Stunden
set advert.interval 360      # Minuten
 
 
 
# Max-Hops 
# bevor Max-Hops gesetzt werden sollte das Netzwerk beobachtet werden was hier sinnvoll ist
# Unerfahrene User sollten diese Wert vorerst nicht konfigurieren
# set flood.max.advert 9
# set flood.max.unscoped 21
# set flood.max 21
 
set lat XX.XXXX # setzt latitude, e.g. 48.23616
set lon YY.YYYY # setzt logitude, e.g. 16.43826
 
set owner.info "Was ist das für ein Node|Name/alias des operators|Kontaktmöglichkeit" # das | Symbol wird zu Zeilenumbruch
# Beispiel: 📌 Dach, 📻 RAK 4631, 🌞 Solar | 🌐 Regions active | RUFZEICHEN t.me/USERNAME
# Beispiel 2: 📻 Heltec v3 | Hausstrom | 💻 v1.15.0 | 🌐 Regions: at, at-ost, at-noe, europe | ✉️ xxx@yyyy.zzz
# Tipp: Proton-Pass kann durch "Alias" anonyme eMail-Adressen erzeugen
# Typische Emojis: 🌞=Solar, 🌐=Regions, 📻=Radio aka Gerät, 🔋=Angabe über Batterie-Leistung, ✉️=eMail Adresse, 📌=Location, 📡=Antenne
# Hinweis: Clients können Regions vom Repeater abfragen, die Region-Angabe ist daher eher für Debug-Zwecke (daher reicht meistens die Angabe ob aktiv oder nicht)

Erklärung der CLI-Befehle

„clock sync“ synchronisiert die Zeit zwischen dem entfernten und lokalen Gerät.

„multi.acks“ kann auf 0=disabled oder 1=enabled gesetzt werden. Von der Implementierung kann davon ausgegangen werden, dass der Wert der Anzahl an zusätzlichen ACKs entspricht. Diese ACKs werden zeitlich versetzt erzeugt.. Ein ACK bestätigt den Erhalt einer Direktnachricht.

„path.hash.mode“ hat gegenwärtig die gültigen Werte 0=1byte, 1=2byte und 2=3byte. Byte bezieht sich auf die Anzahl an Bytes vom Public-Key die als Path mitgeschrieben werden.

„guest.password“ ist ein Passwort was „Gast-Zugriff“ erlaubt. Typische Werte sind „guest“ oder „hello“ oder leer-lassen. Da die Dokumentation nicht näher definiert, sollte es nicht leer gelassen werden. Die offizielle Dokumentation führt dies aktuell nicht näher aus. Was dieser Gast-Zugang genau impliziert scheint implementationsabhängig zu sein. Für Repeater scheint das das Abfragen der Sensoren mit minimalen Rechten zu erlauben (was das impliziert ist scheinbar Hardware abhängig, bspw. GPS wäre ausgenommen). Owner-Info und Nachbarn sollten auch als Gast abfragbar sein. Es wurden Probleme bei dem Setting beobachtet wenn das Gerät welches versucht sich zu verbinden einen hash.mode mit mehr als 1byte nutzt.

„set name“ setzt den Namen des Repeaters. Der Repeater kann jederzeit umbenannt werden, identifiziert wird er über den Public-Key. Die Community-Konvention ist Repeater zu benennen durch [Land]-[Bezirk]-[Name]. Daniel hat mal ein Tool gebastelt um die Namen zu generieren.

„set prv.key“ setzt den Private-Key. Der Private-Key impliziert auch den Public-Key und damit auch die ID des Repeaters. Diese wird typischeweise automatisch generiert und muss nicht gesetzt werden. Viele freuen sich aber wenn dieser Public-Key bestimmte Dinge wie den Vereinsnamen ähnelt. Dafür gibt es Tools die das berechnen. Der Private-Key ist wie der Name suggeriert ein Geheimnis und die Basis aller Verschlüsselung auf dem Gerät. Gewisse Prefixe sind beliebter als andere, wenn du die ID selbst berechnest, wird empfohlen auf Kollissionen zu Prüfen.

„set radio“ setzt die Frequenz, Bandbreite, Spread-Factor und CodingRate. Dabei ist die CR nur die Fehlerkorrektur - das bedeuted, dass zwei Nodes trotz verschiedener CR miteinander auf dem Kanal kommunizieren können. SF erlaubt Werte von 7 bis inkl. 12 - siehe https://www.thethingsnetwork.org/docs/lorawan/spreading-factors/. CR erlaubt Werte von 5 bis inkl. 8 - siehe https://www.thethingsnetwork.org/docs/lorawan/fec-and-code-rate/. Als initialie Konfiguration sollte eine CR von 8 genommen werden (50% Redundanz). Beobachte über einen längeren Zeitraum wie gut der Repeater von seinen Nachbarn gehört wird (nutze dazu Logger wie https://logger-at.meshcore.observer/ ), wird der Repeater von den für dich wichtigsten Nachbarn sehr gut (Score > 0.85) gehört probiere den CR schrittweise zu reduzieren, beachte dabei dass der Score nur selten (Zero-Hop-Advs) aktualisiert wird und nur wenn dies von einem Observer beobachtet wurde.

„set loop.detect“ aktiviert Loop-Prevention. Mögliche Werte sind off, minimal, moderat, strict. Bei Aktivierung prüft der Repeater vor dem Senden ob seine eigene ID bereits im Pfad (minimal=4mal bei 1byte/2mal bei 2byte/1mal bei 3byte; moderate=2mal bei 1byte/1mal bei 2 oder 3 byte; strict=öfters als 1mal) vorkommt. Kommt die ID häufiger wie zulässig vor wird das Paket nicht weiter geleitet. Empfohlen wird minimal oder moderate.

„region put“ + „region save“ Speichen die Region-Config. „region put“ impliziert „allowf“ seit https://blog.meshcore.io/2026/04/17/default-scope#:~:text=So%2C%20you%20won%E2%80%99t%20need%20to%20also%20follow%20with. Bekannte Regionen siehe: Siehe Österreich: https://meshcore-austria.at/doku.php?id=start Siehe Österreich: https://meshcore.at/#einstieg Siehe Deutschland: https://meshcore-de.fyi/meshcore:allgemeines:regions:reale-regions-in-repeatern Siehe Schweiz: https://www.meshcore.ch/regions/ Siehe Niederlande: https://meshwiki.nl/wiki/Lijst_van_regio's

„set txdelay“ Delay, wird in Sekunden angegeben. Vor dem Senden wird ein zufälliges Delay zwischen 0 und dem eingestellten Wert gewürfelt. Da in Meshcore grundsätzlich der „schnelleste“ Pfad gewinnt, ist das txdelay geeignet um „teure“ Knoten unattraktiv zu machen. Da jeder Node für sich die airtime rechnet, sollten daher beim Lernen eines Pfades kritischere Nodes entlastet werden. Das txdelay soll daher dazu führen, dass wenn ein Client einen Pfad (für Direct-Nachrichten) lernt nach Möglichkeit Alternativen gelernt werden. Dies soll dazu dienen die Airtime-Verbrauch von Knoten an neuralgischen Punkten gering zu halten. Siehe https://w6hs.net/meshcore-repeater-deployment-timing-considerations-for-wide-area-networks/

„set rxdelay“ ein Faktor der dazu benutzt wird ein Delay zu berechnen welches die eingehenden Pakete vor deren Verarbeitung basierend auf deren Empfangsqualität verzögert. Dies führt dazu, dass nicht mehr der „schnellste“ Pfad sondern der Pfad mit der besten Verbindungsqualität „gewinnt“. Typischerweise empfängt ein Repeater ein Flood-Paket von mehr als einem Nachbarn - dabei leitet der Repeater das Paket welches als erstes eintraf weiter und markiert das Paket als gesehen und leitet das Paket nicht nocheinmal weiter. Typischerweise ist das Paket welches als erstes eintrifft das Paket mit der schlechtesten Empfangsqualität (weil es bsp. von einem weiter entfernten Hop gerade noch so empfangen werden konnte), das führt zu „instabilen“ Pfaden. Dies kann beobachtet werden, wenn bei einer Direktnachricht ein Pfad gelernt wurde, dieser aber danach nie wieder zu funktionieren scheint. Das rxdelay führt daher zu besseren Pfaden.

Aktuell Implementierungsabhängig - diese Angabe kann daher möglicherweise outdated sein! Aktuell wird dieser von Repeatern implementiert als ((pow(_prefs.rx_delay_base, 0.85f - score) - 1.0) * air_time) https://github.com/meshcore-dev/MeshCore/blob/e8d3c53ba1ea863937081cd0caad759b832f3028/examples/simple_repeater/MyMesh.cpp#L540 wobei Ergebnisse kleiner 50 sofortiges Verarbeiten implizieren https://github.com/meshcore-dev/MeshCore/blob/e8d3c53ba1ea863937081cd0caad759b832f3028/src/Dispatcher.cpp#L243. Der Wert der über die CLI konfiguriert wird ist „_prefs.rx_delay_base“, score ist die Qualität der Verbindung. Siehe https://meshcore-austria.at/doku.php?id=mc_rxcalc

Rationale

„multi.acks“ häufig kann beobachtet werden, dass Nachrichten tatsächlich zugestellt wurden, aber der ACK am Weg verloren ging - es wirkt daher für Clients so als ob die Nachricht nie zugestellt wurde. Nicht-Zugestellte Nachrichten werden typischerweise vom Client erneut versucht. Bei zu vielen dieser Zustellungsversuche wechselt der Client von Direktnachrichten zu Flood. Die „Kosten“ von Mehrfachen-ACKs sind in dem Fall deutlich geringer als die „Kosten“ eines Floods. Daher sollte um die Channel-Nutzung gering zu halten Direct Nachrichten so gut es geht unterstützt werden und Floods vermieden werden. Daher wird Multi-ACKs empfohlen.

„path.hash.mode“ bezieht sich auf Pakete die von dem Gerät ausgehen. bei einem Repeater sind das nur Adverts. Sofern die Firmware moderner als 1.15.0 ist, sollte der Repeater mit Multi-Byte Nachrichten umgehen können und trägt sich mit der ID in der Länge in den Pfad ein die der Sender spezifiziert hat. Um Repeater in Loggern usw. möglichst eindeutig zu haben, sollte auf Repeater daher mit so vielen Byte wie möglich in den Adverts gesendet werden.

„set radio“ ist die wesentlichste Einstellung wie viel Datenrate zur Verfügung steht. Zu Beachten ist, dass unterschiedliche SF sich gegenseitig nicht stören oder sehen. Das bedeuted, dass sofern der Repeater gut von seinen Nachbarn gehört wird ein niedriger CR bedeuted, dass die gleichen Daten weniger Airtime benötigen. Gerade in Bereichen mit hoher Dichte sollten auch bei niedriger CR der Repeater von seinen Nachbarn hinreichend gut gehört werden. Bzgl. der Definition, dass gut besser als 0.85 ist siehe Ausführung zu rxdelay.

„set loop.detect“ ist eine Ergänzung zur Deduplizierung. Die Deduplizierung prüft ACKs getrennt von Messages. Bei Messages wird für die Deduplizierung ein Hash über den Content und ein Headerfeld gebildert. Aktuell werden dafür die letzten 128 dieser Hashes gespeichert (MAX_PACKET_HASHES=128, hasSeen, calculatePacketHash, MAX_HASH_SIZE=8). Die Deduplizierung ist daher sehr leistungsfähig und mit 8 Byte deutlich kollissionsresistenter als die Loop-Detection. Die Loop-Detection kommt daher zum Tragen, wenn der Repeater 128 einzigartige Pakete gesehen hat zwischen dem Senden von dem Paket und dem erneuten Empfang oder sich Payload-Type oder Payload von dem Paket selbst ändert. Realistisch betrachtet reduziert das Setting daher als weitere Verteidigungslinie von Duplikaten falls die Deduplizierung nicht funktioniert und es werden Pfade mit zu vielen Kollissionen im Pfad unterdrückt wodurch das Debuggen erleichtert wird. Das Setting „strict“ scheint bei der Menga an Kollssionen bei 1b Pfaden nicht zielführend.

„rxdelay“ das rxdelay wird über einen Faktor abhängig von der Empfangsqualtität berechnet welcher mit der Airtime multipliziert wird. Geht man daher von einem Tiering durch txdelay der anderen Devices aus, so sollten wir im worst Case ein Duplikat innerhalb von 500ms sehen. Der Faktor wurde daher so gewählt, dass Pakete die gerade noch so empfangen werden konnten (score=0,1) ein Advert (150ms airtime) mit einem delay von knapp über 500ms delayed werden. Kleinere Pakete sollten auch kein Problem sein, da txdelay gleichmäßig verteilt ist - daher sollte in der Hälfte aller Fälle ein Rooftop-Repeater der ein txdelay von 500ms konfiguriert hat das Paket bereits nach 250ms gesendet haben.

„password“ für die Administration wird im Klartext gespeichert und sollte aufgrund der exponierten Natur mancher Repeater (bspw. könnte das Passwort ausgelesen werden wenn der Repeater gestohlen wird oder andere Software geflashed wird) sowie Fehler in der Implementierung der Kryptographie als kompromittiert betrachtet werden. Zudem sollte das Passwort jedenfalls länger als 7 Byte und nicht länger als 11 Byte sein. Da Logger bereits sämtlichen Traffic aufzeichnen und das SharedSecret direkt verwendet wird (also keine PerfectForwardSecrecy implementiert ist) müssen die verwendeten Passwörter als kompromittiert betrachtet werden (da die Verbindung von Remote-Logins entschlüsselt werden könnte). Relevante Fehler in der Krypto-Implementierung: Aktuell kann das Passwort 15Byte lang sein. Login-Requests (Fernwartung) sind ANON-Pakete, deren verschlüsselter Payload 4byte Timestamp + das Passwort enthält. Aktuell nutzt Meshcore AES128 im ECB Modus mit dem SharedSecret als Key. Das Shared Secret wird über den ED22519 Public-Key aus dem Contact (über Adverts gelernt) gebildet. AES128 nutzt 16 Byte große Blöcke. Durch das Einfügen und validieren des Timestamps werden Probleme des ECB (siehe Visualiisierung mit dem Pinguin) im ersten Block hinreichend mitigiert (und schafft neue rund um den 19.1.2038 - siehe Jahr 2038 Problem). Folgende Blöcke könnten angegriffen werden, insbesondere da der MAC mit 2 Byte leicht über Kollissionen umgangen werden kann. Damit nicht am Transport beispielsweise zusätzliche Blöcke angehängt und damit das PW geändert wird sollte Timestamp+Passwort+NULL-byte was das Passwort beendet innerhalb des ersten Blocks ausgehen - darum nicht länger als 11 Byte sein. Wird von der Airtime eines Pakets von 100ms ausgegangen und davon ausgegangen, dass böswillige Angreifer nicht den Dutycycle respektieren so reicht ein 7-Stelliges Passwort aus Kleinbuchstaben, dass ein Brute-Force-Angriff innerhalb eines Jahres unmöglich wird. Da die Owner-Info ein sehr langer String ist, kann dieser leicht beim Setzen vie Fernwartung beobachtet werden und sticht heraus. Zudem kann die Owner-Info im Klartext abgerufen werden. Daher bieten sich aus Angreifer-Sicht die Blöcke der Owner-Info für Angriffe an, daher sollte die Angriffsoberfläche reduziert werden indem keine Zeichenfolgen in der Owner-Info Teil des Passworts sind (jedenfalls nicht das gleiche Byte am Ende und keine Teile die ca. länger als 3 Zeichen sind). Tool um Längen in Byte zu messen: https://mothereff.in/byte-counter