OpenWRT & TL-MR3420: USB-Stick Dateisystem verschlüsseln

Inzwischen bin ich ein heimlicher Fan von den günstigen TP-Link WLAN Routern, besonders dem TL-MR3420: Mit OpenWRT ausgestattet laufen die Geräte super stabil und haben für die verfügbaren Bandbreiten (seufz) ausreichend Leistung um ein VPN-Netz quer durch die Republik aufzuspannen.
OpenWRT Verschlüsselung Beitragsbild
Um ausreichend Platz für die nötigen Programmpakete zu schaffen muss das Dateisystem mit externem Speicher am USB-Anschluss erweitert werden. Leider bringt das ein nicht unerhebliches Risiko mit sich: Die geheimen VPN-Zugangsdaten liegen ungeschützt auf dem Stick — der unbemerkt abgezogen und ausgelesen werden könnte!
Natürlich lassen sich die Daten auch aus dem Router klauen. Dafür müsste man allerdings direkten Zugriff auf die Hardware haben, also zumindest den Failsafe-Modus aktivieren oder sogar den Flash direkt auslesen.

Abhilfe schafft die Verschlüsselung des Sticks mit einer im Router hinterlegten Schlüsseldatei. Ohne den Router ist der Stick damit unlesbar und wertlos, durch die Schlüsseldatei muss beim Einschalten trotzdem kein Passwort eingegeben werden.
Die folgende Anleitung bezieht sich auf den TP-Link TL-MR3420 und die aktuelle OpenWRT Version 15 „Chaos Calmer“, mit kleinen Änderungen bei der Paketauswahl sollte es auf fast allen Geräten ähnlich funktionieren.
Weitere Informationen zum Aufspielen der Images finden sich im OpenWRT Wiki zum TL-MR3420.

Update 10/2016: Erfolgreich getestet mit Chaos Calmer 15.05.1!

Funktionsweise


In dieser Anleitung kommt die Extroot/Pivot-Root Methode zum Einsatz. Dabei wird das gesamte Root-Dateiystem (/) auf den USB Stick kopiert und im PreInit beim Hochfahren statt dem Dateisystem im Gerätespeicher eingehangen. Übrigens ist das auch der Grund wieso nicht der gesamte Stick verschlüsselt werden kann: Das Dateisystem wird umgeschaltet noch bevor alle Kernelmodule geladen sind und die Init-Scripte in /etc/init.d/ ausgeführt werden. Hier einzugreifen ist riskant, aber bestimmt nicht unmöglich.

Was liegt wo?

  • Auf dem Router
    • OpenWRT Grundsystem
    • Upgrades (per sysupgrade.bin) werden hier gespeichert
    • Schlüsseldatei für die LUKS-Partition
  • Auf dem USB-Stick
    • Kopie des Grundsystem
    • Erweiterungen & Konfiguration
    • Verschlüsselte Partition mit VPN Zugangsdaten

Eigene Firmware bauen

Von nur 4MB eingebautem Flash-Speicher bleibt bei den regulären OpenWRT Images nur wenig Platz für die notwendigen Erweiterungen. Da ich den Router an einer bestehenden Internetverbindung betreibe habe ich die Module für Einwahlverbindungen (PPP, PPPoE) entfernt und stattdessen die USB-Treiber eingebaut. Die restlichen Module (besonders das Webinterface) bleiben dabei unverändert erhalten.

Ohne die lange „Package“ Liste erzeugt der ImageBuilder eine minimale Firmware ohne Webinterface, DHCP oder Firewall!

ImageBuilder 🔨

OpenWRT bietet für jede Architektur (hier: AR71xx) nicht nur fertige Binärdateien an sondern auch einen ImageBuilder, der angepasste Firmware Images erzeugen kann. Neben den benötigten Paketen können in diesem Schritt auch angepasste Einstellungen eingebunden werden.

Diese Konfiguration erzeugt das angepasste Image:

Hinzuzufügende Dateien:

Das erzeugte Image liegt im Verzeichnis ./bin/ar71xx und kann wie eine vorcompilierte Version aufgespielt werden:

  • …factory.bin: Zum „Umflashen“ der ursprünglichen Firmware auf OpenWRT
  • …sysupgrade.bin: Zum Aktualisieren einer vorhandenen Installation (dabei unbedingt die Konfiguration zurücksetzen!)

OpenWRT Luci nach dem ersten Einschalten
Direkt nach dem Aufspielen sollte über Telnet (192.168.1.1:23) ein Root-Passwort vergeben werden um den SSH Zugang zu aktivieren. Selbstverständlich muss auch das Basissystem abgesichert werden, da es die Schlüssel zum Auslesen des USB-Sticks enthält. Mehr zur ersten Einrichtung und Absicherung steht im OpenWRT Wiki!

236kB freier Speicher trotz USB Treiber:


USB-Stick vorbereiten

USB Stick partitionieren (GParted)

Für den nächsten Schritt habe ich einen kleinen USB-Stick bestellt (Intenso Micro Line, 4GB) und formatiert:

  • sdX1: 2048MB Pivot Root (mit 4MB Offset)
  • sdX2: 512MB VPN Zugangsdaten
  • sdX3: 96MB SWAP

Damit ist die erste Partition bereit für extroot!


Grundsystem kopieren & extroot einrichten

Weiter geht es mit dem vorbereitetem Stick am Router. Wenn alles funktioniert wird die Partition vom „block“ Tool erkannt und mit ihrer UUID aufgelistet (wichtig für die fstab).

Die Reihenfolge der Schritte ist durchaus wichtig: Nachdem das minimal konfigurierte Grundsystem kopiert wurde werden jetzt die geheimen Schlüssel erzeugt. Die sollen natürlich nur auf dem Router liegen und nicht kopiert werden!
Als kleine Hilfe habe ich an dieser Stelle die Datei /etc/banner in der Dropbear Konfiguration aktiviert und einen Hinweis eingefügt. So wird man beim SSH-Login sofort benachrichtigt wenn das System nicht vom USB-Stick hochgefahren wurde.

Verschlüsselung vorbereiten 🔓

Für die mit LUKS verschlüsselte Partition wird noch eine Schlüsseldatei benötigt:

Extroot aktivieren

Damit der Stick beim Hochfahren automatisch eingebunden wird muss die fstab erweitert werden. Die Zuordnung erfolgt über die UUID der Partition oder das Label „pivot“. Wenn man hier nur die UUID zulässt wird jeder anders formatierte Stick abgelehnt.

Nach einem Neustart fährt der Router ab jetzt automatisch vom USB-Stick hoch!

Jetzt steht massig Speicherplatz zur Verfügung:


Router einrichten

Bevor es weiter geht muss eine Internetverbindung zum Nachladen der nächsten Pakete eingerichtet werden, dabei sollte auch gleich die passende Zeitzone, NTP-Server, Hostname usw. eingerichtet werden.

Die Schlüsseldatei liegt im Flash-Speicher des Routers, der seit der Einrichtung von extroot nicht mehr eingehangen wird. Um trotzdem Zugriff zu bekommen wird das ursprüngliche Root-Dateisystem unter /overlay-boot eingehangen.

Das automatische Einhängen übernimmt (wieder mal) ein Eintrag in der fstab. Beim TL-MR3420 liegt das Dateisystem im Flash-Block #3 (/dev/mtdblock3), für andere Router findet man die Belegung meistens im OpenWRT Wiki. Bis zum nächsten Neustart kann die Partition mit „mount -o ro -t jffs2 /dev/mtdblock3 /overlay-boot“ eingehangen werden, jeweils ohne Schreibzugriff.

Verschlüsselte Partition anlegen

Nach den Vorbereitungen kann jetzt endlich die verschlüsselte Partition erstellt werden!

Eine Besonderheit ist die dritte Partition (SWAP): Sie wird beim Hochfahren mit einem “Wegwerfschlüssel” (aus /dev/random) verschlüsselt und neu formatiert. Dadurch bleiben die Schlüssel geheim auch wenn der Arbeitsspeicher auf den Stick gesichert wird. Alternativ könnte auch die Option „mlock“ in der OpenVPN Konfiguration gesetzt werden.
Um nicht versehentlich (z.B. USB-Stick vertauscht) eine wichtige Partition zu überschreiben muss der SWAP-Bereich eindeutig gekennzeichnet werden. Dazu wird ein kleines (1MB) ext2-Dateisystem erstellt, das ein Volume-Label und eine UUID im Header enthält. Das crypttab-Script verwendet einen Offset (2048) und formatiert den freien Bereich hinter der ext2-Partition, so bleibt das Label erhalten und die Zuordnung eindeutig.


Automatische Entschlüsselung 🔑

Um die Partitionen nicht bei jedem Hochfahren manuell entschlüsseln zu müssen habe ich ein Initscript geschrieben:

Crtab

Die Zuordnung der Partitionen, Schlüssel und Mapper erledigt die Datei /etc/crtab.conf (ähnlich wie die fstab). Trotz der Namensähnlichkeit unterstützt diese „Crypttab“ allerdings nur die hier vorgestellten Optionen, das Initscript ist nicht kompatibel mit der Debian Crypttab!

Für die SWAP Partition muss die UUID der kleinen ext2-Partition herausgefunden werden:

In die Crtab eintragen:
(action) (device) (mapper) (key) (mount/swap-id)

Aktivieren

Dieser Aufruf startet das Initscript und legt die Symlinks für den automatischen Start an:

Geschafft! Ab jetzt steht der verschlüsselte Speicher unter /store zur Verfügung.

4 Kommentare

  1. Vielen Dank. Jetzt funktioniert es. Tolle Anleitung! Eine Frage: Welche Veränderungen an dem Script müsste ich machen, damit ich zusätzlich eine externe LUKS verschlüsselte USB HDD einbinden kann?

    • Die zusätzliche Partition müsstest du genauso vorbereiten wie den „store“ Bereich auf dem Stick, nur mit anderem Namen, Mapper/Mountpoint usw.
      Für die automatische Entschlüsselung reicht dann einfach ein weiterer Eintrag in der /etc/crtab.conf, angepasst für die HDD:

      luks-key /dev/sdb{X} {mapper} /path/to/your.key /{mountpoint}

  2. Ich habe versucht deiner Anleitung zu folgen, leider hast du nicht beschrieben was der Inhalt von `/etc/crtab.conf` sein soll.

    • Hi, danke für die Info, das habe ich falsch beschrieben!
      Ich hatte die Konfiguration erst als ‚/etc/crypttab‘ gespeichert und wegen der Verwechslung mit Debian später in ‚/etc/crtab.conf‘ umbenannt. Im Beitrag ist das noch vertauscht, ich schaue mir das nachher im Router an und korrigiere den Absatz so wie es tatsächlich läuft.

      Versuche es bis dahin mal mit diesen zwei Zeilen:
      luks-key /dev/sda2 store /overlay-boot/upper/root/luks/store.key /store
      cryptswap [UUID] swap /dev/urandom cryptswap

      [UUID] ist die ID der SWAP Partition (sda3?)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.