186 lines
8.3 KiB
Text
186 lines
8.3 KiB
Text
18 Security
|
|
***********
|
|
|
|
18.1 Authentication and authorisation in GRUB
|
|
=============================================
|
|
|
|
By default, the boot loader interface is accessible to anyone with
|
|
physical access to the console: anyone can select and edit any menu
|
|
entry, and anyone can get direct access to a GRUB shell prompt. For
|
|
most systems, this is reasonable since anyone with direct physical
|
|
access has a variety of other ways to gain full access, and requiring
|
|
authentication at the boot loader level would only serve to make it
|
|
difficult to recover broken systems.
|
|
|
|
However, in some environments, such as kiosks, it may be appropriate
|
|
to lock down the boot loader to require authentication before performing
|
|
certain operations.
|
|
|
|
The 'password' (*note password::) and 'password_pbkdf2' (*note
|
|
password_pbkdf2::) commands can be used to define users, each of which
|
|
has an associated password. 'password' sets the password in plain text,
|
|
requiring 'grub.cfg' to be secure; 'password_pbkdf2' sets the password
|
|
hashed using the Password-Based Key Derivation Function (RFC 2898),
|
|
requiring the use of 'grub-mkpasswd-pbkdf2' (*note Invoking
|
|
grub-mkpasswd-pbkdf2::) to generate password hashes.
|
|
|
|
In order to enable authentication support, the 'superusers'
|
|
environment variable must be set to a list of usernames, separated by
|
|
any of spaces, commas, semicolons, pipes, or ampersands. Superusers are
|
|
permitted to use the GRUB command line, edit menu entries, and execute
|
|
any menu entry. If 'superusers' is set, then use of the command line
|
|
and editing of menu entries are automatically restricted to superusers.
|
|
Setting 'superusers' to empty string effectively disables both access to
|
|
CLI and editing of menu entries.
|
|
|
|
Other users may be allowed to execute specific menu entries by giving
|
|
a list of usernames (as above) using the '--users' option to the
|
|
'menuentry' command (*note menuentry::). If the '--unrestricted' option
|
|
is used for a menu entry, then that entry is unrestricted. If the
|
|
'--users' option is not used for a menu entry, then that only superusers
|
|
are able to use it.
|
|
|
|
Putting this together, a typical 'grub.cfg' fragment might look like
|
|
this:
|
|
|
|
set superusers="root"
|
|
password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring
|
|
password user1 insecure
|
|
|
|
menuentry "May be run by any user" --unrestricted {
|
|
set root=(hd0,1)
|
|
linux /vmlinuz
|
|
}
|
|
|
|
menuentry "Superusers only" --users "" {
|
|
set root=(hd0,1)
|
|
linux /vmlinuz single
|
|
}
|
|
|
|
menuentry "May be run by user1 or a superuser" --users user1 {
|
|
set root=(hd0,2)
|
|
chainloader +1
|
|
}
|
|
|
|
The 'grub-mkconfig' program does not yet have built-in support for
|
|
generating configuration files with authentication. You can use
|
|
'/etc/grub.d/40_custom' to add simple superuser authentication, by
|
|
adding 'set superusers=' and 'password' or 'password_pbkdf2' commands.
|
|
|
|
18.2 Using digital signatures in GRUB
|
|
=====================================
|
|
|
|
GRUB's 'core.img' can optionally provide enforcement that all files
|
|
subsequently read from disk are covered by a valid digital signature.
|
|
This document does *not* cover how to ensure that your platform's
|
|
firmware (e.g., Coreboot) validates 'core.img'.
|
|
|
|
If environment variable 'check_signatures' (*note check_signatures::)
|
|
is set to 'enforce', then every attempt by the GRUB 'core.img' to load
|
|
another file 'foo' implicitly invokes 'verify_detached foo foo.sig'
|
|
(*note verify_detached::). 'foo.sig' must contain a valid digital
|
|
signature over the contents of 'foo', which can be verified with a
|
|
public key currently trusted by GRUB (*note list_trusted::, *note
|
|
trust::, and *note distrust::). If validation fails, then file 'foo'
|
|
cannot be opened. This failure may halt or otherwise impact the boot
|
|
process.
|
|
|
|
GRUB uses GPG-style detached signatures (meaning that a file
|
|
'foo.sig' will be produced when file 'foo' is signed), and currently
|
|
supports the DSA and RSA signing algorithms. A signing key can be
|
|
generated as follows:
|
|
|
|
gpg --gen-key
|
|
|
|
An individual file can be signed as follows:
|
|
|
|
gpg --detach-sign /path/to/file
|
|
|
|
For successful validation of all of GRUB's subcomponents and the
|
|
loaded OS kernel, they must all be signed. One way to accomplish this
|
|
is the following (after having already produced the desired 'grub.cfg'
|
|
file, e.g., by running 'grub-mkconfig' (*note Invoking grub-mkconfig::):
|
|
|
|
# Edit /dev/shm/passphrase.txt to contain your signing key's passphrase
|
|
for i in `find /boot -name "*.cfg" -or -name "*.lst" -or \
|
|
-name "*.mod" -or -name "vmlinuz*" -or -name "initrd*" -or \
|
|
-name "grubenv"`;
|
|
do
|
|
gpg --batch --detach-sign --passphrase-fd 0 $i < \
|
|
/dev/shm/passphrase.txt
|
|
done
|
|
shred /dev/shm/passphrase.txt
|
|
|
|
See also: *note check_signatures::, *note verify_detached::, *note
|
|
trust::, *note list_trusted::, *note distrust::, *note load_env::, *note
|
|
save_env::.
|
|
|
|
Note that internally signature enforcement is controlled by setting
|
|
the environment variable 'check_signatures' equal to 'enforce'. Passing
|
|
one or more '--pubkey' options to 'grub-mkimage' implicitly defines
|
|
'check_signatures' equal to 'enforce' in 'core.img' prior to processing
|
|
any configuration files.
|
|
|
|
Note that signature checking does *not* prevent an attacker with
|
|
(serial, physical, ...) console access from dropping manually to the
|
|
GRUB console and executing:
|
|
|
|
set check_signatures=no
|
|
|
|
To prevent this, password-protection (*note Authentication and
|
|
authorisation::) is essential. Note that even with GRUB password
|
|
protection, GRUB itself cannot prevent someone with physical access to
|
|
the machine from altering that machine's firmware (e.g., Coreboot or
|
|
BIOS) configuration to cause the machine to boot from a different
|
|
(attacker-controlled) device. GRUB is at best only one link in a secure
|
|
boot chain.
|
|
|
|
18.3 UEFI secure boot and shim support
|
|
======================================
|
|
|
|
The GRUB, except the 'chainloader' command, works with the UEFI secure
|
|
boot and the shim. This functionality is provided by the shim_lock
|
|
module. It is recommend to build in this and other required modules
|
|
into the 'core.img'. All modules not stored in the 'core.img' and the
|
|
ACPI tables for the 'acpi' command have to be signed, e.g. using PGP.
|
|
Additionally, the 'iorw', the 'memrw' and the 'wrmsr' commands are
|
|
prohibited if the UEFI secure boot is enabled. This is done due to
|
|
security reasons. All above mentioned requirements are enforced by the
|
|
shim_lock module. And itself it is a persistent module which means that
|
|
it cannot be unloaded if it was loaded into the memory.
|
|
|
|
18.4 Measuring boot components
|
|
==============================
|
|
|
|
If the tpm module is loaded and the platform has a Trusted Platform
|
|
Module installed, GRUB will log each command executed and each file
|
|
loaded into the TPM event log and extend the PCR values in the TPM
|
|
correspondingly. All events will be logged into the PCR described below
|
|
with a type of EV_IPL and an event description as described below.
|
|
|
|
Event type PCR Description
|
|
---------------------------------------------------------------------------
|
|
Command 8 All executed commands (including those
|
|
from configuration files) will be logged
|
|
and measured as entered with a prefix of
|
|
"grub_cmd: "
|
|
Kernel command line 8 Any command line passed to a kernel will
|
|
be logged and measured as entered with a
|
|
prefix of "kernel_cmdline: "
|
|
Module command line 8 Any command line passed to a kernel
|
|
module will be logged and measured as
|
|
entered with a prefix of "module_cmdline:
|
|
"
|
|
Files 9 Any file read by GRUB will be logged and
|
|
measured with a descriptive text
|
|
corresponding to the filename.
|
|
|
|
GRUB will not measure its own 'core.img' - it is expected that
|
|
firmware will carry this out. GRUB will also not perform any
|
|
measurements until the tpm module is loaded. As such it is recommended
|
|
that the tpm module be built into 'core.img' in order to avoid a
|
|
potential gap in measurement between 'core.img' being loaded and the tpm
|
|
module being loaded.
|
|
|
|
Measured boot is currently only supported on EFI platforms.
|
|
|