Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save TheHarold/7327425e67c0a3674c6b7c0d0f37e419 to your computer and use it in GitHub Desktop.
Save TheHarold/7327425e67c0a3674c6b7c0d0f37e419 to your computer and use it in GitHub Desktop.
Password protect GRUB Menu editing only, without forcing to enter credentials to load bootloader menu items

Background
The requirement was to secure the bootloader without needing to share the credentials with the end user to be able to boot into the operating system.

Securing Bootloader is required to

i. Preventing Access to Single User Mode — If attackers can boot the system into single user mode, they are logged in automatically as root without being prompted for the root password.

ii. Preventing Access to the GRUB Console — If the machine uses GRUB as its boot loader, an attacker can use the use the GRUB editor interface to change its configuration or to gather information using the cat command.

iii Preventing Access to Non-Secure Operating Systems — If it is a dual-boot system, an attacker can select at boot time an operating system, such as DOS, which ignores access controls and file permissions.

Challenge
After going through tons of documents online, I couldn't find clear step by step documentation on how to achive this but all of them very well explained how to set password to get through to the bootloader and it used to prompt for credentials to get to the bootloader.

Pre-requisites

  • Although the following was done on Ubunto 20.04 LTS but it should work on any system with Grub version 1.9 or above (To check your Grub version try, grub-install --version)
    With Grub 2, there is no /boot/grub/menu.lst. It has been replaced by /boot/grub/grub.cfg. grub.cfg is overwritten by certain Grub 2 package updates, whenever a kernel is added or removed, or when the user runs update-grub.

  • Although not a must but SSH access to the host would be ideal

Step by step guide

  1. Generate Encrypted Password
# grub-mkpasswd-pbkdf2
Enter password: 
Reenter password: 
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.380AD91E6C36BB4018B5CABDAFF5CABC52A16B6EFF503B6BB2E21199C006C526AEE3A2FF8CF41F9A07AEFB1E8E2275ABB44C41B1429B9C5D509786E2B57A51DA.989F1E9FAC061899E1BB8CB38D2119B26E6CE79A5CBB637E5A611AE099EBBF7CD9BCF1A3EC516CE0E4AD007B7DF8E679220BC845E07E440F134DED2537081F54

This command converts your desired password into a very long alphanumeric hash. Keep this handy from grub.pbkdf2 onwards for step 2.

  1. Set the Password on GRUB2 main Configuration File
# cp /etc/grub.d/40_custom /etc/grub.d/40_custom.old
# echo 'set superusers="admin" # You can use any username you like' >> /etc/grub.d/40_custom
# Paste the generated PBKDF2 encrypted password from step 1 into the below command.
# echo 'password_pbkdf2 admin grub.pbkdf2.sha512.10000.380AD91E6C36BB4018B5CABDAFF5CABC52A16B6EFF503B6BB2E21199C006C526AEE3A2FF8CF41F9A07AEFB1E8E2275ABB44C41B1429B9C5D509786E2B57A51DA.989F1E9FAC061899E1BB8CB38D2119B26E6CE79A5CBB637E5A611AE099EBBF7CD9BCF1A3EC516CE0E4AD007B7DF8E679220BC845E07E440F134DED2537081F54' >> /etc/grub.d/40_custom
  1. To prevent supervisor password every time you want to boot any menu item
    Carefully edit the 'linux_entry ()' function in '/etc/grub/10_linux' so that the 'echo "menuentry ..."' lines include --unrestricted by default:
# cp /etc/grub.d/10_linux /etc/grub.d/10_linux.old
# vim /etc/grub.d/10_linux

The modified function should look something like below to include --unrestricted flag. There are only two places to include this.

[...] echo "menuentry '$(echo "$title" | grub_quote)' --unrestricted ${CLASS} $menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
echo "menuentry '$(echo "$os" | grub_quote)' --unrestricted ${CLASS} $menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
[...]

Make a backup of this file as it will be overwritten by grub updates. This way all Linux kernels detected by the script will be available to all users without identifying to grub via username / password.

  1. Update Grub
# update-grub

You may now reboot the system to test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment