Detailed guide for GRUB boot password protection using PBKDF2-SHA512.
GRUB password protection prevents unauthorized modification of boot parameters and recovery mode access. This implementation uses industry-standard PBKDF2-SHA512 hashing with the --unrestricted flag for headless server compatibility.
grub-mkpasswd-pbkdf2This generates a PBKDF2-SHA512 hash with 10,000 iterations:
grub.pbkdf2.sha512.10000.HASH_PART_1.HASH_PART_2
Format breakdown:
grub.pbkdf2.sha512- Algorithm identifier10000- PBKDF2 iteration count- Two long hexadecimal hash segments
GRUB password is configured in /etc/grub.d/40_custom:
#!/bin/sh
exec tail -n +3 $0
# GRUB Boot Password Protection
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.YOUR_HASHKey directives:
set superusers="root"- Defines admin user for GRUBpassword_pbkdf2 root HASH- Associates hash with user
The setup script adds --unrestricted to normal boot entries automatically via update-grub. This ensures:
menuentry 'Ubuntu' --unrestricted {
# Normal boot - no password required
}
menuentry 'Advanced options' --users '' {
# Recovery/advanced - password required
}
grub-mkpasswd-pbkdf2Enter password twice, copy the resulting hash.
sudo nano /etc/grub.d/40_customAdd at the end:
# GRUB Boot Password Protection
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.PASTE_HASH_HERECritical: Ensure the hash is on a single line with no line breaks.
sudo update-grubThis regenerates /boot/grub/grub.cfg with the password configuration.
# Check 40_custom has the config
grep -E "superusers|password_pbkdf2" /etc/grub.d/40_custom
# Check grub.cfg includes it
grep -E "superusers|password_pbkdf2" /boot/grub/grub.cfg
# Verify unrestricted flag
grep "menuentry.*--unrestricted" /boot/grub/grub.cfg- Boot Menu Editing (press 'e' at GRUB)
- GRUB Console (press 'c' at GRUB)
- Recovery Mode (Advanced Options)
- Single User Mode
- Normal boot (default entry)
- Automatic boot (after timeout)
- Remote reboots (headless-compatible)
- Algorithm: PBKDF2-SHA512
- Iterations: 10,000 (reasonable balance)
- Attack surface: Requires physical access + unlimited attempts
- Recommendation: Use strong password (14+ characters)
Typo in Hash:
# ❌ WRONG - Typo in "pbkdf2"
password_pokdr2 root grub.pbkdf2...Result: error: invalid PBKDF2 password at boot
Hash with Line Breaks:
# ❌ WRONG - Hash split across lines
password_pbkdf2 root grub.pbkdf2.sha512.10000.PART1.
PART2Result: Hash not recognized
Correct Format:
# ✅ CORRECT - Single line, no breaks
password_pbkdf2 root grub.pbkdf2.sha512.10000.LONG_HASH_HERECritical: Test immediately after setup!
-
Test 1 - Edit Protection:
- Reboot
- At GRUB menu, press 'e'
- Should prompt: "Enter username:"
- Enter:
root - Should prompt: "Enter password:"
- Enter GRUB password
- Should allow editing
-
Test 2 - Console Protection:
- At GRUB menu, press 'c'
- Should prompt for authentication
-
Test 3 - Normal Boot:
- Let GRUB menu timeout
- Should boot normally without password
The setup script creates timestamped backups:
/etc/grub.d/backups/
├── 40_custom.20260106_150000.bak
├── 40_custom.20260106_160000.bak
└── 40_custom.20260106_170000.bak
sudo cp /etc/grub.d/40_custom /etc/grub.d/40_custom.baksudo cp /etc/grub.d/backups/40_custom.TIMESTAMP.bak /etc/grub.d/40_custom
sudo update-grubCannot access boot menu editing, but can boot normally.
Solution:
- Boot normally (unrestricted)
- Login to system
- Reset GRUB password:
sudo grub-mkpasswd-pbkdf2 # Generate new hash sudo nano /etc/grub.d/40_custom # Update hash sudo update-grub
Boot fails with "error: invalid PBKDF2 password".
Solution:
- Boot from USB/recovery media
- Mount root filesystem:
mount /dev/sda2 /mnt # Adjust device - Restore backup:
cp /mnt/etc/grub.d/backups/40_custom.*.bak /mnt/etc/grub.d/40_custom - Regenerate GRUB:
chroot /mnt update-grub exit - Reboot
Cannot boot, forgot root password, GRUB password blocks recovery.
Solution:
- Boot from USB/recovery media
- Mount root filesystem
- Remove GRUB password:
mount /dev/sda2 /mnt nano /mnt/etc/grub.d/40_custom # Delete password lines chroot /mnt update-grub exit
- Reboot and login
- Reset root password:
sudo passwd root - Re-setup GRUB password correctly
Instead of root, use a custom username:
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.HASHset superusers="admin,backup"
password_pbkdf2 admin HASH1
password_pbkdf2 backup HASH2Protect only specific menu entries:
menuentry 'Ubuntu' --unrestricted {
# Anyone can boot this
}
menuentry 'Rescue Mode' --users admin {
# Only admin can boot this
}This configuration satisfies:
-
CIS 1.4.1: Ensure bootloader password is set
- ✅ PBKDF2 hash configured
-
CIS 1.4.2: Ensure permissions on bootloader config are configured
- ✅
/boot/grub/grub.cfgis 444 (read-only)
- ✅
-
CIS 1.4.3: Ensure authentication required for single user mode
- ✅ Recovery mode requires GRUB password