Saturday, October 06, 2012

Light-weight security, Grub2 password setup problems 1.99 vs 2.00

I believe I'm not the only one who thinks that use case oriented Grub2 documentation is hard to find, and a lot of the documentation is obsolete or wrong. My main cause for writing this blog post is a currently unanswered question regarding 2.00, but meanwhile it seems months have passed and still most 1.99 documentation is wrong as well, which might be interesting to some.

The aim is to prevent grub entries from being edited, while not restricting actual booting. This protection is meant for computers not having any confidential stuff, but just wanting to do some light weight security with the assumption that the computer isn't physically opened.

Common setup

You will obviously want to disable any automatically generated root access giving entries, by for example uncommenting GRUB_DISABLE_RECOVERY="true" in /etc/default/grub on Debian or Ubuntu. Also you would disable allowing any external boot devices to be used in BIOS/EFI/coreboot, which you would also have protected with a password. And that often means you need to also disable USB legacy support, since some BIOSes tend to offer all USB devices as bootable without password otherwise (note that I guess that could also cause problems accessing setup on desktop computers if your only keyboard is USB).

1.99

So to first fix the false instructions in various places - no, setting the superuser in 00_header as instructed is not enough. It might be, but does not apply if eg. old kernels are put into submenu (Ubuntu bug 718670, Fedora bug 836259). The protection from editing does not apply there. And if you remove all but one kernel so that there is no submenu, a submenu will be automatically created when there is a new kernel installed via security updates. I didn't need the submenu feature anyway, so I used to comment out the following lines in /etc/grub.d/10_linux:

  #if [ "$list" ] && ! $in_submenu; then
    #echo "submenu \"Previous Linux versions\" {"
    #in_submenu=:
  #fi
...
#if $in_submenu; then
#  echo "}"
#fi

I hope that was useful. I can imagine it causing a couple of family battles if the commonly instructed setup was the only protection used and there's for example a case of two computer savvy siblings that are eager to get to each others' computers...

2.00 & The Question

The problem with 2.00 is that the superusers setup yields a non-bootable system, ie. password is required for booting. But Google wasn't smiling at me today! Terrible. Can you help me (and others) with 2.00? The aim would be to have a 1.99-like setup where superuser password protects all entries from editing, but booting is fine without any passwords.

Update: Thanks, problem solved, see comments! Find the following line in /etc/grub.d/10_linux:

      echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"

And add --unrestricted there. Don't mix the line with the another menuentry line two lines earlier. The submenu problem doesn't exist anymore in 2.00.

2 comments:

Timo Juhani Lindfors said...

I think the grub.cfg syntax is pretty well explained in

http://www.gnu.org/software/grub/manual/grub.html#Security

but I don't know what's the easiest way to deploy this if you don't want to write your grub.cfg from scratch.

TJ said...

The manual doesn't differentiate in a very explicit way how to control being able to execute an entry and being able to edit it, especially considering the default of allowing execution has changed. Earlier an explicit --users was needed to restrict executing an entry.

It seems though that the '--unrestricted' gives indeed an executing access to the given menuentry. So compared to 1.99, one needs to add that to each entry that is wanted to be allowed to be executed.

The /etc/grub.d/ scripts have also evolved since last time, but it was possible to add it there. Updating the blog post, thanks!