weidner/computer/linux/router/

Linux mit einem Read-Only-Root-Filesystem

Damit ich meinen Router mit Linux bedenkenlos ausschalten kann, muss ich einige Vorkehrungen treffen. Am besten ist es, das Root-Dateisystem read-only einzuhängen.

Read-Only-Root-Filesystem

Ich habe mir einen Artikel auf help.ubuntu.com als Anregung für das Read-Only Filesystem genommen. Dort wird mit AUFS ein Union-Filesystem über / gelegt, das alle Schreiboperationen auf ein anderes Dateisystem (in diesem Fall ein RAM-Filesystem) umlenkt. Auf meinem Router ist Debian 6 Squeeze installiert, so dass ich ein paar kleinigkeiten abwandeln musste.

Zunächst wird der Rechner aktualisiert und die aufs-tools installiert:

apt-get update
apt-get dist-upgrade
apt-get install aufs-tools

Das Script __rootaufs von besagtem Artikel habe ich hier abgelegt, für den Fall das der Artikel nicht mehr erreichbar ist. Dort sollte jedoch die neueste Version zu finden sein.

Dieses Script wird unter /etc/initramfs-tools abgelegt und ausführbar gemacht. Außerdem wird Sorge dafür getragen, dass das Kernelmodule aufs von der InitRAM-Disk geladen wird:

echo aufs >> /etc/initramfs-tools/modules
cp __rootaufs /etc/initramfs-tools/scripts/init-bottom/
chmod 0755 /etc/initramfs-tools/scripts/init-bottom/__rootaufs

Ich habe das Script geringfügig modifziert, um ein paar störende Fehlermeldungen auf dem Startbildschirm loszuwerden. Hier verlinkt ist das modifizierte Script. Die Änderungen sind:

--- __rootaufs.orig 2011-04-11 21:46:53.000000000 +0200
+++ __rootaufs  2011-04-13 09:36:39.000000000 +0200
@@ -50,6 +50,7 @@
         ;;
     aufs=*)
         aufs=${x#aufs=}
+        aufsdebug=0
         case $aufs in
         tmpfs-debug)
             aufs=tmpfs
@@ -222,8 +223,8 @@

 #  Copyright 2008 Joaquín I. Bogado García
 #fix para apparmor, se desactiva y listo ( From the lethe project. )
-rm /scripts/init-bottom/_apparmor
-rm /aufs/etc/init.d/apparmor
+[ -f /scripts/init-bottom/_apparmor ] && rm /scripts/init-bottom/_apparmor
+[ -f /aufs/etc/init.d/apparmor ]      && rm /aufs/etc/init.d/apparmor


 #build remountrw

Nun können wir ein neues InitRAM-Filesystem anlegen

update-grub
update-initramfs -u

Grub

Bei Debian 6 wird per Standard GRUB Version 2 installiert. Die Boot-Optionen werden hier nicht mehr, wie bisher, in /boot/grub/menu.lst eingestellt. Der Eintrag aufs=tmpfs, der dann beim Booten ausgewertet werden soll, wird hier in /etc/default/grub geschrieben. Die betreffende Zeile sieht bei mir so aus:

GRUB_CMDLINE_LINUX_DEFAULT="quiet aufs=tmpfs"

Anschließend ruft man update-grub auf und und schließlich update-initramfs -u.

Damit ist das Read-Only-Root-Filesystem einsatzbereit. Das originale Dateisystem ist unter /ro/ read-only eingehängt. Unter /rw/ ist ein RAM-Filesystem eingehängt, in das alle Schreibzugriffe auf die Root-Partition gehen. Mit den Befehlen remountrw und remountro kann man die Mountoptionen für das Dateisystem unter /ro/ während des Betriebes auf read-write bzw. read-only ändern, um z.B. Änderungen, die nach /rw/ gingen, dauerhaft zu machen, damit sie nach dem nächsten Neustart noch präsent sind.

Software aktualisieren

Wenn man auf diesem System Software aktualisieren will, empfehlt der Artikel, beim Bootmenü von GRUB e eingeben, aus der Kernelzeile das aufs=tmpfs entfernen und schließlich mit b den Rechner ohne aufs starten.

Das ist etwas umständlich und geht sicher noch einfacher. Z.B. könnte man ein Update mit AUFS einspielen, das Verzeichnis /ro/ read-write umhängen und die Änderungen von /rw/ nach /ro/ kopieren. Dabei muss man allerdings aufpassen, dass man keine ungewollten Änderungen nach /ro/ kopiert.

Software austauschen

Bei dem beschränkten Platz auf dem RAM-Filesystem möchte man sichergehen, das kein Programm dieses füllt und damit u.U. den Router bis zum nächsten Neustart unbrauchbar macht. Dazu gilt es die Programme zu identifizieren, die die Platte eventuell unkontrolliert vollschreiben.

Syslogd

Ein Kandidat ist der Systemprotokolldienst (rsyslogd bei Debian 6). Bei diesem wird empfohlen regelmäßig mit logrotate die Protokolldatei zu rotieren und dadurch klein zu halten. Da logrotate jedoch immer zu festen Zeiten via cron gestartet wird, haben wir keine Kontrolle darüber, wieviel rsyslog in der Zwischenzeit in die Protokolldateien schreibt.

Ich habe mich auf meinem Router für den busybox-syslogd entschieden, der bei Debian mit eben diesem Paket installiert wird. Dieser Syslog-Dämon ist im Binary von busybox enthalten, somit benötigt das Paket nur sehr wenig zusätzlichen Platz. Der syslogd von busybox kann in einen Puffer im Hauptspeicher protokollieren, dessen Größe beim Start vorgegeben wird. Die Systemprotokolle werden dann mit dem Befehl logread (ebenfalls busybox) gelesen.

Offene Dateien ermitteln

Um weitere Programme zu finden, die Dateien in die Root-Partition schreiben, kann ich die Programme fuser und lsof verwenden. Mit dem Befehl

$ sudo fuser -amv /
                     USER        PID ACCESS COMMAND
/:                   root     kernel mount /
...
                     dnsmasq     615 .rce.  dnsmasq
                     root        641 Frce.  cron

kann ich die Programme und Prozesse ermitteln, die Dateien der Partition / zum Schreiben geöffnet haben. Diese haben ein F in der Spalte ACCESS. Über die Spalte PID bekomme ich die Prozess-ID und kann mit lsof nachsehen, welche Dateien konkret geöffnet sind:

$ sudo lsof -p 641
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
...
cron    641 root    3u   REG   0,16        4  436 /var/run/crond.pid

Hier sind die Zeilen interessant, bei denen in Spalte FD ein u oder w steht und in der Spalte TYPE ein REG für reguläre Datei.

Posted 2011-04-11
Tags: