Mastering Grub – Part 5 – Grub Security

Grub Security

Authentication and authorization 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’ and ‘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 ‘grub2-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 is automatically restricted to superusers.

   Other users may be given access to specific menu entries by giving a list of usernames (as above) using the ‘–users’ option to the ‘menuentry’ command.  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 ‘grub2-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.

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’ is set to ‘enforce’, then every attempt by the GRUB ‘core.img’ to load another file ‘foo’ implicitly invokes ‘verify_detached foo foo.sig’.  ‘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.  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 ‘grub2-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

 

Note that internally signature enforcement is controlled by setting the environment variable ‘check_signatures’ equal to ‘enforce’.  Passing one or more ‘–pubkey’ options to ‘grub2-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 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.

Ramdev

Ramdev

I have started unixadminschool.com ( aka gurkulindia.com) in 2009 as my own personal reference blog, and later sometime i have realized that my leanings might be helpful for other unixadmins if I manage my knowledge-base in more user friendly format. And the result is today's' unixadminschool.com. You can connect me at - https://www.linkedin.com/in/unixadminschool/

What is in your mind, about this post ? Leave a Reply

Close
  Our next learning article is ready, subscribe it in your email

What is your Learning Goal for Next Six Months ? Talk to us