Freifunk in Rheinbach (5)
Zugriff per SSH

[vgwort line=“84″ server=“vg05″ openid=“3ea92ca9574d480488984bb6bfcc1bef“]

Verwaltung eines Router per SSH
Verwaltung eines Router per SSH

Vorbemerkung

Aufstellen eines Freifunkrouters ist recht einfach. Router kaufen, Firmware durch Freifunk-Firmware ersetzen. Neustarten und fertig. So ein Router verlangt ab und zu einem Update. Er kann seine Position und Kontaktadresse enthalten und weitermelden. Die könnte sich auch mal ändern. Vielleicht muss die genutzte Bandbreite geändert – reduziert – werden, weil der Internetanschluss des Betreibers durch die vielen Gäste blockiert wird. Oder es läuft gleichzeitig ein verschlüsseltes WLAN auf dem Router und das Password müsste mal geändert werden. So ganz einfach muss es also nicht sein.

Nicht jeder möchte oder kann sich selbst um diese Aufgaben kümmern. Aus diesem Grunde bin ich der Frage nach gegangen, wie kann ich eine größere Zahl Router, die über die Stadt verteilt sind, zentral von meinem Arbeitszimmer aus verwalten? Allein zwei Router, die ich betreue stehen im evangelischen Gemeindezentrum; weitere dürften folgen.

Die folgende Überlegungen gehen tief in technischen Details der Administration eines Freifunkrouter und dürften nur für wenige interessant sein. Aber wer sich dafür interessiert, findet am Ende auch eine Lösung, zu der es ein langer Weg war, mit vielen kleinen, zum Teil fast zehn Jahre alten Steinen, die nicht allein durch Google aus dem Weg zu räumen waren.

Eigene Firmware

Der typische Ablauf bei einem neuen Router ist folgender: Router starten, Rechner anschließen, Firmware ersetzen, Router neu starten, Router in den Setup Modus setzen, Rechner neue IP-Adresse geben, Router konfigurieren, Router neu starten. Diese Schritte kosten alle sehr viel Zeit. Wenn sich einigen Schritte einsparen kann, dann könnte der Aufwand pro Router deutlich reduziert werden. Am besten wäre es, wenn ich nur die ersten vier Schritte bräuchte und alles andere aus der Ferne machen könnte.

In den letzten Tagen habe ich daher versucht eine eigene Firmware für Rheinbach zu erstellen, die dies ermöglicht. Nicht nur um die Router zentral verwalten zu können, sondern auch um viele Router mit möglichst wenig Aufwand konfigurieren zu können. Den Hürden, die dabei zu überwinden waren, werde ich einen eigenen Artikel widmen. Eine Hürde war die Frage der Administration der Router per SSH, die ich in diesem Artikel behandeln will, weil diese Hürde überwunden ist. Mit der eigenen Firmware liege ich noch etwas im Clinch. Die Fehler sind beseitigt, aber ich weiß nicht warum. Symptome kuriert, Krankheit unbekannt.

Verwaltung per Konsole

Im Gegensatz zu gängigen Routern lässt sich ein Freifunkrouter nur in einem speziellen Setup Modus per Web-Oberfläche administrieren. Um den Router in diesen Modus zu versetzen, muss die Reset-Taste gedrückt werden. Der Administrator muss zum Router. Ein Weg, den ich mir selbst im eigenen Haus gerne erspare. Verfahren in aller Kürze: Zum Router gehen, Reset-Taste drücken, warten bis Router im Setup Mode gestartet ist, Rechner an einen gelben LAN-Port anschließen, IP-Adresse beziehen, die Seite http://192.168.1.1 aufrufen, Änderungen vornehmen, speichern und Router neu starten. Administration bei Turnschuh.

Dieses Verfahren ist etwas umständlich und zeitaufwändig, insbesondere wenn viele Router zu betreuen sind, die auch noch weit auseinander stehen. Auch kann man nicht nachschauen, was gerade auf einem Router läuft oder – oft wichtiger – nicht läuft, denn in diesem Setup Modus funktioniert er nicht als Freifunkrouter. Der (blaue) WAN-Port wird nicht eingeschaltet. Sprich: Ein Rechner muss an einem lokalen (gelben) Port des Routers angeschlossen werden. D.h, der Router muss zum Rechner oder der Rechner zum Router.

Im laufenden Betrieb ist eine Verwaltung (nur) über die Kommandozeile in einem Terminal möglich. Auch wenn grafische Oberflächen modern sind, hat die gute alte Kommandozeile immer noch deutliche Vorteile, weil Scripte auf den Router geladen werden können, die die gesamte Arbeit in einem Zug erledigen. Zum Beispiel die Einrichtung eines privaten WLAN wie in Freifunk in Rheinbach (2) beschrieben. Für ein Update werden nur noch die folgenden drei Befehle benötigt:

scp firmware.bin root@router:/tmp/
ssh root@router
sysupgrade /tmp/firmware.bin

Muss dies für dutzende Router gemacht werden, kommt keine grafische Oberfläche gegen eine Geschwindigkeit einer Lösung per Kommandozeile an.

Administration per SSH

Um einen Router mittels der Kommandozeile in einer Konsole zu verwalten, kann ein Password oder der öffentliche Teil eines SSH-Schlüsselpaares auf dem Router hinterlegt werden. Da ich hier mehr als einen Router administriere, möchte ich mir ein Image bauen, bei dem eine Administration im laufenden Betrieb schon gleich nach der Installation über SSH möglich ist. So möchte mir auch die Erstkonfiguration über den Setup Mode ersparen.

Aber dazu später, vorher möchte ich einen kleinen Abstecher machen: Die Router brauchen im lokalen Netz feste IP-Adressen. Ständig wechselnde Adressen sind für die Administration auf Dauer lästig.

Feste IP-Adressen für die Router

Ein Server unter OpenSuSE dient bei mir als zusätzliche Firewall, Proxy, Mail-, DHCP und DNS-Server. Er verteilt bei mir anstelle des Router die IP-Adressen. Einzelnen Geräten ordne ich anhand der MAC-Adresse eine feste IP zu. Dies geht natürlich auch mit den meisten Routern (SpeedPort, FritzBox) mehr oder weniger gut.

Der Freifunk-Router wird mit dem WAN-Port (Schnittstelle br-wan) an das lokale Netz angeschlossen, damit die Endgeräte einen Zugang zum Internet erhalten können. Über diese Schnittstelle kann der Router dann auch per SSH von einer Konsole aus verwaltet werden. Über DHCP wird dem Routern eine feste IP-Adressen und ein Namen zugeteilt, damit ich nicht ständig nach ihrer IP-Adresse suchen muss.

Beispiel:

# Switch TP-LINK TL WR841ND V9 (1)
(/etc/dhcpd.conf)
...
host rff0.example.com {
  hardware ethernet ea:95:f6:78:36:2a ;
  fixed-address 192.168.20.40 ;
}
...

Meine lokalen Namen sind kurz um Tipparbeit zu sparen und haben nichts mit dem Hostname auf dem Router gemein. Auf dem Router stellt sich diese Einstellung wie folgt dar:

root@su-rhb-001:~# ifconfig br-wan
br-wan    Link encap:Ethernet  HWaddr EA:95:F6:78:36:2A  
          inet addr:192.168.20.40  Bcast:192.168.20.255  Mask:255.255.255.0
          inet6 addr: fe80::e895:f6ff:fe78:362a/64 Scope:Link
...

Damit lässt sich der Router über den Namen rff0.example.com oder kurz rff0 ansprechen, was in den folgenden Beispielen Verwendung findet.

Authorized Keys

Auf dem Roter kann ein Password für den User root angegeben werden, um sich per SSH auf dem Router in einer Konsole anmelden zu können. Alternativ lassen sich mehrere öffentliche SSH-Schlüssel in der Datei /etc/dropbear/authorized_keys auf dem Router hinterlegen. Ich bevorzuge letzteres – oder beides.

Da mehrere Schlüssel auf dem Router hinterlegt werden können, könnten auch mehrere Administratoren die Router verwalten, ohne das root-Kennwort zu kennen. Um einen Administrator später zu auszuschließen muss nur sein öffentlicher Schlüssen aus der Datei /etc/dropbear/authorized_keys gelöscht werden.

Über den Eintrag authorized_keys in der Datei site.conf und das Paket gluon-authorized-keys können die öffentlichen SSH-Schlüssel bereits ins Image eingebunden werden. Dies ist bei der normalen Freifunkfirmware nicht der Fall, weil die Ersteller der Firmware die Schlüssel der „Administratoren“ nicht kennen. Ein allgemein bekannter Default Schlüssel wäre nicht sinnvoll, weil damit jeder auf den Router zugreifen könnte. Aber dazu später etwas mehr.

Über die Vor- und Nachteile der Einbindung ins Image lässt sich trefflich streiten; aber nicht hier. Eingebunden ins Image überleben die Schlüssel auch eine völlige Neuinstallation aus der Ferne. Hier nur kurz das Beispiel der Einbindung des öffentlichen Teils eines SSH-Schlüssels:

...
authorized_keys = {
  'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCWJjFLLnarSVvniQFvjA3je/YTL98adZk7r1dIgSt5nLheUlPvM7KzC1gvhQZQVDOsIThRf3wzJfPwlLbIOo8uNFI6jTUM8YBlAZRLxNwVjRPWWzyp2g6ayHgpOENqBH3/sSjSmtxnPAF7Fw04d8RLui//Kdj3PQIaB0hnbbNtowvT6oFzt6WXwumIv1dF2sRz9ocIq/FfHHJcq/YEhzXZ0Ri3K452YEm1FGkhwZRRA7nrXkF+AjtNnb+6B3ytA7+6/xTwmLJGQqTJWB3xw3RSXU59WJcTKBw3Y9ZDjV5PqBQFmfgI7ZiWO3de71lZjoe1YwRuyy7azsiHubFIo+DP router@freifunkrheinbach.de'
...

Anmerkung: Den automatisch erzeugten Kommentar am Ende der Zeile habe ich durch router@freifunkrheinbach.de überschrieben. Es ist nicht sinnvoll, diesen öffentlichen Schlüssel in seinen Router einzutragen, da nur ich den geheimen Teil habe. Außer ich soll den Router verwalten – btw: rechts ist ein Spenden-Button.

Die Erstellung der Firmware beschreibe ich in einem anderen Artikel. Und wir wollen die Frage der Firmware jetzt verlassen und uns den SSH-Schlüsselpaaren widmen, unabhängig davon, ob die Schlüssel in eine Firmware eingebunden werden oder nicht. Bevor ich einen öffentlichen Schlüssel eintragen kann, muss ich ihn erzeugen. Dies ist gar nicht so unproblematisch, wie es mir auf den ersten Blick erscheint. Ich verwalte alle meine Rechner über Schlüsselpaare.

SSH-Schlüsselpaare

Das Erzeugen der Schlüsselpaare ist etwas trickreich. Warum dies so ist, erkläre ich später. Grundsätzlich können die Schlüssel mit ssh-keygen unter Linux erzeugt werden, aber diese Schlüsselpaare führen später zu einem Fehler, wenn ich mich von einem Router zum nächsten mit SSH hangeln will. Auf dem Router läuft ein eingeschränkter SSH-Server/Client: dropbear. Allein ssh –help zeigt, dass hier vieles nicht möglich ist, was in OpenSSH geht. Aber ssh ist doch ssh – dachte ich anfangs.

dropbearkey

OpenWRT bietet zum Erzeugen der Schlüssel den Befehl dropbearkey an, der auch unter anderen Linux Derivaten zur Verfügung steht, aber normalerweise nicht mit installiert wird.

Anmerkung: Unter OpenSuSE kann das Paket dropbear mit sudo zypper in dropbear installiert werden; Unter Ubuntu entsprechend mit sudo apt-get install dropbear

Schlüssel erzeugen

dropbear speichert die Schlüssel anders als OpenSSH. Deshalb müssen die Schlüssel noch konvertiert werden. Aber ein Schritt nach dem anderen.

Mit folgenden Befehlen wird der Schlüssel erzeugt:

dropbearkey -t rsa -f db-freifunk_rsa
dropbearkey -y -f db-freifunk_rsa | grep '^ssh-rsa' >db-freifunk_rsa.pub

Anders als ssh-keygen erzeugt drobbearkey nur die geheime Datei. Deshalb muss der öffentliche Teil des Schlüssels mit dem zweiten Befehl aus dem geheimen Teil extrahiert werden. Den Inhalt der Datei db-freifunk_rsa.pub fügen wir unter authorized_keys in die site.conf ein und erstellen damit ein neues Image. Es lassen sich natürlich beliebig viele Schlüsselpaare erzeugen und einfügen.

Der öffentliche Teil des Schlüssel wird in einem Router in der Expertenkonfiguration eingetragen, wenn wir ihn nicht in die Firmware einbinden. Wurde ein Password für den User root gesetzt, kann der öffentliche Teil mit folgendem Befehl auf den Router kopiert werden. Vorhandene Schlüssel werden dabei überschrieben.

scp db-freifunk_rsa.pub root@rff0:/etc/dropbear/authorized_keys

Mit dem Befehl ssh -i db-freifunk_rsa root@rff0 sollte ich mich nun von meinem Linux Rechner auf dem Router anmelden können. Unter Windows bietet sich PuTTY als SSH-Client an. Das Problem ist nur, dass ssh nach einer Passphrase für den geheimen Teil des Schlüssels fragt, obwohl bei der Erzeugung mit dropbearkey nicht nach einer Passphrase gefragte wurde. Ein Blick in die Parameter zeigt: dropbear kann Schlüssel nicht mit einer Passphrase schützen. Die Anmeldung gelingt auch mit einer leeren Passphrase (Enter drücken) nicht.

Schlüssel konvertieren

Nach Probieren und Anfragen bei Dr. Google kam ich zu der Erkenntnis: OpenSSH versteht das dropbear-Format ohne Passphrase nicht. Um diesen Fehler zu vermeiden muss der Schlüssel mit dropbearconvert in das OpenSSH-Format konvertiert werden. Das Programm bezieht man am besten aus den Quellen bei Dropbear SSH. Unter Debian sind die Pakete veraltet und enthalten nicht das Programm dropbearconvert.

dropbearconvert dropbear openssh db-freifunk_rsa os-freifunk_rsa

Auch hier erhalten wir nur den geheimen Teil des Schlüssels und können den öffentlichen Teil daraus mit ssh-keygen extrahieren. Da ssh-keygen keinen „Overhead“ erzeugt, können wir uns den grep-Befehl sparen. (Natürlich kann ich den Schlüssel mit ssh-keygen erzeugen und anschließend mit dropbearconvert in das dropbear-Format konvertieren, aber ich bin aufgrund der Hinweise von Dr. Google den umgekehrten Weg gegangen, weil ich vorher einen anderen Fehler hatte, der weiter unten beschrieben ist.)

ssh-keygen -y -f os-freifunk_rsa > os-freifunk_rsa.pub

Vergleichen wir beide Dateien, dann sehen wir, dass die Zeichenfolge hinter ssh-rsa und vor dem Kommentar, der öffentliche Teil des Schlüssels, in beiden Dateien identisch ist. Der letzte Schritt wäre daher nicht zwingend erforderlich. Dies erklärt natürlich, warum ich mich vom Linux-Rechner mit einem per OpenSSH erzeugten Schlüssel am Router anmelden kann. Der abgespeckte SSH-Client auf dem Router kann jedoch nicht mit dem geheimen OpenSSH-Schlüsseln umgehen. Aber dazu kommen wir gleich.

Nun funktioniert die Anmeldung am Router ohne Passphrase mit ssh -i os-freifunk_rsa root@rff0. Die OpenSSH Datei lässt sich nun nachträglich mit einer Passphrase schützen, was nur eingeschränkt hilfreich ist, weil wir das ungeschützte dropbear-Format später noch brauchen werden.

SSH von Router zu Router

Wie kann ich aber einen Router über SSH administrieren, der nicht mit seinem WAN-Port an das lokale Netz (LAN) angeschlossen ist, sondern nur über anderer Router im MESH-VPN erreichbar ist. Und: Kann ich einen Router administrieren, der gar nicht in meinem lokalen Netz steht?

Hier hilft die Schnittstelle br-client weiter, über die alle Router untereinander über ihre IPv6 Adresse erreichbar sind – auch über die Grenze des lokalen Netzes hinaus.

root@su-rhb-001:~# ifconfig br-client
br-client Link encap:Ethernet  HWaddr E8:94:F6:78:36:2A  
          inet6 addr: fda0:747e:ab29:2241:ea94:f6ff:fe78:362a/64 Scope:Global
          inet6 addr: fe80::ea94:f6ff:fe78:362a/64 Scope:Link
...

Habe ich mich auf irgendeinem Router im Freifunknetz angemeldet, kann ich mich auf diesem Router mit folgendem Befehl anmelden:

root@su-rhb-002:~# ssh -i /tmp/db-freifunk_rsa root@fda0:747e:ab29:2241:ea94:f6ff:fe78:362a

Host 'fda0:747e:ab29:2241:ea94:f6ff:fe78:362a' is not in the trusted hosts file.
(ssh-rsa fingerprint md5 4e:f3:db:5c:65:9d:b7:80:61:38:69:c4:76:19:bb:68)
Do you want to continue connecting? (y/n) y

Da jeder von seinem Router an jeden anderen Router kommt, ist es wichtig seinen Router durch ein sehr starkes Kennwort zu schützen, oder keines zu vergeben. Ohne ein Kennwort für den User root ist die Anmeldung per Kennwort deaktiviert. Eine Anmeldung ist aber auch dann mit einem Schlüsselpaar möglich, wenn kein Password gesetzt wurde. Daher ist auch der geheime Teil des Schlüssels entsprechend gut zu schützen, insbesondere, wenn er im unverschlüsselten dropbear-Format vorliegt.

Fehlermeldung „ssh: Exited: String too long“

Wichtig ist die Datei db-freifunk_rsa für die Authentisierung von Router zu Router zu nehmen, denn mit der Datei os-freifunk_rsa erhält man die Fehlermeldung ssh: Exited: String too long.

root@su-rhb-zingsheim-31-n2:~# ssh -i /tmp/os-freifunk_rsa root@fda0:747e:ab29:2241:ea94:f6ff:fe78:362a
ssh: Exited: String too long

Diese Fehlermeldung ist schon seit etwa 10 Jahren bekannt. Sie war die erste Fehlermeldung, auf die ich stieß, als ich mich mit einem OpenSSH-Key von Router zu Router anmelden wollte. Und genau wie ich haben schon sehr viele nach einer Lösung gesucht. Die Fehlermeldung „String too long“ führt einen dabei doch sehr in die Irre. Alle Lösungsvorschläge wiesen nur auf die Nutzung von dropbearkey zur Generierung der Schlüssel hin, den Rest musste ich mir dann erarbeiten. Das Leid der Foren: Jeder fragt, doch keiner schreibt, wie am Ende die Lösung war.

Fazit

Die Aufgabe der zentralen Verwaltung aller Router einer größeren Gruppe durch einen oder mehrere Administratoren ist über SSH-Schlüsselpaare möglich. Werden die öffentlichen Schlüssel in einer Firmware hinterlegt, kann die Erstkonfiguration auch über die Konsole erfolgen.

Gute Nacht

PS: Nach fünf Stunden Arbeit an diesem Artikel habe ich genug Rechtschreibfehler und brauche keine mehr; wer weitere findet, darf sie behalten.