I would like to make a RHEL system read-only. This is obviously not possible for the complete system. For example directories like /tmp en /var need write access. Why would I want this? There are various reasons:
  1. Security. It’s safe(r). Nobody can tamper with you’re system, unless they get root access. Getting root access is by itself pretty hard, but not impossible. I will add some simple tips to make it even harder to gain root access.
  2. Performance. Because most of the filesystem is readonly, there is no need for locking, making the IO system faster.
  3. Backup. Because the best part of the filesystem is readonly, that part needs to be back-ed up only once, making backup’s faster en smaller.
I will sum up the various things to make this work:
First, you need to think about you’re file system and partition layout. The following is needed at a minimum (make the size as needed):
  • Seperate /boot partition. This is mainly necessary if you’re going to put the rest into LVM, which we will.
  • A seperate LV for /
  • Seperate LV’s for /home/tmp, /var and swap. I also wanted to put /root into a seperate LV, but anaconda refused to do this.
Install the system and login with root. Next, make the following adjustments:
  • Add the noexec option to the mountoptions of the /tmp/var/bootswap and possibly /homefilesystems. This prevents the execution of executables on these filesystems, even if you have execute permission. If you want you’re users to be able to execute scripts from their home directory, don’t add this to the /home filesystem.
  • Add the ro option to the root filesystem. Don’t be surprised is you’ll end up with a writable root filesystem after reboot. More needs to be done.
  • Some files in /etc need write access, although imho they don’t belong there, because of this. These files are /etc/mtab and /etc/resolv.conf. mtab is more or less deprecated and /proc/mountsgives you the same and even more info. However, the system complains about not being able to write to it. /etc/resolv.conf must only be writeable is the system is on DHCP and under the control of NetworkManager. Most servers have a static ip stack and don’t need NetworkManager. Create a directory /vat/etc, move /etc/mtab and, if needed, /etc/resolv.conf to this directory and create symlinks to them from their old location in /etc.
  • Add the following two lines to the end of /etc/rc.d/rc.local:
umount /boot
mount -o remount,ro /
This will unmount /boot and remounts the root filesystem to readonly. This file is executed at the end of the boot procedure and will unmount the /boot filesystem and make the root filesystem readonly. The /boot filesystem is only needed during boot and maintenance.
  • As root, create the directory /root/bin and create 2 scripts, named mainton and maintoff inside it. Make sure these two scripts have mode 6000 on them. We put these scripts in /root/bin because this directory is only accessable by root and is present in the path of the root user. Pretty safe. The function of the mainton script is to change the system to “maintenance mode” by making the root filesystem writeable again and by mounting the boot filesystem on it. maintoff, as you would guess, reverts this again, putting the system into “safe” mode. The two scripts look like this:
/root/bin/mainton:
#!/bin/sh
mount -o remount,rw /
mount /boot
echo "System now in Maintenance Mode.."
exit 0
/root/bin/maintoff:
#!/bin/sh
if [ -d /boot/grub ]; then umount /boot; fi
mount -o remount,ro /
echo "System now in Safe Mode.."
exit 0
  • Add the /root/bin/maintoff script to /root/.bash_logout. This will put the system into safe mode implicetly when you logout, in case you forgot to do it explicetly.
Now, if maintenance is needed, simply execute mainton and everything is back to “normal”. After maintenace, don’t forget to put the system back into safe mode by executing maintoff. Depending on the function of the server, more stuff needs to be done. For example, if you install apache onto this system, the websites end up in /var/www. That’s a writeable filesystem and I don’t particularly like to have my website on that. Better move it to /web or something, but don’t forget to change the SELinux policies to reflect this. Some apps like to have themselves installed in /opt and want to have write access to some files in there. Find out what files need write access and move them to a location in /var, where they belong. Just use the same procedure as with /etc/mtab.
If this is a virtual filesystem, things get even better. Put all the readonly filesystems, /tmp, and swap on one virtual disk, /var and /home on another. save the virtual disk with the readonly filesystems as a template disk. Restoring the system is now simply copying the template and restoring the virtual disk with /var on it. Don’t forget to create  a new template after doing maintenance.
For backup purpose, only /var needs to be back-ed up. Doing backup’s and restores fast using snapshot technology is for another HOWTO post.