3

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?

2 Answers2

3

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.

muru
  • 197,895
  • 55
  • 485
  • 740
  • Well, that's why a posted my question... The community documentation You have quoted is definitely not up to date. Content of file /etc/grub.d/10_linux in Ubuntu 14.04 is different than stated there, so the instruction is useless. –  Jul 18 '14 at 19:51
  • 1
    @MikołajBartnicki since you linked to wrong page, it seemed to me you hadn't read the page with any seriousness. – muru Jul 19 '14 at 00:57
  • @MikołajBartnicki here, I updated to reflect changes in the grub.d files. – muru Jul 19 '14 at 03:36
  • You are right, I pasted the wrong URL! I have just corrected it, thanks for pointing out. Now I am going to try your updated instruction. No response from me within an hour definitely means that my PC exploded and we are both burning. –  Jul 19 '14 at 11:27
  • @MikołajBartnicki if it does work, could you update the community wiki? – muru Jul 19 '14 at 11:31
  • It does not work. I tried the '--unrestricted' option in various places, but the only result I get is unbootable menu entry. I withdrew the '-1' since You updated your answer, but my problem is still not resolved - please read the bold part of my question. After all, it looks like GRUB2 is a piece of turd - unfinished and undocumented software. –  Jul 19 '14 at 12:19
0

Configure superusers. To do this, for example, add the following lines to /etc/grub.d/00_header:

# Support user protection on entries
cat << EOF
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.8E51188BE7DF732DDF102C918DEC152087558E04DA843B4A74C3EA8374BAB1ECA493399D62E3F2779F55C5BE2E8B65B8636113A99C09BFB892DB64626337904C.3016474FE6B420DBE6371B41D9BE8471B135CDF4BE674AC1265D3BA123CD9E459E960AEC199AB8C7C1C1A6BAF45314C64591E85E404AB54F4777E032A50CC731
EOF

Update the encrypted password using the output of grub-mkpasswd-pbkdf2 command. In our example, what you need to change is the following information:

grub.pbkdf2.sha512.10000.8E51188BE7DF732DDF102C918DEC152087558E04DA843B4A74C3EA8374BAB1ECA493399D62E3F2779F55C5BE2E8B65B8636113A99C09BFB892DB64626337904C.3016474FE6B420DBE6371B41D9BE8471B135CDF4BE674AC1265D3BA123CD9E459E960AEC199AB8C7C1C1A6BAF45314C64591E85E404AB54F4777E032A50CC731

Edit the /etc/grub.d/10_linux file and look for line 129 (in Ubuntu 14.04 LTS). In its pristine form, it should look like the following:

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

Here, add the --unrestricted option after the CLASS variable to complete the configuration line:

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

Rebuild /boot/grub/grub.cfg. To do this you run the sudo update-grub command.

Reboot the system and try.

Now you should have a configuration where:

  • The main Ubuntu operating system entry will boot up normally but no one except the superusers will be able to edit the related entry in the list.

  • Only the superusers will be able to boot and edit all other entries in the list.


See also:

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sec-GRUB_2_Password_Protection.html