Introduction
Ubuntu boots using the GRUB boot
loader. GRUB has all sorts of fun powers including the ability to
pull up a root shell without any authentication. Sometimes, though,
you don't want root to be so trivially accessible to your drunk
frenemies and script kiddie siblings. This is a perfectly normal
sentiment.
In this post, I will explain how to
lock down the GRUB 2 boot menu used in Ubuntu. This will not protect
your data if your computer is stolen, if the CIA is out to get you,
or in the face of another persistent attack. It will, however, make
it a lot harder for passersby to ruin your digital life.
GRUB 2 on Ubuntu is a bit of a mess at
the moment, and locking down GRUB is a good time to also do some
cleaning up. The second part of the post is about just that.
Disclaimer
The procedure I describe worked for me,
but it might not work for you. I am not your sysadmin, and I am not
responsible for what you do with the computers to which you have
access. I cannot be responsible for any data loss resulting from
following these instructions. ALWAYS MAKE A BACKUP! I used Ubuntu
11.10 (Oneiric Ocelot); other versions may differ.
Background
This section explains why configuring
GRUB 2 on Ubuntu is such a pain. If you're just skimming through, the
interesting info starts in the next section.
Since Ubuntu 9.10 (Karmic Koala),
Ubuntu has used GRUB 2 as the bootloader rather than classic GRUB.
The difference in configuring the two is illustrated in the following
diagram:
In words: In classic GRUB, the user
wrote a menu.lst file that controlled GRUB. In GRUB 2, the user
modifies a series of configuration files and scripts, the update-grub
script takes these files and some hard-coded magic, and spits out a
grub.cfg configuration file.
Using eight (or more) configuration
files has some advantages over using just one. For example, 8 is
clearly a bigger and better number than 1. On the downside, the
number of files involved makes it difficult to find the setting you
want, and sometimes the setting you want is controlled by
hard-coded scripting magic instead of a line in a configuration file.
Password-protecting GRUB is an example of just such functionality.
The amusingly unhelpful “Security” section of Ubuntu's GRUB 2 documentation says that there's
no way to lock down GRUB. This is actually not true; it's possible to
have coarse-grained control over what is locked in GRUB through the
standard configuration files. Fine-grained control currently requires
a slightly more unorthodox approach. I will cover both options.
Files
First, a list of all the useful files:
/etc/default/grub
The main, user-facing configuration
file. All the options you would ever want to change as an end user
should be in this file. In fact, they are not.
/etc/grub.d/##_<description>
These scripts generate the entries that
show up in the GRUB 2 boot menu. You're really only meant to edit the
one called 40_custom.
/boot/grub/grub.cfg
This is the autogenerated GRUB 2
configuration. You should never touch this file, but editing it is
the only way to get GRUB to really do what you want.
/usr/sbin/update-grub
This is a very thin wrapper around
grub-mkconfig. It is called to regenerate grub.cfg.
Locking down GRUB
This section is based on some Googling,
the GRUB info pages, and trial
and error. Before you change anything, it's a good idea to create
copies of the files so that it's easy to revert back. You will need
root access to complete these steps.
1. Disable generation of recovery mode menu entries (optional)
In /etc/default/grub, uncomment the GRUB_DISABLE_RECOVERY=”true” line. Recovery mode entries in the GRUB menu allow access to a root shell. Uncommenting this line will make the recovery mode entries go away. Of course, you might want a recovery mode entry in case you need it, so you can skip this step. However, if you do skip this step, you will need to resort to the unorthodox methods in step 4 to lock GRUB.
2. Set superuser name and password
In /etc/grub.d/40_custom, add these two lines at the end:
1. Disable generation of recovery mode menu entries (optional)
In /etc/default/grub, uncomment the GRUB_DISABLE_RECOVERY=”true” line. Recovery mode entries in the GRUB menu allow access to a root shell. Uncommenting this line will make the recovery mode entries go away. Of course, you might want a recovery mode entry in case you need it, so you can skip this step. However, if you do skip this step, you will need to resort to the unorthodox methods in step 4 to lock GRUB.
2. Set superuser name and password
In /etc/grub.d/40_custom, add these two lines at the end:
set superusers="root"
password_pbkdf2 root
grub.pbkdf2.sha512.10000.<biglongstring>
As with all shell scripts, make sure
the file ends with a blank line.
The first line sets the name of the
superuser to “root”. The second line contains the hash of the
root user's password. To obtain this, run $> grub-mkpasswd-pbkdf2
on the command line, and type the desired password. Then paste the
output of the command into 40_custom.
This change, once passed to grub.cfg, will password-protect command-line
access and the ability to edit menu items from within GRUB itself. If you
skipped step 1, recovery mode entries will still allow unfettered
access to a root shell.
3. Run update-grub
3. Run update-grub
$> sudo update-grub
This will generate a new grub.cfg file,
taking into account the changes in the previous two steps.
If you completed step 1, you now have
coarse-grained password-protection: GRUB will allow you to boot all
installed Linux kernels as well as any other OS you have on your hard
drive without a password. There are no recovery mode menu items, and
you need a password to get into a shell from GRUB. You can finish
here or go on to the next step.
4. Hack grub.cfg (optional)
If you want fine-grained control over what is password-protected in GRUB or you skipped step 1, you will need to hack grub.cfg. Some system updates will regenerate grub.cfg for you, so you will need to repeat this step after every update.
4. Hack grub.cfg (optional)
If you want fine-grained control over what is password-protected in GRUB or you skipped step 1, you will need to hack grub.cfg. Some system updates will regenerate grub.cfg for you, so you will need to repeat this step after every update.
The first thing to do is find the
recovery mode entry and other entires you want to password-protect in
grub.cfg, and add the --user "" option:
menuentry 'Ubuntu, with Linux <some
version> (recovery mode)' --users "" --class ubuntu ...
This tells GRUB that by default, no
users are allowed to access this entry; the root password will be
required to run it.
If you have more than one Linux kernels
installed and you skipped step 1, update-grub will create recovery
mode entries for each kernel. These show up in a GRUB sub-menu called
“Previous Linux versions.” You will see
submenu "Previous Linux versions"
{...}
in grub.cfg. For some reason, adding
the --user "" option does not actually password-protect the
recovery modes of previous Linux kernels. The solution is to either
uninstall all but one kernel, or just comment out the entries in
grub.cfg. When commenting out, make sure to comment out the right
number of closing curly braces. You can also comment out the entire
“Previous Linux versions” submenu. Unfortunately there is no
obvious way to keep this submenu from being created in the first
place.
Now just save grub.cfg, and reboot into
GRUB to check that it all worked. I have no idea on how GRUB will
respond to a malformed grub.cfg file, so be very careful when editing
it.
Cleaning up GRUB
Since you're already messing around
with all the configuration files, now is a good time to clean up the
GRUB menu. Here are three ideas.
Remove old kernel versions
Unless you're a developer, there's really no reason to have the ability to boot previous Linux kernels. In grub.cfg, comment out the bit that starts with
Remove old kernel versions
Unless you're a developer, there's really no reason to have the ability to boot previous Linux kernels. In grub.cfg, comment out the bit that starts with
submenu "Previous Linux versions"
{
Again, make sure to comment out the
right number of closing curly braces.Remove other operating systems
You might have other operating systems on your computer that you don't plan to boot using GRUB. For example, you might have followed this guide to triple-boot a Mac. You could comment these out in grub.cfg, but the better option is to use /etc/grub.d/30_os-prober. You could rename the file to something like no_touchy_30_os-prober, take away the execute privileges with chmod, or move it somewhere else. All three options will keep other operating systems from showing up in the GRUB menu. Note that this is an all-or-nothing step; there's no way to choose which other OSes to list and which ones to ignore.
Decrease GRUB timeout
When you're booting up, there's no reason to sit at the GRUB menu for half a minute. In /etc/default/grub, change the GRUB_TIMEOUT value to something like 5 or 1 or however many seconds you like. If you need to, you can always stop the timer in the GRUB menu by hitting an arrow key.
Conclusion
Out of the box, GRUB 2 on Ubuntu can be unwieldy and a bit messy. There are many configuration files in various places that control GRUB, and it can be difficult to keep track of them. It's possible to lock down GRUB and clean up the GRUB menu just by using the configuration files, but to really control GRUB, you need to break the configuration interface.
Out of the box, GRUB 2 on Ubuntu can be unwieldy and a bit messy. There are many configuration files in various places that control GRUB, and it can be difficult to keep track of them. It's possible to lock down GRUB and clean up the GRUB menu just by using the configuration files, but to really control GRUB, you need to break the configuration interface.
I'm not sure how much of the
configuration process is designed by the Ubuntu developers, and how
much is designed by the GRUB developers. I can see that the
developers are trying to organize the configuration process to make
it more user-friendly, but I don't think it's working as well as it
could. Admittedly, GRUB 2 is still in active development, but I'm not
convinced that it's even possible to extend the current configuration
infrastructure to provide both simplicity for normal users and
flexibility for power users.