Securing the GRUB Menu
By setje on Oct 17, 2005
Background and problem:
Since the in-memory miniroot compressed binary glob is only around 46Mb in size we started copying it to our desktop and test machines as a sort of failsafe secondary system image that could be booted in case we hosed the root image. This allowed us to develop at a far more reckless pace than before as recovering a system, which in the past involved configuring and then performing a netboot. Having the failsafe archive allows me to bfu untested bits onto my laptop without having another system near-by or becoming nervous.
In the end it turns out that we liked having this stand-alone image on our test machines enough to make it part of the product. It contributes very directly to the serviceability of the system if something should go wrong.
However much in the same way that a CD or network boot can be used to mount a root filesystem, so can the failsafe archive. This of course (amongst other things) allows the etc/shadow file on that filesystem to be accessed and/or modified. This suggests that the failsafe menu entry needs to be secured in the same environments that require securing the systems firmware to avoid unauthorized removable media boots. In addition to that, the grub command line also offers full filesystem access, so it needs to be secured as well.
On Solaris the grub shell is currently being delivered as /boot/grub/bin/grub (Note: while that location is unstable at this point, it is unlikley to change until we have some sort of bootadm(1m) integration).
So to protect the failsafe entry as well as the command line by a password of my choosing I can do the following:
clubsix:~> /boot/grub/bin/grub GNU GRUB version 0.95 (640K lower / 3072K upper memory) [ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. ] grub> md5crypt Password: \*\*\*\*\*\*\*\* Encrypted: $1$1g5y41$HX2EHzvJIUbBda0m/txBq. grub> Control-C
Then I edit /boot/grub/menu.lst and add a password line like:
password --md5 $1$1g5y41$HX2EHzvJIUbBda0m/txBq.
I also add the lock command to the failsafe entry:
title Solaris failsafe lock root (hd0,1,a) kernel /boot/multiboot -B console=ttyb kernel/unix -s module /boot/x86.miniroot-safe
Now when the system is rebooted and drops into GRUB, only the default Solaris entry (there are no other entries on this system) can be booted. Bother the failsafe as well as access to command line requires hitting 'p' and entering the password. Any other entry that might compromise system security (for instance a service partition) should also be locked in the same manner.
While not ideal, such a hashed password could be deployed via jumpstart finish scripts.
Conclusion / Better Solution:
In an ideal world bootadm(1M) would implement an abstraction that allows the password to be set or manipulated. In an even more ideal world setting it would be tightly integrated with selecting a security model for the system via install and jumpstart.