Skip to content

Boot & Physical Security: GRUB, LUKS, Secure Boot

Harden the Linux boot chain against console access, stolen disks and evil-maid attacks with GRUB passwords, LUKS encryption and Secure Boot.

Published on Updated on 3 min read

Once an attacker reaches the console or holds your powered-off disk, most software controls you configured for the running system stop applying. Filesystem permissions, sudo policy and SELinux are enforced by a kernel the attacker can replace or bypass. Boot and physical security is the layer that decides who is allowed to start that kernel in the first place, and whether the bytes on the platter mean anything to a thief. This article covers the GRUB bootloader, LUKS full-disk encryption, Secure Boot, and the small firmware and console settings that close the remaining gaps.

The threat model

Physical and console access defeats most runtime hardening. An attacker at the keyboard can interrupt GRUB, append init=/bin/bash or rd.break to the kernel command line, and obtain a root shell without any password. A stolen disk can be mounted read-write on another machine, exposing every unencrypted file regardless of its mode bits — see filesystem-permissions for why permissions alone are not a confidentiality control. Single-user and recovery boot entries are designed to grant unauthenticated root for repair, which is exactly what an attacker wants. The evil-maid scenario is subtler: a brief unattended moment lets someone tamper with /boot or the bootloader to capture your passphrase on the next boot. No amount of in-OS configuration stops these once the attacker controls the boot chain, so the controls below operate before and around the kernel.

Password-protecting GRUB

Generate a hashed password and define a superuser so menu editing and recovery entries require authentication, while normal boot stays unattended.

grub-mkpasswd-pbkdf2
# copy the resulting grub.pbkdf2.sha512.<...> string

Add a superuser block to /etc/grub.d/40_custom:

cat <<'EOF' | sudo tee -a /etc/grub.d/40_custom
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.AB12...CD34
EOF

By default this locks every menu entry. To let the machine still boot the default kernel without a password — only protecting editing and recovery — mark normal entries --unrestricted. On Debian/Ubuntu this is the CLASS line in /etc/grub.d/10_linux; the edit/e and command-line/c actions remain superuser-only. Regenerate the config with the path your distro uses:

# Debian / Ubuntu
sudo update-grub

# RHEL / Fedora / openSUSE (BIOS)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# RHEL UEFI: /boot/efi/EFI/<distro>/grub.cfg

Encrypting the disk with LUKS

LUKS encrypts a block device so a stolen or imaged disk is unreadable without the passphrase. The cleanest approach is to enable encryption in the installer, which sets up the LUKS container, the unlock prompt and /etc/crypttab for you. To encrypt an extra device after the fact:

sudo cryptsetup luksFormat /dev/sdb1
sudo cryptsetup luksOpen /dev/sdb1 cryptdata
sudo mkfs.ext4 /dev/mapper/cryptdata

Persist the mapping so it unlocks at boot via /etc/crypttab, then reference /dev/mapper/cryptdata in /etc/fstab:

# <name>      <device>                         <key>  <options>
cryptdata  UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxx  none   luks

Always encrypt swap as well: pages of memory, including keys and decrypted data, are written there in cleartext otherwise. Use a random key in crypttab so swap is re-keyed every boot:

cryptswap  /dev/sdc1  /dev/urandom  swap,cipher=aes-xts-plain64,size=256

Secure Boot and the kernel

Secure Boot has UEFI firmware verify the signature of the bootloader (shim), GRUB and the kernel against keys in the platform's db, refusing anything unsigned or tampered. Distro kernels and shim ship pre-signed. Check the current state:

mokutil --sb-state          # expect: SecureBoot enabled
bootctl status | grep -i secure

Secure Boot pairs with kernel lockdown mode, which is automatically engaged in integrity mode when Secure Boot is on, restricting even root from loading unsigned modules or reading kernel memory. Continue this in kernel-hardening, and ensure boot-time accounts are locked down per accounts-privileges.

Firmware and console settings

Set a BIOS/UEFI supervisor password and disable booting from USB, CD and network in firmware, so an attacker cannot sidestep your encrypted disk by booting their own media. Finally, stop a console user from triggering an uncontrolled reboot:

sudo systemctl mask ctrl-alt-del.target

Verify

Confirm each control is actually in force:

sudo grep -E 'superusers|password_pbkdf2' /boot/grub*/grub.cfg
sudo cryptsetup status cryptdata
mokutil --sb-state
systemctl is-enabled ctrl-alt-del.target   # expect: masked

If GRUB prompts for credentials on edit, the LUKS device shows as active, Secure Boot is enabled and Ctrl+Alt+Del is masked, the boot chain is hardened end to end.