Protecting the Root Filesystem on Ubuntu with Overlayroot

In certain situations, it is desirable to have a read-only root filesystem. This prevents any changes from occurring on the root filesystem that may alter system behavior, and it allows a simple reboot to restore a system to its pristine state. Examples of such applications include kiosks and embedded devices. Using overlayroot on Ubuntu makes creating a read-only root filesystem quick and easy.

Motivation

Let us imagine that we have an embedded Linux device that needs to run a particular program. The program does not need to store any data (except perhaps some logs), and we want to protect the system against any changes. If the program or any system processes make filesystem modifications, we want to toss them out and return to the original state. We want a robust system that will run our program, but be restored to it’s ‘factory’ state with a power-cycle.

Background

Overlayroot is a package for Ubuntu which utilizes OverlayFS, a union filesystem implementation. OverlayFS presents a unified view of two different filesystems; the presented filesystem is the result of overlaying one filesystem over another.

In OverlayFS, there is an ‘upper’ filesystem and a ‘lower’ filesystem. If a particular object exists in both the upper filesystem and the lower filesystem, the object from the upper filesystem is presented, and the object from the lower filesystem is hidden. If the object is a directory, the contents of the directory on the upper and lower filesystems are merged and presented.

With overlayroot, the lower filesystem is a read-only mount of the root filesystem, and the upper filesystem is a read-write mount of another block device. That block device can be tmpfs, a standard block device, or an encrypted block device (à la dmcrypt).

All changes made on top of the root filesystem are stored elsewhere and do not affect the root filesystem. Depending on the block device chosen, those changes can persist across reboots. While the root filesystem will not be affected, the view presented by OverlayFS will include any changes stored in the upper filesystem.

Situation

For our embedded Linux device, we are not interested in preserving any changes to the root filesystem. Any data that we want to preserve will be stored on a separate filesystem dedicated to data storage.

Here is our filesystem structure:

  • /dev/sda1 on /
  • /dev/sda2 on /data

We want to mount / using overlayroot so that we have a read-write filesystem available but not persist any changes to /, and we want to mount /data normally so that our program can write out and persist log files.

Solution

Overlayroot has been available since Ubuntu 12.10, and has been back-ported to 12.04 LTS. It is quick to install:

apt-get install overlayroot

The configuration file is stored at /etc/overlayroot.conf, and contains a wealth of in-line documention.

The only item to change is the overlayroot variable. By default, it is blank:

overlayroot=""

Start Simple

Since we want to use tmpfs mode for overlayroot, we set the variable accordingly.

overlayroot="tmpfs"

The other modes (specifying a device, or crypt) are documented in overlayroot.conf, with some nice diagrams on the post introducing overlayroot.

Add Swap

By default, overlayroot disables swap. This can be re-enabled by providing another option to the configuration:

overlayroot="tmpfs:swap=1"

(The default value for swap is 0).

Don’t Recurse

By default, overlayroot will mount all filesystems under / in the specified mode. This can be prevented by adding another option to the configuration:

overlayroot="tmpfs:swap=1,recurse=0"

Note that swap=1 and recurse=0 are separated by a comma, not a colon.

(The default value for recurse is 1).

This will prevent overlayroot from overlaying a read-write tmpfs on top of a read-only /data filesystem. All of / will be protected from any modifications, except /data, which is what we want.

The Result

After making changes to overlayroot.conf and rebooting, the root filesystem should now be mounted as a read-write tmpfs overlaying the read-only / filesystem.

Running mount, we should see something like:

overlayroot on / type overlayfs (rw,lowerdir=/media/root-ro/,upperdir=/media/root-rw)
proc on /proc type proc (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
none on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/fuse/connections type fusectl (rw)
devtmpfs on /dev type devtmpfs (rw,mode=0755)
none on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
none on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /media/root-ro type ext4 (ro)
tmpfs-root on /media/root-rw type tmpfs (rw,relatime)
/dev/sda2 on /data type ext4 (rw)

Note how the root filesystem is of type overlayfs with specified upper and lower filesystems that correspond to the read-write tmpfs and read-only mounts listed.

Disabling Overlayroot

Once overlayroot is enabled, it is no longer possible to make changes to the root filesystem. This introduces problems if we legitimately need to make changes (such as for updates, tweaks, etc.). Fortunately, we can override any overlayroot configuration by passing overlayroot=disabled to the kernel at boot. This can be done as a one-off operation as needed, or can be set up as an alternate boot configuration in a boot loader such as GRUB.

For example, with GRUB2, something like the following could be used:

menuentry 'Ubuntu, with Linux 3.5.0-54-generic (Writable)' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    gfxmode $linux_gfx_mode
    insmod gzio
    insmod part_msdos
    insmod ext2
    set root='(hd0,msdos1)'
    search --no-floppy --fs-uuid --set=root 28adfe9d-c122-479a-ab81-de57d16516dc
    linux   /vmlinuz-3.5.0-54-generic root=/dev/mapper/faramir-root ro overlayroot=disabled
    initrd  /initrd.img-3.5.0-54-generic
}

Conclusion

Overlayroot makes the process of mounting the root filesystem as read-only on Ubuntu very easy. Prior to the availability of overlayroot packages, custom scripts were added to the initramfs configuration. These scripts were often fragile, and not always compatible across versions of Ubuntu. With the availability of OverlayFS and overlayroot, creating robust kiosks and embedded Linux devices with rollback capabilities is now extremely easy.

Conversation
  • It’s also possible to make updates to the system by mounting the underlying filesystem directly, without disabling overlayroot. The overlayroot package contains a utility, overlayroot-chroot, which makes it very easy to execute commands against the read-write FS.

  • I was wondering if it was possible to specify lowerdir in /etc/overlayroot.conf ?
    I’d like to move my root-ro to another device.

  • I am trying something similar over a PXE NFS bootable environment. Did you have to do anything inside fstab to provide overlayfs definitions for the lower and upper directories? From your instructions it looks like overlayfs is able to determine the upper and lower automatically.

  • Mauro says:

    Hi,
    thanks for this article. I have a problem with Grub2. It lose default timeout, remain in the windows where you can choose the kernel until you press enter…. All ok with Grub1. Somebody else have this problem?

    Thanks Mauro

    • Denis says:

      Hi Mauro,
      you can solve this problem like this – open “/boot/grub/grub.cfg”, find “set timeout=30”, change the value.

  • Justin Roberts says:

    When i enable overlayroot, at boot up it displays the grub boot menu and i have to select Ubuntu. I’ve tried to change some settings in grub to prevent this, but it seems like no matter how i set it, it still does this. Any ideas?

  • Josh says:

    Thanks for the clear article! It was very helpful! But I have a question: do you know how to increase the size of tmpfs if I use that mode? I’m on a system with low RAM (and I can’t add more RAM), so the system locks up fairly quickly. Can we force overlayroot to use swap? I tried changing my fstab to include “tmpfs /tmp tmpfs size=4G 0 0”, but it didn’t seem to have any effect. Thanks!

  • Anonymous says:

    Not all is true, you can make changes to:
    /dev/sda1 on /media/root-ro type ext4 (ro)

    Without rebooting, just with a bind remount in rw.

    And you can set such new mount (rw) the new root by chrooting.

    So that is not any king of protection real root filesystem against changes maded by malintentioned applications (or troyans, etc)… or even users that gain root access.

    I say that since you did not talk about that vulnerability.

    A real way to do it is use a real READ only medium for that root… it implies a low level copy in Off-Line mode of a TEST state… and do a lot of tests.

    I succedded by mounting a file stored on a DVD-R in losetup mode and then using the mount point as your /media/root-ro (but not in Ubuntu), the rest just as you.

    The hard part (or not so hard) was doing a dd to clone real root partion to such file, then burn it on a DVD-R.

    The losetup way is to avoid DVD-R not having linux permisions.

    I had also tried the trick of putting the file on a SD (not microSD) with write lock on, but it gives me a lot of problems of crashes due to really slow SD speed (much slower than the DVD-R).

    The file is only 500MiB size (SD is 512MiB) and it is cached (by kernel, filesystem, etc, not by me) on RAM when readed from DVD-R but not when readed from SD… anyone knows why?

    So finally i got to the real working, fastest and top secured way… have that file on DVD-R and copy it to RAM as many LiveCDs (like SystemRescueCD) does, then no need to do anything extra, no even need to use Overlayroot layer anymore.

    My rootfs is in RAM in RW mode, at boot it is copied to RAM from a DVD-R… so voila, a booting system that can not be altered apon boots unless i change the DVD-R to another one.

    Now using that as lower layer and Overlayroot as top layer… i can make my users to boot their own modified version of the system, alter the rootfs (the fake one) and mantain the changes, but do not alter other users boot.

    That was done by putting a middle layer in a USB stick, DVD-R is lower layer, USB stick is the middle layer that has personalized boot for the user, and as a top layer an encrypted partition on the rack of disks (in a cluster configuration), one for each user.

    Overlayroot is really great if well combined with other tricks.

  • wang says:

    Hello.
    Thanks for the article
    I want to use overlayroot because my device often automatically powers off causing the system to crash.
    But I have a question to ask you, in the use of “tmpfs” option, the default use of half the physical memory, right?
    What happens if you write a file that exceeds this limit? throw away?

  • Comments are closed.