Debian

Protect GRUB with Password on Linux

Physical access to a Linux machine is game over unless the bootloader stops an attacker from dropping into single-user mode or booting their own kernel parameters. GRUB 2 has a built-in mechanism for this: define a superuser with a PBKDF2-hashed password, and optionally mark individual menu entries as password-protected. Done right, you can still boot your normal kernel without prompting anyone, but editing a menu entry or dropping to a rescue shell requires the password. Pair this with fail2ban on the network side for a layered defence.

Original content from computingforgeeks.com - post 83

This guide walks through the exact steps on Kali Linux Rolling 2026.1, Debian 13 (trixie), and Ubuntu 24.04 LTS. All three use the same GRUB 2.12 packaging and the same configuration files, so the commands are identical across distros. The trick that catches most people out is that GRUB treats a password as blanket protection by default, which makes the system prompt at every boot. We’ll cover how to avoid that.

Tested April 2026 on Kali Linux Rolling 2026.1 with GRUB 2.12-9+kali1 and kernel 6.18.12+kali-amd64

Step 1: Generate a PBKDF2 password hash

GRUB never stores plain passwords. Use the grub-mkpasswd-pbkdf2 helper to turn a clear-text password into a SHA-512 hash GRUB can embed in the config. Run it with sudo because it needs to read the GRUB keyring:

sudo grub-mkpasswd-pbkdf2

The command asks for the password twice, then spits out a long hash starting with grub.pbkdf2.sha512.10000.... Copy the full hash string, including the prefix:

Enter password:
Reenter password:
PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.CFF5695F5747C932DE7A8EC4905500C9924E6808F4AE5947516C06277AA380B182BBC6FA738577CAE46565563D23CA7E05E0F06116B268A1C85E61157316FBA5.5B06ED51B6D9EFFAB6ED23722944A9CA1A3116B04119D7A2709E89D3285C6898F6E24E10DF3988626F62C27361907AB527E9E0ABBC03CBEC4E084548639935E3

Never commit this hash to a public repo. It’s a one-way hash, but running it through a cracking tool with a weak source password is still cheap.

Step 2: Define a superuser in 40_custom

Rather than editing /boot/grub/grub.cfg directly (it gets regenerated on every kernel update), append to /etc/grub.d/40_custom. That file is the designated place for local additions and is read every time update-grub rebuilds the menu config:

sudo vi /etc/grub.d/40_custom

Add these two lines at the end, pasting the full hash from Step 1 after password_pbkdf2 admin:

set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.CFF56...35E3

You can use any username for the superuser. admin, grubadmin, or a real person’s name all work. Multiple superusers are allowed too: repeat the password_pbkdf2 line for each one and list the names space-separated inside set superusers=.

Step 3: Allow normal kernel boot without a password

By default, once you set a superuser, GRUB prompts for the password on every boot, including the default menu entry. That’s usually not what you want. The right behaviour is: boot the default kernel without a password, but require the password to edit entries or drop to the rescue shell. Add the --unrestricted flag to the kernel menu entries by editing /etc/grub.d/10_linux:

sudo vi /etc/grub.d/10_linux

Find the line that begins with CLASS= near the top of the file and append --unrestricted to the classes:

CLASS="--class gnu-linux --class gnu --class os --unrestricted"

Save and exit. The --unrestricted flag means normal boot entries no longer require a password, but editing them with e or opening a GRUB shell with c will still prompt for the superuser credentials. This is the combination most administrators actually want.

Step 4: Regenerate grub.cfg

Neither 40_custom nor 10_linux is read at boot. They’re inputs to update-grub, which rewrites the real /boot/grub/grub.cfg each time:

sudo update-grub

The command walks through every entry in /etc/grub.d/ and writes the final menu:

Generating grub configuration file ...
Found theme: /boot/grub/themes/kali/theme.txt
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-6.18.12+kali-amd64
Found initrd image: /boot/initrd.img-6.18.12+kali-amd64
Adding boot menu entry for UEFI Firmware Settings ...
done

Any warnings about os-prober or missing themes are harmless in this context.

Step 5: Verify the config embedded everything correctly

Before rebooting, read the generated grub.cfg and confirm the superuser block made it in, the password hash is present, and every kernel menu entry carries the --unrestricted marker:

sudo grep -E 'password_pbkdf2|superusers|unrestricted' /boot/grub/grub.cfg

Every kernel menu entry should carry --unrestricted, and the trailing lines should contain the superuser block:

menuentry 'Kali GNU/Linux' --class kali --class gnu-linux --class gnu --class os --unrestricted ...
  menuentry 'Kali GNU/Linux, with Linux 6.18.12+kali-amd64' --class kali --class gnu-linux --class gnu --class os --unrestricted ...
  menuentry 'Kali GNU/Linux, with Linux 6.18.12+kali-amd64 (recovery mode)' --class kali --class gnu-linux --class gnu --class os --unrestricted ...
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.CFF5695F5747C932DE7A8EC4905500C9...

If you don’t see all three lines (menu entries with --unrestricted, set superusers, and password_pbkdf2), something didn’t make it through. Re-check 10_linux and 40_custom, then rerun update-grub.

Step 6: Reboot and test

Reboot the system and watch what happens at the GRUB menu:

sudo reboot

You should see the normal GRUB menu, with the default entry selected, and the countdown starting. Let it boot and confirm everything works. Then reboot a second time and press e at the menu to try editing an entry. GRUB should now prompt for the superuser name and password. Enter admin and your password, and you’ll land in the edit view. Escape returns to the menu.

Locking specific entries instead of the global rule

The --unrestricted flag is applied per menu entry, so you can selectively lock some entries while leaving others open. Remove --unrestricted from a specific block in grub.cfg, and that block requires authentication before booting. You can also restrict by username with --users admin,ops at the start of a menu entry, which allows multiple accounts to boot the entry but blocks anyone else.

Since update-grub regenerates the file, you should make these per-entry tweaks in /etc/grub.d/40_custom by writing custom menuentry blocks rather than editing grub.cfg by hand.

Recovering when you forget the password

Physical access still wins. If you forget the GRUB password, boot from a Kali live USB or a rescue ISO, mount the root filesystem, and edit /etc/grub.d/40_custom to remove or replace the hash, then chroot into the mounted root and run update-grub. Reboot and the password is either gone or replaced. This is the reason a GRUB password alone is not a complete physical-access defence. It raises the bar, but anyone with a bootable USB and ten minutes can still get past it. For genuine at-rest protection, add LUKS full-disk encryption on top, or go further with LUKS combined with LVM on an encrypted root. If the machine is a pen-testing workstation, round out the hardening with kernel headers plus a working JDK so tools like Burp and Ghidra have everything they need.

Related Articles

Debian Best Gnome GTK Themes for Kali Linux / Debian / Ubuntu Ubuntu How To Install Python 3.10 on Ubuntu 22.04|20.04|18.04 Cheat Sheets Basic Linux Terminal Shortcuts Cheat Sheet Monitoring Install and Configure Nagios 4 on Ubuntu 22.04|20.04|18.04

2 thoughts on “Protect GRUB with Password on Linux”

  1. Thanks. I used this method but I didn't want to enter user name and password every time I boot, so I edited /boot/grub/grub.cfg file adding ' –unrestricted' next to a menu entry for allowing any user to boot the OS while preventing the user from editing the entry and preventing access to the grub command console.

    like this:
    menuentry 'Kali GNU/Linux' –unrestricted –class kali…

    Also,I read somewhere that for preventing that anyone edit GRUB's boot entries or use its command-line mode (allowing to boot without password) you should add the encrypted password in the file /etc/grub.d/40_custom (I haven't tried)

    Reply

Leave a Comment

Press ESC to close