http://gentoo-wiki.com/HOWTO_Read-only_root_filesystem http://www.debian-administration.org/users/endecotp/weblog/1 I used to maintain a file in which I summarized all I knew about running Debian with a read-only root filesystem. I took the file offline when I decided to stop maintaining it. I was not aware that anyone else was reading it. :) Since there is interest here, I post the last version, dated 20 December 2005. I assume that some things have changed since then. -- Thomas Hood read-only root filesystem News ---- Last updated: 20 December 2005 * sysvinit is now more rorfs-friendly * hotplug is replaced by udev Introduction ------------ This file summarizes what has been done, what remains to be done, and what can be done locally to make Debian work correctly with a root filesystem that is mounted read-only. It is a work in progress. Please send corrections. Rationale --------- The effort to make Debian easier to use with a read-only root filesystem was discussed at some length on the debian-devel mailing list in the spring of 2003 in threads with the following subject headings: * ifupdown writes to /etc... a bug? * /run and read-only /etc * Nameserver-pushing mechanism * /run/, resolvconf and read-only root One might want to mount the root filesystem read-only if, e.g., * one's root filesystem is currently a cramfs * one wants to run from a root filesystem on a CD-ROM * one has multiple hosts that share a NFS-mounted root filesystem and one wants to minimize the number of symlinks that have to be set up on each machine * one wants to put /etc/ under version control * one wants the security benefit of a configuration directory that can't be changed (... unless the cracker can remount the filesystem read-write, of course ...) HOWTO ----- / * Choose an appropriate filesystem type * A read-only root filesystem doesn't need a journal, for example. * fsck * Needless to say, if the root filesystem needs to be fsck'ed then this should be done by the administrator before the filesystem is put into normal use mounted read-only. After that it shouldn't ever need fscking... in theory. * sysvinit * Make sure that neither the /fastboot nor the /forcefsck file exists, and don't use shutdown's "-f" or "-F" options. These options cause the so named files to be created in the root directory which prevent or force, respectively, fsck on boot. /dev/ Several programs manipulate the permissions and ownership of files in /dev/ . Some of those changes are not strictly needed (e.g., fixing the permissions of /dev/log, /dev/xconsole and /dec/initctrl) and the rest can be ignored on systems with limited physical access (e.g., changing the permissions of /dev/cdrom). If only trusted persons can log in to the console then you can use a read-only /dev/. Changing the permissions of ttys and pseudo ttys is a security measure required on multi user systems. For pseudo-ttys you can use the devptsfs. For ttys, some other solution is required. If you have a 2.6 kernel then you can put /dev/ on a tmpfs and use udev. If you have a 2.4 kernel then you can use devfs. Either of the latter is a complete solution to the problem. /tmp/ Many programs write temporary files to /tmp/ . Therefore, if the root filesystem is to be read-only then /tmp/ has to be a separate, writable, filesystem. One may choose to make /tmp/ either a disk filesystem or a tmpfs filesystem. /etc/ The remaining problem is that if / is mounted read-only then no program can write to files in /etc/ . Variable files must be stored elsewhere. (In the present context, "variable" information is information that changes during the normal operation of a system, not just when the system is administered. It is the same sense of 'variable' as is used in the Linux Filesystem Hierarchy Standard (FHS).) Among the files in /etc/ are the password and shadow password files. These files can be regarded as static for the purposes of normal use. If one wants to update these files dynamically on a ROR system then he could consider using something like LDAP. Here is how to deal with other packages which are known to write variable files to /etc/ . * bind * Put the db files for any zones you are master for in /etc/bind/ (perhaps even in a subdirectory structure depending on complexity); specify the full pathnames to these files in the named.conf file. Any zones you are secondary for should be configured in named.conf with simple filenames (no path); these files will then be stored by named in its working directory, /var/cache/bind/ . Ditto for any zones that are updated via DHCP. * hotplug * See TODO section * ifupdown * Make /etc/network/ifstate a symlink to a writable location such as /dev/shm/network/ifstate. Releases of the ifupdown package of version 0.6.4-4.10 or later create this symlink for you on installation. * libc6 (/etc/resolv.conf) * Install the resolvconf package version 1.8 or later and configure it as described below * resolvconf * Make sure that /etc/resolvconf/run is a symlink to /dev/shm/resolvconf/. * lvm * Use a recent lvm which doesn't egregiously write to files in /etc/lvm/ * mount * See TODO section * samba * Upgrade to the latest version available * Use the 'smb passwd file' option in smb.conf to put the smbpasswd file outside /etc/ , or use tdbsam instead of smbpasswd. * suck * See TODO list * sysvinit * See TODO list * util-linux * See TODO list TODO ---- It would be better if the standard Debian system made it easier to mount the root filesystem read-only. The main difficulty at present is presented by base programs that store variable files under /etc/. Those programs fall into two classes: first, programs that have to write to files before network filesystems are mounted; second, those that do not have to write to files before network filesystems are mounted. There should be little difficulty in changing the programs of the "late" class to store their variable files under /var/. The programs of the "early" class do present a difficulty because on some systems /var/ is mounted across a network; hence the programs need to write files somewhere but can write neither to /etc/ (which is mounted read-only) nor to /var/ (which isn't mounted yet) nor to /tmp/ (which programs may not use to store information across program invocations). The proposed solution is that the programs of the "early" class continue to write to the current location in /etc/, but to do so in such a way that they will operate correctly if there is a symlink at this location. Packages containing programs of the "late" class: * suck # 158563, 189652, 206631: Please don't store variable files under /etc/ - OKed by maintainer, but nothing has been done about it * base-files, util-linux # 156489: Move adjtime out of /etc/ - OKed by maintainer, but nothing has been done about it - In the meantime, /etc/adjtime can be symlinked to a writable location such as /var/lib/hwclock/adjtime (the location mandated by FHS 2.2) Packages containing programs of the "early" class: * mount # 154438: mount should write to non-/proc/mount symlinks - LIMBO. A patch was sent upstream but the maintainer hasn't done anything about it in over a year. - Workaround #1: Make /etc/mtab a symlink to a writable location First you have to patch the mount program so that it works with a symlink. The patch is available at: http://panopticon.csustan.edu/thood/readonly-root.html - Workaround #2: Make /etc/mtab a symlink to /proc/mounts This can cause problems in some cases (e.g., with loop devices) because not all the information that mount normally stores in /etc/mtab is reported in /proc/mounts . Read the comment about symlinking /etc/mtab to /proc/mounts in mount(8). (As of this writing the comment is the last paragraph of the DESCRIPTION.) * See also the debian-devel mailing list thread entitled "Get rid of /etc/mtab ?" starting here: http://lists.debian.org/debian-devel/2002/debian-devel-200206/msg 01831.html and jumping to here: http://lists.debian.org/debian-devel/2002/debian-devel-200207/msg 00001.html An old summary of the problem: http://www.xss.co.at/sysinfo/mounts.html * See also the comment that the maintainer of the mount program, Andries Brouwer, made in a posting to the linux-kernel mailing list and which was covered in kernel-traffic #278: http://www.kerneltraffic.org/kernel-traffic/kt20041019_278.html#6 To support read-only root filesystem mounting we may want to enhance some of the initscripts. Some ideas from #186892 may be useful. I haven't looked into this deeply enough though. DONE ---- * alsa-utils # 106244: asound.state should be stored in /var/lib - DONE in 1.0.3-1 * cupsys # 187954: Move printcap.cups under /var/ - DONE in 1.1.19candidate4-1 * Writes to /etc/cups/certs - DONE in 1.1.15-1 * dhcpcd * Don't use files in /etc/dhcpc/ to pass information to scripts - DONE in 1.3.22pl4-8 * ifupdown * Writes ifstate to /etc/network/ - DONE in 0.6.4-4.10 and 0.6.4-4.10exp3. These versions of ifupdown store the ifstate file in /dev/shm/network/. * laptop-net * Do not use /etc/ for generating temporary files - DONE in 2.20-1 * linuxlogo # 292740: Please do not store files in /etc - DONE in 4.10-1 * ppp # 187756: Tolerate read-only /etc/ - DONE partially in 2.4.1.uus2-2. If resolvconf is installed then the package's /etc/ppp/ip-up.d/0000usepeerdns script won't write to /etc/resolv.conf - DONE finally in 2.4.2+20040428-6 -- pppd won't complain any more if /etc/ppp/resolv.conf isn't writable * pppconfig # 187810: Support read-only /etc/ - DONE in 2.2.0 # 187651: Make resolv.conf futzing optional - DONE in 2.2.0 * resolvconf * Manage resolver configuration so that /etc/resolv.conf can more easily be a symlink - DONE (http://packages.debian.org/resolvconf) * sysvinit, initscripts # 150355: [Handle motd as symlink] - DONE in 2.85-4 # 188087: Move ioctl.save out of /etc ? - DONE in 2.85-1 # 191041: Follow /etc/nologin symlink - DONE in 2.85-4 * Writes motd and nologin files to /etc/ - DONE in 2.86.ds1-8 Author Thomas Hood