How to set up GRUB2 password in an easy way?

I need to setup password for GRUB2 on Ubuntu 14.04 LTS amd64. The setup I am trying to reach is to have [e]dit and [c]onsole options protected by password, but booting of operating system entries (Ubuntu, Windows) unprotected.

I have studied Grub2/Passwords (it is outdated, quite chaotic and hardly readable by the way) and it seems that I need to set up the superuser password and add --unrestricted option to menu entries. OK, but where exactly do I have add this --unrestricted option?

If in the /boot/grub/grub.cfg then it is not the most clever idea, because this file is overwritten each time grub-update is run. So this is not an option for me, because - let's assume that - I like to change GRUB background image twice a week. Moreover, /boot/grub/grub.cfg readability is far from perfect; it is still not obvious where to put the --unrestricted option.

If in the menu entry files in the/etc/grub.d/*, then it is even worse than editing /boot/grub/grub.cfg. Those files are quite a mess in the terms of readability so editing them is all the more difficult.

Is there any clean and easy method of setting GRUB2 password up as I described? Maybe some brilliant documentation other than the one I linked in this post?


Solution 1:

According to the section on protecting entries:

There is currently no automated method of adding users or designating menu items to be protected. The user must manually edit the GRUB 2 scripts. The GRUB 2 menu is a compilation of the inputs of several scripts. The /etc/grub.d/10_linux file is responsible for adding the default Ubuntu OS to the GRUB 2 menu. [...] The majority of these sections are devoted to editing the default scripts located in the /etc/grub.d/ folder.

And in the next section:

The GRUB 2 menu includes selections for operating systems other than the default Ubuntu OS via the /etc/grub.d/30_os-prober script. [...] This would include other Ubuntu and Linux installations, Windows, etc.

The 30_os-prober script looks for specific types of operating systems. The user can make the changes for all of the OS's via a single command, or individually by OS type as documented below.

So, it seems you will have to edit the files in /etc/grub.d/. At least for adding a superuser, you needn't edit one of those files, but can create a new file:

The superuser/user information and password do not have to be contained in the /etc/grub.d/00_header file. The information can be placed in any /etc/grub.d file as long as that file is incorporated into grub.cfg. The user may prefer to enter this data into a custom file, such as /etc/grub.d/40_custom so it is not overwritten should the Grub package be updated. If placing the information in a custom file, do not include the "cat << EOF" and "EOF" lines as the content is automatically added from these files.

These paragraphs remain relevant until the official GRUB documentation says otherwise:

The grub-mkconfig program does not yet have built-in support for generating configuration files with authentication.

(Whatever that's supposed to mean.)


Up to Ubuntu 12.04

Here are the outdated instructions for protecting menu entries:

In /etc/grub.d/10_linux, find the following line:

printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"

Add --users '' :

printf "menuentry '${title}' ${CLASS} --users '' {\n" "${os}" "${version}"

For all the entries in 30_os-prober:

sudo sed 's/--class os /--class os --users /' -i /etc/grub.d/30_os-prober

Ubuntu Packages doesn't list Ubuntu 12.10, so I am not sure if 12.10 uses the old method or the new one.

Ubuntu 13.04 and later

Now, the 10_linux file uses echo instead of printf:

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

And the 30_os-prober file uses cat and heredocs:

# The minix entry
cat << EOF
menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" {
EOF
# The hurd entry
cat << EOF
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
EOF

So you can stick the --user "" part somewhere before the menuentry ends (before the brace opens).

Remember to backup any files you modify, and run update-grub after modification.