PC Engines WRAP als WLAN-Router
Und es routet doch
Die «Wireless Router Application Platform» (WRAP) war ein sparsamer Kleincomputer, lange bevor das Raspberry Pi und seine Kollegen die Gattung der Kleincomputer salonfähig machten. Für die meisten heutigen Aufgaben ist das System deutlich zu langsam, mit der richtigen Software kann es seiner ursprünglichen Berufung als WLAN-Router aber weiterhin gerecht werden.
Bei mir musste das WRAP seinerzeit einem ALIX-System weichen, weil es von der Leistung her nicht mehr mit den steigenden Bandbreiten zurecht kam. Seit einer Weile verwaltet es als Router das Zweit-WLAN, wo es mit pfSense bestückt zuverlässig seinen Dienst tat. Leider stellte pfSense mit Version 2.4 die Unterstützung für 32-bit-Systeme ein, so dass ich entweder das Gerät oder das Betriebssystem tauschen musste – letzteres schien mir sinnvoller. Nach einigen Experimenten gelang ich schliesslich zur Einsicht, dass es an der Zeit ist, wieder einmal selbst Hand anzulegen und dem WRAP ein massgeschneidertes Kostüm zu verleihen, ein klassisch gebautes Betriebssystem für ein klassisches Gerät.
Die Anforderungen
Die Erwartungen für den Einsatz in unserem Zweit-WLAN sind recht bescheiden: Das Gerät soll WLAN routen. Es soll dies im Frequenzbereich von 2.4 GHz nach IEEE 802.11b/g tun, so dass das Netz auch für ältere Geräte erreichbar ist, selbstverständlich WPA2-verschlüsselt. Darüberhinaus schienen mir folgende Punkte relevant:
- Von den drei Ethernet-Buchsen brauche ich eine für den Internetzugang, die anderen beiden sollen Netzzugang für mögliche weitere Geräte zur Verfügung stellen. Der Einfachheit halber schliesse ich das Kabelmodem an der mittleren Buchse an, dann ist egal in welcher Richtung diese nummeriert werden.
- Selbstverständlich soll auf dem Router aktuellste Software ohne bekannte Sicherheitslücken zum Einsatz kommen und das System soll einfach wartbar sein; insbesondere darf es für Aktualisierungen nicht erforderlich sein, die Speicherkarte auszubauen. Wartung geschieht per SSH oder über eine serielle Konsole.
- Da das WRAP keine Stützbatterie für die Uhr hat, muss die aktuelle Uhrzeit per NTP bezogen werden.
- Damit das System über die Jahre nicht unter ständigen Schreibzugriffen leidet, soll auf das Speichermedium im Betrieb nur lesend zugegriffen werden.
Die Hardware
Die Denkarbeit auf dem WRAP erledigt eine CPU des Typs Geode SC1100 (GX1) mit 266 MHz, 128 MB Arbeitsspeicher sind ebenfalls vorhanden. Für die Verbindung ans Netzwerk stehen drei 100mbps-Ethernet-Anschlüsse zur Verfügung, eine Mini-PCI-Karte mit Atheros AR5213A schliesslich erledigt die Drahtloskommunikation. Das Betriebssystem wird auf einer CompactFlash-Karte installiert.
Das Betriebssystem beschreibt die CPU wie folgt:
$ cat /proc/cpuinfo processor : 0 vendor_id : Geode by NSC cpu family : 5 model : 9 model name : Unknown stepping : 1 cpu MHz : 266.579 fdiv_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu tsc msr cx8 cmov mmx cxmmx bogomips : 88.47 clflush size : 32 cache_alignment : 32 address sizes : 32 bits physical, 32 bits virtual power management:
Das System
Um das WRAP nicht mit unnötigem Ballast zu quälen, sollte die Software möglichst genau auf das System und auf den Einsatz als WLAN-Router abgestimmt sein. Insbesondere brauchen wir:
- Einen Bootloader
- Einen Kernel
- User-Space-Applikationen
Die ganze Software wird auf einem Drittrechner für das WRAP kompiliert; einerseits um Zeit zu sparen, andererseits aber auch, um etwaige Huhn-Ei-Probleme zu umschiffen.
Partitionierung
Bevor wir loslegen, müssen wir die Speicherkarte vorbereiten. Das selbstgebaute System wird recht wenig Speicherplatz belegen, ein paar Megabytes sollten reichen. Ich hatte noch eine 64-MB-Karte aus einer alten Photokamera herumliegen und habe darum diese gewählt; auf all dem überflüssigen Platz können wir noch eine zweite Kopie des Betriebssystem installieren, für Notfälle oder Wartungsarbeiten.
Das sieht dann folgendermassen aus:
$ fdisk -l /dev/sdx Disk /dev/sdx: 61.3 MiB, 64225280 bytes, 125440 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000 Device Boot Start End Sectors Size Id Type /dev/sdx1 2048 43007 40960 20M 83 Linux /dev/sdx2 43008 83967 40960 20M 83 Linux /dev/sdx3 83968 124927 40960 20M 83 Linux
Danach formatieren wir die Partitionen und konfigurieren die Dateisysteme:
$ mkfs.ext3 /dev/sdx1 $ mkfs.ext3 /dev/sdx2 $ mkfs.ext3 /dev/sdx3 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx1 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx2 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx3
Die CompactFlash-Karte ist nun bereit, bespielt zu werden.
Bootloader
Als Bootloader verwenden wir GNU GRUB, zur Zeit ist Version 2.02 aktuell. Bereits beim Kompilieren können wir einige unnötige Komponenten deaktivieren und mit der Angabe des Präfix sicherstellen, dass der WRAP-GRUB nicht die Dateien des GRUB unserer Kompiliermaschine überschreibt:
$ ./configure --disable-liblzma --disable-device-mapper --disable-efiemu --prefix=/tmp/grub
Danach wird GRUB mit make und make install installiert. Falls auf einem allzu modernen System kompiliert wird, ist ein kleiner Patch mit Anpassungen nötig; alternativ sollte auch die jeweils aktuelle GIT-Version von GRUB funktionieren.
Nach dem Kompilieren können wir den Bootloader auf die CompactFlash-Karte installieren. Dazu binden wir die erste Partition ein:
$ mount /dev/sdx1 /mnt/cf
Danach wird das Installationsskript (als root) aufgerufen. Die Angabe des Boot-Verzeichnisses verhindert dabei wieder, dass bestehende Dateien verändert werden und die explizite Liste der zu installierenden Module sorgt dafür, dass GRUB statt seiner vollständigen Modulsammlung lediglich die gelisteten Module installiert; das spart Speicherplatz und auch Zeit beim Start:
# ./grub-install --locales= --boot-directory=/mnt/cf/ /dev/sdx \ --install-modules="ext2 part_msdos serial terminfo normal linux"
Schliesslich kommt noch die GRUB-Konfigurationsdatei auf die CF-Karte. Mit dieser Konfiguration lässt sich GRUB über die serielle Konsole steuern und beide Betriebssysteme können aus dem Menü gestartet werden:
$ cat /mnt/cf/grub/grub.cfg serial --speed=57600 terminal_input serial terminal_output serial set timeout_style=countdown set timeout=2 insmod part_msdos insmod ext2 menuentry 'buildroot' { set root='hd0,msdos1' linux /bzImage-3.16 console=ttyS0,57600n8 root=/dev/sda2 ro notsc } menuentry 'buildroot (recovery)' { set root='hd0,msdos1' linux /bzImage-3.16 console=ttyS0,57600n8 root=/dev/sda3 ro notsc }
Kernel
Die genaue Kernel-Version spielt keine grosse Rolle, alle Treiber für das WRAP sind schon lange dabei. Wichtig ist, dass wir einen aktuellen LTS-Kernel mit allen Sicherheitspatches einsetzen, hier exemplarisch die aktuellste Version von Kernel 3.16. Kernel-Konfigurationen für verschiedene Versionen finden sich auf git, beim Einsatz anderer oder zusätzlicher Kernel-Versionen ist die GRUB-Konfiguration entsprechend anzupassen bzw. zu ergänzen.
Da sich die Regeln bezüglich Drahtlosübertragung (Frequenzbänder, Sendestärke) von Land zu Land unterscheiden, wacht normalerweise auf GNU/Linux-Systemen der CRDA-Dienst darüber, dass die jeweiligen Gesetze eingehalten werden. Um uns diesen Dienst zu sparen, kopieren wir vor dem Kompilieren die statische Liste der erlaubten Frequenzbänder nach net/wireless/db.txt
.
Danach können wir kompilieren. Den fertigen Kernel kopieren wir zu den GRUB-Dateien auf der ersten Partition der CF-Karte. Das sieht dann folgendermassen aus:
$ ls -1 /mnt/cf/ bzImage-3.16 grub lost+found
Nun werfen wir die Partition wieder aus:
$ umount /mnt/cf
User-Space
Unser eigentliches Betriebssystem kommt von Buildroot, einer sparsamen Distribution, die für den Einsatz auf Geräten mit begrenzten Ressourcen besonders geeignet ist. Ähnlich wie schon beim Linux-Kernel, werden auch bei Buildroot die (meisten) Optionen in einer zentralen Konfigurationsdatei verwaltet und mit make menuconfig bearbeitet.
Meine Buildroot-Konfiguration für WRAP sieht zwei zusätzliche Verzeichnisse vor: overlay
beinhaltet von Hand angepasste Dateien, die ebenfalls im fertigen System landen, custom_config
enthält Konfigurationsschnipsel, die nicht in der Hautpkonfigurationsdatei verwaltet werden können (zur Zeit lediglich eine Option von busybox). Die beiden Verzeichnisse sind auf git zu finden, die Konfigurationsdatei ebenfalls; letztere muss vor dem Gebrauch in .config
umbenannt werden.
Meine Buildroot-Konfiguration ist noch in folgenden Punkten anzupassen:
- In
.config
sollte das Passwort fürroot
von «CHANGEME» auf einen sinnvollen Wert geändert werden. Auch der gewünschte Hostname lässt sich in dieser Datei setzen. - Für das WLAN sind die SSID, der WPA-Schlüssel und ggf. der Ländercode in
overlay/etc/hostapd.conf
zwingend anzupassen. - Falls der Adressbereich für den DHCP-Server geändert werden soll, kann dies in
overlay/etc/network/interfaces
undoverlay/etc/dnsmasq.conf
geschehen. - Die leere Datei
overlay/etc/dropbear/dropbear_ecdsa_host_key
sollte durch einen gültigen Host-Key für dropbear ersetzt werden. Ein solcher Schlüssel lässt sich mit dropbearkey -t ecdsa -f overlay/etc/dropbear/dropbear_ecdsa_host_key erzeugen. - Damit das passwortlose Login per SSH klappt, werden die öffentlichen SSH-Schlüssel in der Datei
overlay/root/.ssh/authorized_keys
eingetragen. - Meine WLAN-Karte hat zwei Antennenanschlüsse, das WRAP jedoch nur einen. In der Datei
overlay/etc/network/if-pre-up.d/wlan0
ist darum definiert, dass lediglich einer der beiden Anschlüsse verwendet wird. Falls der WLAN-Empfang am Ende nicht überzeugt, kann dies daran liegen, dass der falsche Antennenanschluss aktiv ist; das lässt sich in dieser Datei umkonfigurieren.
Nach dem Kompilieren mit make sollte in output/images/rootfs.tar
unser frisch kompiliertes System bereitstehen. Dieses können wir nun (wieder als root) auf die beiden leeren Partitionen schreiben:
# mount /dev/sdx2 /mnt/cf # tar -C /mnt/cf -xf output/images/rootfs.tar # umount /mnt/cf # mount /dev/sdx3 /mnt/cf # tar -C /mnt/cf -xf output/images/rootfs.tar # umount /mnt/cf
Danach ist die CF-Karte bereit.
System starten
Die fertig beschriebene Karte bauen wir nun ins WRAP ein. Damit wir sehen können, ob alles korrekt funktioniert, verwenden wir die serielle Konsole. Die korrekten Parameter für das WRAP sind:
- 57600 bps
- 8 Bits
- Keine Parität
- 1 Stop-Bit
Falls die BIOS-Meldungen nicht sichtbar sind, ist die Geschwindigkeit der seriellen Schnittstelle im BIOS wahrscheinlich falsch eingestellt. Der Standardwert beim WRAP ist 38400 bps, es können aber auch 9600 bps eingestellt sein – da hilft nur ausprobieren.
Das Gerät sollte je nach CF-Karte nach ca. 15 – 25 Sekunden fertig gestartet haben und ist dann bereit für seinen Einsatz als WLAN-Router. Meines hängt an einem rudimentären Kabelanschluss der lediglich 10 Mbps liefert, da passt das WRAP perfekt und liefert ebenso viel Leistung wie dies ein aktueller Router auch täte, ist für Updates jedoch nicht auf den guten Willen eines Hardware-Herstellers angewiesen und wird auch nicht vorzeitig geplant obsolet.
Und wunderschön rot ist es auch.