Manual for creating readonly-mountable root fs

Last modified: $Date: 2006-11-25 10:18:46 +0900 (Sat, 25 Nov 2006) $


TOMOYO Linux can report file accesses that were failed due to readonly filesystem. This manual describes how to create a readonly-mountable root fs on VMware using this functionality.

1. Assumption

1.1 Required resources

You need the following softwares and resources in addition to regular procedure of TOMOYO Linux. You don't need to burn ISO image to CD, for VMware can use ISO image instead of CD.

1.2 Partition layouts

In the production environment, root fs is mounted as read-only. For applications that need to write in the /tmp and a part of /var directories, I allocate /data partition for writable partition. The /tmp and a part of /var directories will be located on /data partition. This memo suppose the following partition layout.

VM environment name hostname partition layout
Compiler Environment compile /dev/sda1 ext3 /
Builder Environment build /dev/sda1 ext3 /data
/dev/sda2 ext3 /

You need to allocate /data partition for Build Environment more than twice larger than the size of / partition.

You need to prepare file transfer method (like scp, ftp) to transfer ISO image from VM environment to host environment.

2. Preparation

Do operations until just before Preparing Policy described in TOMOYO Linux Install manual (Simplified version).
But you need to compile kernel with the following options enabled. Since initrd-loop.img doesn't include insmod, compile them as built-in, not as modules.

If you want to use 2.4 series, choose the following options.
  • Block devices ---> <*> Loopback device support
  • Block devices ---> <*> RAM disk support
  • Block devices ---> [*] Initial RAM disk (initrd) support
  • File systems ---> <*> Ext3 journalling file system support
  • File systems ---> <*> ISO 9660 CDROM file system support
  • File systems ---> [*] SAKURA (Domain-Free Mandatory Access Control) support
  • File systems ---> [*]   Read-only filesystem error tracing support
  • File systems ---> <*> SYAORAN (Tamper-Proof Device Filesystem) support
  • SCSI support ---> <*> SCSI support
  • SCSI support ---> <*> SCSI disk support
  • SCSI support ---> <*> SCSI CD-ROM support
  • SCSI support ---> <*> SCSI generic support
  • SCSI support ---> SCSI low-level drivers ---> <*> BusLogic SCSI support
  • Fusion MPT device support ---> <*> Fusion MPT (base + ScsiHost) drivers
  • ATA/IDE/MFM/RLL support ---> <*> ATA/IDE/MFM/RLL support
  • ATA/IDE/MFM/RLL support ---> IDE, ATA and ATAPI Block devices ---> <*> Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
  • ATA/IDE/MFM/RLL support ---> IDE, ATA and ATAPI Block devices ---> <*> Include IDE/ATAPI CDROM support
  • ATA/IDE/MFM/RLL support ---> IDE, ATA and ATAPI Block devices ---> <*> SCSI emulation support
  • Network device support ---> [*] Network device support
  • Network device support ---> Ethernet (10 or 100Mbit) ---> [*] Ethernet (10 or 100Mbit)
  • Network device support ---> Ethernet (10 or 100Mbit) ---> [*] EISA, VLB, PCI and on board controllers
  • Network device support ---> Ethernet (10 or 100Mbit) ---> <*> AMD PCnet32 PCI support
If you want to use 2.6 series, choose the following options.
  • Device Drivers ---> Block devices ---> <*> Loopback device support
  • Device Drivers ---> Block devices ---> <*> RAM disk support
  • Device Drivers ---> Block devices ---> [*] Initial RAM disk (initrd) support
  • File systems ---> <*> Ext3 journalling file system support
  • File systems ---> CD-ROM/DVD Filesystems ---> <*> ISO 9660 CDROM file system support
  • File systems ---> [*] SAKURA (Domain-Free Mandatory Access Control) support
  • File systems ---> [*]   Read-only filesystem error tracing support
  • File systems ---> <*> SYAORAN (Tamper-Proof Device Filesystem) support
  • Device Drivers ---> SCSI device support ---> <*> SCSI disk support
  • Device Drivers ---> SCSI device support ---> <*> SCSI CDROM support
  • Device Drivers ---> SCSI device support ---> <*> SCSI generic support
  • Device Drivers ---> SCSI device support ---> SCSI low-level drivers ---> <*> BusLogic SCSI support
  • (2.6.12 and before) Device Drivers ---> Fusion MPT device support ---> <*> Fusion MPT (base + ScsiHost) drivers
  • (2.6.13 and after) Device Drivers ---> Fusion MPT device support ---> <*> Fusion MPT ScsiHost drivers for SPI
  • Device Drivers ---> ATA/ATAPI/MFM/RLL support ---> <*> ATA/ATAPI/MFM/RLL support
  • Device Drivers ---> ATA/ATAPI/MFM/RLL support ---> <*> Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
  • Device Drivers ---> ATA/ATAPI/MFM/RLL support ---> <*> Include IDE/ATAPI CDROM support
  • Device Drivers ---> ATA/ATAPI/MFM/RLL support ---> <*> SCSI emulation support
  • Device Drivers ---> Network device support ---> [*] Network device support
  • Device Drivers ---> Network device support ---> Ethernet (10 or 100Mbit) ---> [*] Ethernet (10 or 100Mbit)
  • Device Drivers ---> Network device support ---> Ethernet (10 or 100Mbit) ---> [*] EISA, VLB, PCI and on board controllers
  • Device Drivers ---> Network device support ---> Ethernet (10 or 100Mbit) ---> <*> AMD PCnet32 PCI support

3. Protecting device files

The system can't work if /dev directory is read-only, so you can use SYAORAN filesystem for /dev . You can use devfs or udev, but they can't prevent tampering with device files.

Do the following operation to create /.syaoran .

echo '#! /bin/sh' > /.syaoran
echo 'mount -n -t syaoran -o accept=/root/security/syaoran.conf none /dev' >> /.syaoran
echo 'exec /sbin/init "$@"' >> /.syaoran
chmod 700 /.syaoran

To mount this filesystem automatically before /sbin/init starts, add "init=/.syaoran" to the TOMOYO Linux's kernel command line. I recommend you to add "init=/.syaoran" to the boot loader's configuration file because it is a bother specifying every time.

Do the following operation to create initial /root/security/syaoran.conf that contains all entries.

mkdir -p /root/security
/root/ccstools/makesyaoranconf > /root/security/syaoran.conf

To forbid access other than /data partition, remove all /dev/sda* entries other than /dev/sda1 from /root/security/syaoran.conf .

This will work. But if you want to remove unnecessary entries in /root/security/syaoran.conf , see Protecting Device Files (Optional).

4. Relocating files to make root fs read-only

Since /etc/mtab becomes read-only, replace the file with a symbolic link to /proc/mounts .

ln -sf /proc/mounts /etc/mtab

Since /etc/adjtime becomes read-only, replace the file with a symbolic link to /dev/null .

ln -sf /dev/null /etc/adjtime

Modify the startup script not to remount / as read-write.

The following is for RedHat Linux 9 and Fedora Core 3.

sed -i 's:mount -n -o remount,rw /:/root/ccstools/remount_rootfs:' /etc/rc.d/rc.sysinit

The following is for Debian Sarge.

sed -i 's:#.*Remount.*:&\ngrep -q readonly /proc/cmdline \&\& rootmode=ro' /etc/init.d/checkroot.sh

Modify the startup script not to run fsck on /.

The following is for RedHat Linux 9.

sed -i 's:initlog -c "fsck -T -a $fsckoptions /":echo "Skipped":' /etc/rc.d/rc.sysinit

The following is for Fedora Core 3.

sed -i 's:fsck -T -a $rootdev $fsckoptions:echo Skipped:' /etc/rc.d/rc.sysinit

For Debian Sarge, update the <pass> field to 0 where <mount point> is / in /etc/fstab .

If the option "readonly" is given in the kernel commandline, remount_rootfs won't remount the root fs as read-write. And the system tries to boot with root fs mounted as read-only. But probably the system can't boot properly without any file relocation. Therefore, you will need to relocate files and directories that needs to be writable to writable partitions.

To know files and directories that needs to be writable, you can give a line "TRACE_READONLY=1" in /root/security/profile0.txt . With this line, the TOMOYO Linux kernel dumps pathnames of files and directories that write attempt failed due to readonly filesystem to syslog. Pick up lines that contains ReadOnly: in /var/log/messages , and decide which files and directories to relocate. The destination is /data partition, and refer from / partition using symbolic links. Note that not all errors caused by readonly filesystem are reported.

The following is an example that need to be relocated. This depends on distributions and applications installed in the Builder Environment.

At this point, make sure that you can do all operation you want to do on readonly mounted root fs without errors.

5. Boot loader Configuration

Extract stage2_eltorito, the bootloader for ISO image, from the grub package if the Compiler Environment doesn't have it. The following is a step to extract from grub package for Fedora Core 3. If the Compiler Environment has stage2_eltorito, copy it to /boot/grub/ .

cd /tmp
wget ftp://rpmfind.net/linux/fedora/core/3/i386/os/Fedora/RPMS/grub-0.95-3.i386.rpm
rpm2cpio < grub-0.95-3.i386.rpm | cpio -idm '*/stage2_eltorito'
mv usr/share/grub/i386-redhat/stage2_eltorito /boot/grub/

Boot the Builder Environment using KNOPPIX's ISO image.

Copy the stage2_eltorito from the Compiler Environment to /mnt/sda1/IMAGE/boot/grub/ in the Building Environment. Copy the kernel and initrd-loop.img , too. Replace the part vmlinuz-2.4.32-ccs with the version you are using.

mount /dev/sda1 /mnt/sda1
mkdir -p /mnt/sda1/IMAGE/boot/grub
scp -p compile:/boot/grub/stage2_eltorito /mnt/sda1/IMAGE/boot/grub/
scp -p compile:/boot/grub/splash.xpm.gz /mnt/sda1/IMAGE/boot/grub/
scp -p compile:/boot/vmlinuz-2.4.32-ccs /mnt/sda1/IMAGE/vmlinuz
scp -p compile:/root/ccstools/initrd-loop.img /mnt/sda1/IMAGE/
cat > /mnt/sda1/IMAGE/boot/grub/grub.conf << EOF
default=0
timeout=10
splashimage=/boot/grub/splash.xpm.gz
title SAKURA Linux
kernel /vmlinuz fastboot init=/.syaoran root=/dev/scd0 hdc=ide-scsi
initrd /initrd-loop.img
EOF
ln -s grub.conf /mnt/sda1/IMAGE/boot/grub/menu.lst

6. Creating ISO image

Boot the Builder Environment with KNOPPIX's ISO image.

Create a loopback mount image file and copy the content of / partition. Determine the size of the loopback image using the output of "df /dev/sda2" command. The following example creates the loopback image of 640 MB.

mount /dev/sda1 /mnt/sda1
mount -o ro /dev/sda2 /mnt/sda2
touch /mnt/sda1/IMAGE/rootimg
mke2fs -j -F -m 0 -b 1024 /mnt/sda1/IMAGE/rootimg 655360
mount -o loop /mnt/sda1/IMAGE/rootimg /mnt/sda1/
cp -a /mnt/sda2/* /mnt/sda1/
sync
umount -d /mnt/sda1/
e2fsck -f /mnt/sda1/IMAGE/rootimg

If copy finished successfully, convert into ISO image file.

cd /mnt/sda1/IMAGE/
mkisofs -R -o /mnt/sda1/image.iso -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table .

Transmit /mnt/sda1/image.iso to host environment. Don't forget to remove from /data partition after transmission.


Return to index