[[Vorlage(Archiviert, )]] [[Vorlage(Fortgeschritten)]] {{{#!vorlage Wissen [:Terminal: Ein Terminal öffnen] [:Editor: Einen Editor öffnen] [:sudo: Root-Rechte] [:Rechte: Rechte für Dateien und Ordner ändern] }}} [[Inhaltsverzeichnis()]] Dieser Artikel beschreibt, wie Schreibzugriffe auf das Root-[:Dateisystem:] auf eine [wikipedia:RAM-Disk:] umgeleitet werden können. Dadurch ergeben sich die unter anderem folgende Vorteile: * Nach jedem Neustart ist immer ein „sauberes“ (und stabiles) System verfügbar. * Das Root-Dateisystem kann nicht beschädigt werden, wenn der Rechner einfach ausgeschaltet wird. * Änderungen am Dateisystem werden sichtbar Dabei liegt der Fokus dieses Artikels darauf, ein System für den alltäglichen Einsatz zu haben, wobei trotzdem einfache permanente Änderungen und [:Update:Aktualisierungen] möglichen sind - z.B. als Media-Server, Automotive Computer etc. Denn das Nur-Lesen Dateisystem kann bei Bedarf beschreibbar [:mount:eingebunden ] werden. Ist dies nicht gewünscht oder sollen noch weitere Anforderungen erfüllt werden, können evtl. die folgenden Ansätze weiterhelfen: * Der Wikipedia-Artikel [wikipedia:Live-System:] beschreibt diverse Konfigurationen für verschieden Einsatzzwecke. * Das Aufsetzten eines einfachen Ubuntu Live-System auf einem USB-Stick ist im Artikel [:Live-USB:] beschrieben. * Einsatz von [wikipedia:SquashFS:SquashFS] für das Root-Dateisystem. Für jede permanente Änderung muss dann explizit ein neues Dateisystem-Abbild erzeugt werden. = Überblick = Prinzipiell existieren mit [wikipedia:aufs:] und OverlayFS zwei Möglichkeiten, wie ein Nur-Lesen Root-Dateisystem erzeugt werden kann. Langfristig soll [wikipedia:aufs:] aber durch OverlayFs ersetzt werden, da ersteres nur unter hohem Aufwand der Ubuntu-[:Kernel:]-Maintainer (Betreuer) geführt werden kann. Denn die aufs-Unterstützung wird nicht in den Upstream-Kernel aufgenommen. = Voraussetzungen = Die [:Kernelmodule:] `aufs` bzw. `overlayfs` müssen verfügbar sein. Dies lässt sich mit folgenden Kommandos feststellen: {{{#!vorlage Befehl sudo modprobe aufs }}} bzw. {{{#!vorlage Befehl sudo modprobe overlayfs }}} In den regulären von Ubuntu verwendeten Kerneln ist das `aufs`-Modul ab [:Lucid:Ubuntu 10.04] bis einschließlich [:Precise:Ubuntu 12.04] verfügbar, das `overlayfs`-Modul ist ab Version [:Oneiric:11.10] im Standardkernel enthalten. Es gibt allerdings spezielle Kernel für Portierungen, in denen diese Module fehlen, wie z.B. der [https://launchpad.net/~tiomap-dev/+archive/release: neuste Kernel von TI] für die ARM OMAP Platformen. = Umsetzung = Im Artikel [:Archiv/Nur-Lesen Root-Dateisystem mit aufs:Nur-Lesen Root-Dateisystem mit aufs] ist eine Anleitung enthalten, die auch für OverlayFs geeignet ist. Es sind lediglich folgende Anpassungen nötig: 1. Das Modul `overlayfs` muss in die Datei '''/etc/initramfs-tools/modules''' eingefügt werden, damit es im [wikipedia:initramfs:] verfügbar ist: {{{#!vorlage Befehl echo overlayfs >>/etc/initramfs-tools/modules }}} 1. Es wird ein anderes Skript benutzt, nämlich '''root-ro'''. * Das [#Das-Skript-root-ro root-ro Skript] muss unter '''/etc/initramfs-tools/scripts/init-bottom/root-ro''' gespeichert werden. * Es muss ausführbar gemacht werden [4]. 1. Zuletzt muss das neue initramfs erstellt werden: {{{#!vorlage Befehl sudo update-initramfs -u }}} Dann kann das System neu gestartet werden. Ob alles geklappt hat, lässt sich dann mit folgendem Kommando überprüfen: {{{#!vorlage Befehl sudo mount }}} Falls die originale Rootpartition '''/dev/sdXY''' war, sollte die Ausgabe jetzt u.a. diese drei Einträge enthalten: {{{ overlayfs-root on / type overlayfs (rw) /dev/sdXY on /mnt/root-ro type ext4 (rw,relatime,user_xattr,acl,barrier=1,data=ordered) tmpfs-root on /mnt/root-rw type tmpfs (rw,relatime) }}} == Funktion des Skripts root-ro == * Die echte Rootpartition ist unter '''/mnt/root-ro''' nur lesbar eingehängt. * Die RAM-Disk, welche die Änderungen aufnimmt, ist unter '''/mnt/root-rw''' eingehängt. * Es werden die Treiber `overlayfs` und `aufs` unterstützt, dies wird über den Kernel [:Booten#Bootoptionen:Bootparameter] `root-ro-driver=[overlayfs|aufs]` definiert. Dabei ist `overlayfs` der Standardwert, falls nichts angegeben ist. Zum Deaktivieren gibt es zwei Möglichkeiten: * Es wird der Kernel Bootparameter `disable-root-ro=true` übergeben. * Im echten Root-Dateisystem kann eine (leere) Datei '''disable-root-ro''' in dessen Wurzelverzeichnis angelegt werden, also unter '''/mnt/root-ro/disable-root-ro'''. Nach einem Neustart sollte die Datei wieder entfernt werden. == Änderungen auf dem Nur-Lesen Dateisystem durchführen == Das original Root-Dateisystem ist unter '''/mnt/root-ro''' eingehängt und kann beschreibbar gemacht werden mit {{{#!vorlage Befehl sudo mount -o remount,rw /mnt/root-ro }}} Dann können Änderungen einfach kopiert werden: {{{#!vorlage Befehl cp -v DATEI /mnt/root-ro }}} Damit die Änderungen auch im „virtuellen“ Root-Dateisystem sichtbar werden, ist ggf. ein Neustart erforderlich. Denn wenn es sowohl auf der RAM-Disk ('''/mnt/root-rw''') als auch im echten Root-Dateisystem ('''/mnt/root-ro''') einen Eintrag gibt, hat derjenige auf der RAM-Disk Vorrang. = Deinstallation == Zur Deinstallation muss das Root-Dateinsystem zuerst wieder beschreibbar gemacht werden. Dafür gibt es die oben genannten Wege: 1. Den Kernel mit dem Parameter `disable-root-ro=true` starten 1. Oder die „magische“ Datei '''disable-root-ro''' benutzen {{{#!vorlage Befehl sudo mount -o remount,rw /mnt/root-ro sudo touch /mnt/root-ro/disable-root-ro }}} neu starten {{{#!vorlage Befehl sudo reboot }}} und nach dem Neustart die Datei wieder löschen: {{{#!vorlage Befehl sudo rm /disable-root-ro }}} Wurde das System mit einem „normalen“ beschreibaren Root-Dateisystem gestartet, kann das Skript einfach gelöscht und ein neues initramfs erzeugt werden: {{{#!vorlage Befehl sudo rm /etc/initramfs-tools/scripts/init-bottom/root-ro sudo update-initramfs -u }}} = Das Skript root-ro= {{{#!code bash #!/bin/sh # Copyright, 2012 Axel Heider # # Based on scrpts from # Sebastian P. # Nicholas A. Schembri State College PA USA # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # . # # # Tested with Ubuntu 11.10 # # Notes: # * no changes to the root fs are made by this script. # * if /home/[user] is on the RO root fs, files are in ram and not saved. # # Install: # put this file in /etc/initramfs-tools/scripts/init-bottom/root-ro # chmod 0755 root-ro # optional: clean up menu.lst, update-grub # update-initramfs -u # # Disable read-only root fs # * option 1: kernel boot parameter "disable-root-ro=true" # * option 2: create file "/disable-root-ro" # # ROOT_RO_DRIVER variable controls which driver isused for the ro/rw layering # Supported drivers are: overlayfs, aufs # the kernel parameter "root-ro-driver=[driver]" can be used to initialize # the variable ROOT_RO_DRIVER. If nothing is given, overlayfs is used. # # no pre requirement PREREQ="" prereqs() { echo "${PREREQ}" } case "$1" in prereqs) prereqs exit 0 ;; esac . /scripts/functions MYTAG="root-ro" DISABLE_MAGIC_FILE="/disable-root-ro" # parse kernel boot command line ROOT_RO_DRIVER= DISABLE_ROOT_RO= for CMD_PARAM in $(cat /proc/cmdline); do case ${CMD_PARAM} in disable-root-ro=*) DISABLE_ROOT_RO=${CMD_PARAM#disable-root-ro=} ;; root-ro-driver=*) ROOT_RO_DRIVER=${CMD_PARAM#root-ro-driver=} ;; esac done # check if read-only root fs is disabled if [ ! -z "${DISABLE_ROOT_RO}" ]; then log_warning_msg "${MYTAG}: disabled, found boot parameter disable-root-ro=${DISABLE_ROOT_RO}" exit 0 fi if [ -e "${rootmnt}${DISABLE_MAGIC_FILE}" ]; then log_warning_msg "${MYTAG}: disabled, found file ${rootmnt}${DISABLE_MAGIC_FILE}" exit 0 fi # generic settings # ${ROOT} and ${rootmnt} are predefined by caller of this script. Note that # the root fs ${rootmnt} it mounted readonly on the initrams, which fits nicely # for our purposes. ROOT_RW=/mnt/root-rw ROOT_RO=/mnt/root-ro # check if ${ROOT_RO_DRIVER} is defined, otherwise set default if [ -z "${ROOT_RO_DRIVER}" ]; then ROOT_RO_DRIVER=overlayfs fi # settings based in ${ROOT_RO_DRIVER}, stop here if unsupported. case ${ROOT_RO_DRIVER} in overlayfs) MOUNT_PARMS="-t overlayfs -o lowerdir=${ROOT_RO},upperdir=${ROOT_RW} overlayfs-root ${rootmnt}" ;; aufs) MOUNT_PARMS="-t aufs -o dirs=${ROOT_RW}:${ROOT_RO}=ro aufs-root ${rootmnt}" ;; *) panic "${MYTAG} ERROR: invalide ROOT_RO_DRIVER ${ROOT_RO_DRIVER}" ;; esac # check if kernel module exists modprobe -qb ${ROOT_RO_DRIVER} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: missing kernel module ${ROOT_RO_DRIVER}" exit 0 fi # make the mount point on the init root fs ${ROOT_RW} [ -d ${ROOT_RW} ] || mkdir -p ${ROOT_RW} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to create ${ROOT_RW}" exit 0 fi # make the mount point on the init root fs ${ROOT_RO} [ -d ${ROOT_RO} ] || mkdir -p ${ROOT_RO} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to create ${ROOT_RO}" exit 0 fi # mount a tempfs using the device name tmpfs-root at ${ROOT_RW} mount -t tmpfs tmpfs-root ${ROOT_RW} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to create tmpfs" exit 0 fi # root is mounted on ${rootmnt}, move it to ${ROOT_RO}. mount --move ${rootmnt} ${ROOT_RO} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to move root away from ${rootmnt} to ${ROOT_RO}" exit 0 fi # there is nothing left at ${rootmnt} now. So for any error we get we should # either do recovery to restore ${rootmnt} for drop to a initramfs shell using # "panic". Otherwise the boot process is very likely to fail with even more # errors and leave the system in a wired state. # mount virtual fs ${rootmnt} with rw-fs ${ROOT_RW} on top or ro-fs ${ROOT_RO}. mount ${MOUNT_PARMS} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to create new ro/rw layerd ${rootmnt}" # do recovery and try resoring the mount for ${rootmnt} mount --move ${ROOT_RO} ${rootmnt} if [ $? -ne 0 ]; then # thats badm, drpo to s shell to let the user try fixing this panic "${MYTAG} RECOVERY ERROR: failed to move ${ROOT_RO} back to ${rootmnt}" fi exit 0 fi # now the real root fs is on ${ROOT_RO} of the init file system, our layered # root fs is set up at ${rootmnt}. So we can write anywhere in {rootmnt} and the # changes will end up in ${ROOT_RW} while ${ROOT_RO} it not touched. However # ${ROOT_RO} and ${ROOT_RW} are on the initramfs root fs, which will be removed # an replaced by ${rootmnt}. Thus we must move ${ROOT_RO} and ${ROOT_RW} to the # rootfs visible later, ie. ${rootmnt}${ROOT_RO} and ${rootmnt}${ROOT_RO}. # Since the layered ro/rw is already up, these changes also end up on # ${ROOT_RW} while ${ROOT_RO} is not touched. # move mount from ${ROOT_RO} to ${rootmnt}${ROOT_RO} [ -d ${rootmnt}${ROOT_RO} ] || mkdir -p ${rootmnt}${ROOT_RO} mount --move ${ROOT_RO} ${rootmnt}${ROOT_RO} if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to move ${ROOT_RO} to ${rootmnt}${ROOT_RO}" exit 0 fi # move mount from ${ROOT_RW} to ${rootmnt}${ROOT_RW} [ -d ${rootmnt}${ROOT_RW} ] || mkdir -p ${rootmnt}${ROOT_RW} mount --move ${ROOT_RW} ${rootmnt}${ROOT_RW} if [ $? -ne 0 ]; then s "${MYTAG}: ERROR: failed to move ${ROOT_RW} to ${rootmnt}${ROOT_RW}" exit 0 fi # technically, everything is set up nicely now. Since ${rootmnt} had beend # mounted read-only on the initfamfs already, ${rootmnt}${ROOT_RO} is it, too. # Now we init process could run - but unfortunately, we may have to prepare # some more things here. # Basically, there are two ways to deal with the read-only root fs. If the # system is made aware of this, things can be simplified a lot. # If it is not, things need to be done to our best knowledge. # # So we assume here, the system does not really know about our read-only root fs. # # Let's deal with /etc/fstab first. It usually contains an entry for the root # fs, which is no longer valid now. We have to remove it and add our new # ${ROOT_RO} entry. # Remember we are still on the initramfs root fs here, so we have to work on # ${rootmnt}/etc/fstab. The original fstab is ${rootmnt}${ROOT_RO}/etc/fstab. ROOT_TYPE=$(cat /proc/mounts | grep ${ROOT} | cut -d' ' -f3) ROOT_OPTIONS=$(cat /proc/mounts | grep ${ROOT} | cut -d' ' -f4) cat <${rootmnt}/etc/fstab # # This fstab is in RAM, the real one can be found at ${ROOT_RO}/etc/fstab # The original entry for '/' and all swap files have been removed. The new # entry for the read-only the real root fs follows. Write access can be # enabled using: # sudo mount -o remount,rw ${ROOT_RO} # re-mounting it read-only is done using: # sudo mount -o remount,ro ${ROOT_RO} # ${ROOT} ${ROOT_RO} ${ROOT_TYPE} ${ROOT_OPTIONS} 0 0 # # remaining entries from the original ${ROOT_RO}/etc/fstab follow. # EOF if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to modify /etc/fstab (step 1)" #exit 0 fi #remove root entry and swap from fstab cat ${rootmnt}${ROOT_RO}/etc/fstab | grep -v ' / ' | grep -v swap >>${rootmnt}/etc/fstab if [ $? -ne 0 ]; then log_failure_msg "${MYTAG} ERROR: failed to modify etc/fstab (step 2)" #exit 0 fi # now we are done. Additinal steps may be necessary depending on the actualy # distribution and/or its configuration. log_success_msg "${MYTAG} sucessfully set up ro/tmpfs-rw layered root fs using ${ROOT_RO_DRIVER}" exit 0 }}} = Links = ## * [:Nur-Lesen Root-Dateisystem mit aufs:] * [:chroot/persistente-Installation:] * [ubuntu_doc:community/aufsRootFileSystemOnUsbFlash:aufsRootFileSystemOnUsbFlash] - Hier gibt es evtl eine aktuellere Version des Skripts root-ro. #tag: System, Sicherheit, Installation