|
19. Ramdisk Router1.1 HintergrundHardware Plattformen wie Soekris net6501-30 stellen mit 512MB RAM genügend Memory zur Verfügung, um Linuxrouter in einer Ramdisk zu betreiben. Die Vorteile liegen auf der Hand, bei Verdacht auf ein korrumpiertes System genügt ein Reboot um den Router in seinen Ausgangszustand zurückzuführen. ( Um dann die nötigen Schritte einzuleiten, damit ein erfolgreicher Angriff nicht wiederholt werden kann. ) Linuxrouter wird auch in seiner Ramdisk Version als standalone Maschine betrieben, da sonst ein separater Bootserver bereitgestellt werden müsste, der das System zur Verfügung stellt. Mit anderen Worten, es handelt sich nicht um eine «diskless» Maschine. 19.2 Systembau
Der Aufbau des Ramdisk Systems erfordert die folgenden Schritte:
-Linuxrouter wird in die Partition 19.3 SystemträgerAls Systemträger wurde eine 120GB SSD ( Solid State Disk ) mit folgendem Aufbau verwendet.
Erklärung: 19.4 Kernel Konfiguration
Kernel 2.6.39 muss mit
19.5
|
# /etc/fstab.std /dev/sda1 / ext2 defaults 1 1 /dev/sdb1 /media/usb vfat,ext2,ext3,iso9660 rw,noauto,user,exec 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 proc /proc proc defaults 0 0 usbfs /proc/bus/usb usbfs defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev/shm tmpfs nodev,nosuid,noexec 0 0 # /etc/fstab.ramboot none / tmpfs defaults 0 0 /dev/sdb1 /media/usb vfat,ext2,ext3,iso9660 rw,noauto,user,exec 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 proc /proc proc defaults 0 0 usbfs /proc/bus/usb usbfs defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev/shm tmpfs nodev,nosuid,noexec 0 0 |
Anschliessend wird ein Softlink auf /etc/fstab.std
angelegt.
( Beim Kopieren des Systems wird der Link umgeschrieben, so dass das
Ramdisk System mit der /etc/fstab.ramboot
startet. )
# cd /etc # ln -s fstab.std fstab |
/etc/rc.d/rc.S
anpassen
Bei «normalen» Bootups wird das Root Filesystem des Systems
mittels e2fschck
auf Fehler untersucht.
Wenn in eine Ramdisk gebootet wird, ist diese Überprüfung überflüssige und erzeugt lediglich die Fehlermeldung:
ERROR: Root partition has already been mounted read-write. Cannot check!
Daher muss das Startscript /etc/rc.d/rc.S
ebenfalls modifiziert
werden − zugegebenermassen ein «ugly hack», Vorschläge,
wie dieser vermieden werden kann, sind willkommen.
/etc/rc.d/rc.S
wird somit ebenfalls in zwei Versionen geführt,
/etc/rc.d/rc.S.std
und /etc/rc.d/rc.S.ramboot
.
Slackware 11.0 /etc/rc.d/rc.S
verzichtet auf eine Überprüfung des
Filesystems, wenn dieses vom Typ umsdos
ist. Für
/etc/rc.d/rc.S.ramboot
genügt es somit, an zwei Stellen
«umsdos
» durch «tmpfs
» zu ersetzen.
Damit wird auf die Überprüfung der Ramdisk verzichtet.
# /etc/rc.d/rc.S.ramboot # lines 140ff ... echo "Testing root filesystem status: read-write filesystem" #if cat /etc/fstab | grep ' / ' | grep -wq umsdos ; then # ROOTTYPE="umsdos" #fi #if [ ! "$ROOTTYPE" = "umsdos" ]; then # no warn for UMSDOS if cat /etc/fstab | grep ' / ' | grep -wq tmpfs ; then ROOTTYPE="tmpfs" fi if [ ! "$ROOTTYPE" = "tmpfs" ]; then # no warn for tmpfs ... |
Anschliessend wird ein Softlink auf /etc/rc.d/rc.S.std
angelegt.
# cd /etc/rc.d # ln -s rc.S.std rc.S |
Der Bootmanager muss den Router via initrd
starten.
Linuxrouter v0.50 verwendet lilo
, die zugehörige
lilo.conf
benötigt somit die folgenden Einträge.
# /etc/lilo.conf # 2016-01-12 # # Comment the following two entries out after the first install on the development machine. #disk=/dev/sdd bios=0x80 # Overrides BIOS' harddisk order, makes BIOS see sdd as sda. #boot=/dev/sdd # Where lilo installs its boot block. boot=/dev/sda map=/boot/map install=text default=ramboot lba32 read-only prompt timeout=50 # LILO bootable partitions config image=/boot/linux label=linux root=/dev/sda1 append="console=tty0 console=ttyS0,9600n8r" image=/boot/linux label=ramboot root=/dev/sda1 initrd=/boot/initrd.gz append="console=tty0 console=ttyS0,9600n8r" |
initrd-tree
anpassen
Die Vorlage für das Minimalfilesystem, das von /usr/sbin/mkintrd
auf die initrd
kopiert wird, befindet sich im Tarfile
/usr/share/mkinitrd/initrd-tree.tar.gz
.
Unix Systembefehle wie cp
, mount
, etc., die
darin enthalten sind, werden via BusyBox
bereitgestellt.
Leider ist die BusyBox
, die im initrd-tree
von
Slackware 11.0 zur Anwendung kommt, ohne tar
Support kompiliert.
Somit kann das System Archiv /boot/sysimg.tar
beim Booten
nicht in die Ramdisk entpackt werden.
Da die BusyBox
statisch gelinkt ist, ist Abhilfe jedoch recht
einfach. Wir benützen das Archiv /usr/share/mkinitrd/initrd-tree.tar.gz
eines neueren Systems, beispielsweise von Slackware 13.0. Das Vorgehen ist
wie folgt:
Den initrd-tree
eines Slackware 13.0 Systems auf den Router
kopieren und im /tmp
Verzeichnis entpacken.
# mkdir /tmp/slack13 # cp initrd-tree_slack13_orig.tar.gz /tmp/slack13 # cd /tmp/slack13 # tar -xzvf initrd-tree_slack13_orig.tar.gz # rm initrd-tree_slack13_orig.tar.gz |
Den initrd-tree
von Linuxrouter sichern und ebenfalls im /tmp
Verzeichnis entpacken.
# mv /usr/share/mkinitrd/initrd-tree.tar.gz /usr/share/mkinitrd/initrd-tree_slack11.tar.gz # mkdir /tmp/slack11 # cp /usr/share/mkinitrd/initrd-tree_slack11.tar.gz /tmp/slack11 # cd /tmp/slack11 # tar -xzvf initrd-tree_slack11.tar.gz |
Den initrd-tree
von Slackware 13.0 an die Gegebenheiten
von Slackware 11.0 anpassen.
# cd /tmp/slack13 # mkdir ramboot # rm init # cp ../slack11/linuxrc . # cp ../slack11/linuxrc linuxrc00 # cd bin # ln -s busybox chroot # ln -s busybox insmod # ln -s busybox pivot_root |
Die Konfigurationsdatei /tmp/slack11/linuxrc
derart anpassen,
dass beim Booten des Systems via initrd
eine funktionsfähige
Ramdisk erstellt wird. Die folgenden Anpassungen sind notwendig.
# linuxrc ... # Mount root filesystem on rootdev to /mnt #mount -o ro -t $ROOTFS $ROOTDEV /mnt mount -o ro -t ext2 /dev/sda1 /mnt # Create root ramdisk mount -t tmpfs -o size=256M /dev/ram2 /ramboot # Copy your sysimg.tar file over to the ramdisk cd /ramboot tar xf /mnt/boot/sysimg.tar umount /mnt ## Uncomment for debugging #echo "list /ramboot content" #ls /ramboot #echo "show mounted devices" #mount ... # OK, in case there's no initrd directory: # ( NOTE: The directory for the old root must exist before calling pivot_root. ) if [ ! -d /ramboot/initrd ]; then mkdir -p /ramboot/initrd fi # bye now echo "/boot/initrd.gz: exiting" pivot_root . initrd exit 0 |
Damit kann der initrd-tree
neu gepackt werden.
# cd /tmp/slack13 # tar czvf /usr/share/mkinitrd/initrd-tree_slack13_custom.tar.gz . |
Die neu angelegten Verzeichnisse in /tmp
werden nicht
mehr benötigt.
# cd /tmp # rm -rf slack11 # rm -rf slack13 |
Das neu erstellte Archiv /usr/share/mkinitrd/initrd-tree_slack13_custom.tar.gz
mittels Softlink systemkonform benennen.
# cd /usr/share/mkinitrd/ # ln -s initrd-tree_slack13_custom.tar.gz initrd-tree.tar.gz |
Als letztes muss das Script /usr/sbin/mkintrd
gesichert
und wie folgt angepasst werden.
# cd /usr/sbin # cp mkinitrd mkinitrd00 |
# /usr/sbin/mkintrd # line 87 ... # PAD=98 PAD=1536 ... |
initrd
anlegen
Mit Hilfe des angepassten Archivs initrd-tree.tar.gz
kann nun eine
initrd
für den Ramdisk Router angelegt werden.
Der Aufruf von /usr/sbin/mkintrd
mit Parametern bewirkt:
-dass das File /boot/initrd.gz
angelegt wird,
-dass das Verzeichnis /boot/initrd-tree/
angelegt wird.
Der Aufruf von /usr/sbin/mkintrd
ohne Parametern bewirkt:
-dass ein neues File /boot/initrd.gz
angelegt wird, das
den Inhalt von /boot/initrd-tree
übernimmt.
Mit anderen Worten: Wenn die /boot/initrd.gz
erstmalig
erzeugt wird, werden die relevanten Parameter angegeben:
# mkinitrd -c -f ext2 -r /dev/sda1 -c : Clear the existing initrd tree /boot/initrd-tree -f : Specify the filesystem to use for the root partition. Use together with -r -r : Specify the device to be used as the root partition -k : Use kernel modules from the specified version -o : The file to write the initrd to, this is /boot/initrd.gz by default |
( In der hier diskutierten Konfiguration ist der Aufruf von «-f»
und «-r» nicht wirklich nötig, da die entsprechenden
Werte bereits in die Konfigurationsdatei /boot/initrd-tree/linuxrc
geschrieben wurden. )
Wenn anderseits nachträgliche Anpassungen am File /boot/initrd-tree/linuxrc
vorgenommen werden, dann muss die neue /boot/initrd.gz
mit dem folgenden Kommando erstellt werden ( ansonsten /boot/initrd-tree/
ebenfalls neu erstellt und damit überschrieben wird ):
# mkinitrd |
Es ist somit keine schlechte Idee, das File /boot/initrd-tree/linuxrc
nach Änderungen zumindest lokal zu sichern!
# cp /boot/initrd-tree/linuxrc /boot/linuxrc_current |
Hinweis: Immer wenn das /boot/initrd.gz
File neu angelegt wird, muss
anschliessend lilo
aufgerufen werden, damit /boot/initrd.gz
beim Booten erkannt wird.
# lilo |
Damit ist das System derart vorbereitet, dass es kopiert und ins Archivfile
/boot/sysimg.tar
geschrieben werden kann, das dann seinerseits
beim Booten in die Ramdisk entpackt wird.
Dafür steht das folgende Script /boot/create_rtr05_bootimg.sh
zur Verfügung.
Anmerkung: Die Kopieroption -x (--one-file-system) bewirkt, dass der Kopiervorgang
nur innerhalb des lokalen Filesystems stattfindet, und dass gemountete
Filesysteme nicht kopiert werden. Damit werden die Pseudofilesysteme
/proc
und /sys
nicht kopiert und es wird auch
vermieden, dass cp
versucht, das kopierte System rekursiv
erneut zu kopieren, denn die Kopie wird in eine Ramdisk geschrieben und
diese besitzt ein tmpfs
. Es ist somit möglich, ein
laufendes System korrekt und vollständig zu kopieren (eine
nützliche Erkenntnis, denn damit ist es auch möglich ein
beliebiges System, beispielsweise einen Server, im laufenden Betrieb
zu sichern).
#!/bin/sh # # /boot/create_rtr05_bootimg.sh # # First completed 2015-12-26 # Last changed 2016-02-24 # # rolf.burkart@linuxrouter.ch # # Description: # Script takes an OS snapshot, and writes it to /boot/sysimg.tar # # Usage: # Run script as root to create a tar archive of your current # router OS. Run this script again after making changes to # the parent OS to update the ramdisk system as well. # # ============================================== # User variables # ============================================== # FSTAB_STD="/etc/fstab.std" FSTAB_RAMBOOT="/etc/fstab.ramboot" RC6_STD="/etc/rc.d/rc.S.std" RC6_RAMBOOT="/etc/rc.d/rc.S.ramboot" BOOT="/boot" RAMDISK="/mnt/ramdisk" RAMDISK_SIZE="256M" SYSIMG="sysimg.tar" SHELLSCRIPT_PATH="/boot/create_rtr05_bootimg.sh" LOG_PATH="/var/log" # # ============================================== # Code section # ============================================== # # Check if fstab files exist. if [ ! -f ${FSTAB_STD} ]; then echo "File ${FSTAB_STD} does not exist. Aborting... " exit 1 fi if [ ! -f ${FSTAB_RAMBOOT} ]; then echo "File ${FSTAB_RAMBOOT} does not exist. Aborting... " exit 1 fi # Check if rc.S files exist. if [ ! -f ${RC6_STD} ]; then echo "File ${RC6_STD} does not exist. Aborting... " exit 1 fi if [ ! -f ${RC6_RAMBOOT} ]; then echo "File ${RC6_RAMBOOT} does not exist. Aborting... " exit 1 fi # Check for leftovers from previous runs. if [ -f ${BOOT}/${SYSIMG} ]; then echo "Removing old ${BOOT}/${SYSIMG}... " rm ${BOOT}/${SYSIMG} fi # Clear logfiles of parent system. cat /dev/null > ${LOG_PATH}/cron cat /dev/null > ${LOG_PATH}/debug cat /dev/null > ${LOG_PATH}/lastlog cat /dev/null > ${LOG_PATH}/messages cat /dev/null > ${LOG_PATH}/ntp.log cat /dev/null > ${LOG_PATH}/secure cat /dev/null > ${LOG_PATH}/syslog cat /dev/null > ${LOG_PATH}/wtmp # Create mountpoint for ramdisk if it does not exist. if [ ! -d ${RAMDISK} ]; then mkdir ${RAMDISK} echo "Ramdisk mountpoint ${RAMDISK} created." fi echo "Switching fstab to fstab.ramboot... " ln -sf ${FSTAB_RAMBOOT} /etc/fstab echo "Switching rc.S to rc.S.ramboot... " ln -sf ${RC6_RAMBOOT} /etc/rc.d/rc.S echo "Mounting ramdisk on ${RAMDISK}... " mount -t tmpfs -o size=${RAMDISK_SIZE} tmpfs ${RAMDISK} echo "Copying system to ${BOOT}/${SYSIMG} ... " exec 3>&1 exec 1>/dev/null cd / # The --one-file-system option 'x' ask the cp command not # to cross mount points and stay in local file system when copying # files and directories. So "/sys, /proc, /mnt/ramdisk" will not be copied. cp -vax /. ${RAMDISK}/. cp -vax /dev/. ${RAMDISK}/dev/. rm ${RAMDISK}/${SHELLSCRIPT_PATH} cd ${RAMDISK} tar -cf ${BOOT}/${SYSIMG} ./ cd / exec 1>&3 echo "Switching fstab and rc.S back to std... " ln -sf ${FSTAB_STD} /etc/fstab ln -sf ${RC6_STD} /etc/rc.d/rc.S echo "Umounting ramdisk... " umount ${RAMDISK} echo "done" exit 0 |
/boot/sysimg.tar
erzeugen und Ramdisk Router booten.
# cd /boot # chmod 0770 create_rtr05_bootimg.sh # ./create_rtr05_bootimg.sh # telinit 6 |
Eine Systemsicherung des Ramdisk Routers lässt sich dank der SSD sehr
einfach durchführen. Den Router in die Ramdisk booten, anschliessend
kann das Grundsystem problemlos auf eine freie Partition − beispielsweise
nach /dev/sda6
− oder auf einen USB Stick kopiert werden.
Vorgehen:
Grundsystem und freie Partition mounten.
# mount /dev/sda1 /mnt # mkdir /vol_b # mount /dev/sda6 /vol_b |
/mnt/boot/sysimg.tar
braucht nur Platz und muss nicht gesichert werden.
# mv /mnt/boot/sysimg.tar /vol_b |
Wenn der Backup nicht auf der SSD des Routers verbleiben soll, einen USB Stick mounten.
# mount /dev/sdb1 /media/usb |
System kopieren.
# cd /mnt # tar -czSpv --numeric-owner --atime-preserve -f /media/usb/slack11_lnxrtr_v05_2019-01-02.tar.gz ./ |
sysimg.tar
an seinen Platz zurückkopieren und /dev/sda1
umounten.
# mv /vol_b/sysimg.tar /mnt/boot # umount /mnt |
Ausgangszustand wiederherstellen, vol_b
wird nicht mehr gebraucht. USB Stick umounten.
# umount /vol_b # rmdir /vol_b # umount /media/usb |
Den Backup im feuer- und erdbebensicheren Panzerschrank verwahren.
;-)
Prev | Home | |
IPv6 Router | Content | That's all folks |