complete cleanup of grub.cfg docs
remove all the redundant information, and merge some of it between the two articles (grub hardening and grub cbfs guides) Signed-off-by: Leah Rowe <info@minifree.org>master
parent
30cae6536a
commit
c50c0e1676
|
@ -3,11 +3,11 @@ title: Modifying grub.cfg in CBFS
|
||||||
x-toc-enable: true
|
x-toc-enable: true
|
||||||
...
|
...
|
||||||
|
|
||||||
NOTE: Libreboot standardises on [flashprog](https://flashprog.org/wiki/Flashprog)
|
Read [Libreboot flashing guides](../install/) before continuing, and make sure
|
||||||
now, as of 27 January 2024, which is a fork of flashrom.
|
to back up the current flash contents before you consider following this guide.
|
||||||
|
|
||||||
Before you follow this guide, it is advisable that you have the ability to
|
Before you follow this guide, it is advisable that you have the ability to
|
||||||
flash externally, just in case something goes wrong.
|
[flash externally](../install/spi.md), just in case something goes wrong.
|
||||||
|
|
||||||
Libreboot's own GRUB configuration automatically scans for one provided by
|
Libreboot's own GRUB configuration automatically scans for one provided by
|
||||||
your distro, and this automation will usually work. Sometimes, you might wish
|
your distro, and this automation will usually work. Sometimes, you might wish
|
||||||
|
@ -15,82 +15,89 @@ to override it with your own custom menuentry or additional logic in the GRUB
|
||||||
config. You can configure GRUB however you like, and this topic is vast so what
|
config. You can configure GRUB however you like, and this topic is vast so what
|
||||||
to actually *put in the config* will not be covered here.
|
to actually *put in the config* will not be covered here.
|
||||||
|
|
||||||
This guide will simply teach you how to modify the config, but not what to put.
|
This guide will simply teach you how to modify the config, but not what to put,
|
||||||
|
whereas the [GRUB hardening](../linux/grub_hardening.md) guide specifically
|
||||||
|
says what to modify; cross reference that page and this page.
|
||||||
|
|
||||||
Compile flashprog and cbfstool
|
**Disable security before continuing**
|
||||||
=============================
|
================================
|
||||||
|
|
||||||
libreboot does not currently distribute utilities pre-compiled. It only
|
**Before internal flashing, you must first disable `/dev/mem` protections. Make
|
||||||
provides ROM images pre-compiled, where feasible. Therefore, you have to build
|
sure to re-enable them after you're finished.**
|
||||||
the utilities from source.
|
|
||||||
|
|
||||||
As for the ROM, there are mainly three methods for obtaining a libreboot ROM
|
**See: [Disabling /dev/mem protection](../install/devmem.md)**
|
||||||
image:
|
|
||||||
|
|
||||||
1. Dump the contents of the the main *boot flash* on your system, which already
|
This only applies if you're following these instructions via internal
|
||||||
has libreboot installed (with GRUB as the default payload). Extract the
|
flashing, from an existing installation. If you're externally flashing the
|
||||||
GRUB configuration from *that* ROM image.
|
machine, you can ignore this advice.
|
||||||
2. Extract it from a libreboot ROM image supplied by the libreboot project, on
|
|
||||||
the libreboot website or mirrors of the libreboot website.
|
|
||||||
3. Build the ROM yourself, using the libreboot build system. Instructions for
|
|
||||||
how to do this are covered in the following article:
|
|
||||||
[How to build libreboot from source](../build/)
|
|
||||||
|
|
||||||
In either case, you will use the `cbfstool` supplied in the libreboot build
|
Build dependencies
|
||||||
system.
|
==================
|
||||||
This can be found under `coreboot/*/util/cbfstool/` as source code,
|
|
||||||
where `*` can be any coreboot source code directory for a given mainboard.
|
|
||||||
The directory named `default` should suffice.
|
|
||||||
|
|
||||||
Install the build dependencies. For Debian and similar, you can run
|
**Please first [install build dependencies](../build/).**
|
||||||
the following command in the libreboot build system, from the root directory
|
|
||||||
of the libreboot Git repository.
|
|
||||||
|
|
||||||
./mk dependencies debian
|
Coreboot utilities
|
||||||
|
------------------
|
||||||
|
|
||||||
Determine what coreboot tree you need for your board. For example, if building
|
You need `cbfstool` from coreboot. For whatever board you have, check which
|
||||||
for `x200_8mb`, check `config/coreboot/x200_8mb/target.cfg` and it might
|
coreboot tree it uses in Libreboot's build system, lbmk. For example, let's
|
||||||
say `tree="default"` - in this case, the coreboot tree is named `default`.
|
say your board is `x200_8mb`, you would do:
|
||||||
|
|
||||||
Then, download coreboot (we'll assume the `default` tree is correct):
|
grep tree= config/coreboot/x200_8mb/target.cfg
|
||||||
|
|
||||||
./mk -f coreboot default
|
In this example, the output might be:
|
||||||
|
|
||||||
Finally, compile the `cbutils` payload (and you will then have the utils):
|
tree="default"
|
||||||
|
|
||||||
./mk -b grub
|
This means you should compile `cbfstool` from the `default` coreboot tree,
|
||||||
|
like so:
|
||||||
GRUB is multi-tree, but for GRUB utilities that's fine because we don't patch
|
|
||||||
those in any tree; we only patch the GRUB kernel to add various drivers and
|
|
||||||
extra crypto such as argon2.
|
|
||||||
|
|
||||||
Among other things, this will produce a `cbfstool` executable under any of the
|
|
||||||
subdirectories in `src/coreboot/` under `util/cbfstool/cbfstool`.
|
|
||||||
|
|
||||||
For example: `src/coreboot/default/util/cbfstool/cbfstool`
|
|
||||||
|
|
||||||
The `cbfstool` utility is what you shall use. It is used to manipulate CBFS
|
|
||||||
(coreboot file system) which is a file system contained within the coreboot
|
|
||||||
ROM image; as a *coreboot distribution*, libreboot inherits this technology.
|
|
||||||
|
|
||||||
You can compile cbfstool and ifdtool for the given coreboot tree, e.g.:
|
|
||||||
|
|
||||||
./mk -d coreboot default
|
./mk -d coreboot default
|
||||||
|
|
||||||
This will create `elf/cbfstool/default/cbfbstool`
|
This will result in the following binary: `elf/cbfstool/default/cbfstool`
|
||||||
and `elf/ifdtool/default/ifdtool`.
|
|
||||||
|
|
||||||
You will also want to build `flashprog` which libreboot recommends for reading
|
We won't assume the path to cbfstool, in the remainder of this guide, so
|
||||||
from and/or writing to the boot flash. In the libreboot build system, you can
|
adapt accordingly.
|
||||||
build it by running this command:
|
|
||||||
|
GRUB utilities
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Again, let's assume the coreboot board is `x200_8mb`. Check the
|
||||||
|
file `config/coreboot/x200_8mb/target.cfg` for `grubtree` - if it's not set,
|
||||||
|
then the GRUB tree is `default`. We will assume `default`:
|
||||||
|
|
||||||
|
./mk -b grub default
|
||||||
|
|
||||||
|
This will compile GRUB for the given tree. If you need to use any of the GRUB
|
||||||
|
utilities, this command will build them and in this example, they will be
|
||||||
|
available under `src/grub/default/`.
|
||||||
|
|
||||||
|
Flashprog
|
||||||
|
---------
|
||||||
|
|
||||||
|
Compile flashprog like so:
|
||||||
|
|
||||||
./mk -b flashprog
|
./mk -b flashprog
|
||||||
|
|
||||||
An executable will be available at `elf/flashprog/flashprog` after you have done
|
A binary will appear at `elf/flashprog/flashprog`.
|
||||||
this.
|
|
||||||
|
Default GRUB config
|
||||||
|
===================
|
||||||
|
|
||||||
|
The coreboot image has its own filesystem, CBFS, and within CBFS is the GRUB
|
||||||
|
binary, and within the GRUB binary is another filesystem called memdisk, where
|
||||||
|
the default GRUB configuration is located.
|
||||||
|
|
||||||
|
You can override it by inserting your own GRUB config within CBFS.
|
||||||
|
|
||||||
|
Acquiring a GRUB config
|
||||||
|
=======================
|
||||||
|
|
||||||
Dump the boot flash
|
Dump the boot flash
|
||||||
===================
|
-------------------
|
||||||
|
|
||||||
|
This is only useful if you already inserted a GRUB config in CBFS. Otherwise,
|
||||||
|
you can grab it from Libreboot's build system, lbmk.
|
||||||
|
|
||||||
[Learn how to externally reprogram these chips](../install/spi.md) and use
|
[Learn how to externally reprogram these chips](../install/spi.md) and use
|
||||||
the `-r` option in flashprog; alternatively, for internal flash access,
|
the `-r` option in flashprog; alternatively, for internal flash access,
|
||||||
|
@ -98,6 +105,28 @@ look at the [main flashing guide](../install/).
|
||||||
|
|
||||||
Those guides show how to dump the flash contents, which you are advised to do.
|
Those guides show how to dump the flash contents, which you are advised to do.
|
||||||
|
|
||||||
|
Default GRUB config location
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
We'll assume that your GRUB tree is `default`, so the
|
||||||
|
file `config/grub/default/config/payload` is your GRUB config; this will be the
|
||||||
|
same as what you have in memdisk. Make a copy of this file, for modification.
|
||||||
|
|
||||||
|
Modify *that* file, or the one you extracted if you already inserted a custom
|
||||||
|
one before, and you will re-insert it when you're done.
|
||||||
|
|
||||||
|
Insert grubtest.cfg
|
||||||
|
===================
|
||||||
|
|
||||||
|
Before reading the next section, please note: if you only have the fallback
|
||||||
|
GRUB config in memdisk, and no configs in CBFS, you can test the modified
|
||||||
|
version by inserting it as `grubtest.cfg`, instead of `grub.cfg`:
|
||||||
|
|
||||||
|
cbfstool libreboot.rom add -f grubtest.cfg -n grubtest.cfg
|
||||||
|
|
||||||
|
Libreboot will not automatically load it, but it will be available from the
|
||||||
|
default GRUB menu. This can be useful for test purposes, hence the name.
|
||||||
|
|
||||||
Insert new grub.cfg
|
Insert new grub.cfg
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
@ -110,32 +139,20 @@ Now remove it:
|
||||||
|
|
||||||
cbfstool libreboot.rom remove -n grub.cfg
|
cbfstool libreboot.rom remove -n grub.cfg
|
||||||
|
|
||||||
It's important that you re-add `grub.cfg` before flashing:
|
It's important that you re-add `grub.cfg` before flashing (or just add it, if
|
||||||
|
it was never there in the first place):
|
||||||
|
|
||||||
cbfstool libreboot.rom add -f grub.cfg -n grub.cfg
|
cbfstool libreboot.rom add -f grub.cfg -n grub.cfg
|
||||||
|
|
||||||
Repeat this for `grubtest.cfg` if you wish.
|
**If you flash the Libreboot image without a `grub.cfg` in CBFS, it will
|
||||||
|
default back to the one in GRUB memdisk.
|
||||||
|
|
||||||
If you're using a default Libreboot image, there *is no `grub.cfg` in flash*.
|
AGAIN:
|
||||||
This is because there is also a default one embedded inside the GRUB binary,
|
|
||||||
which is inside CBFS. So:
|
|
||||||
|
|
||||||
The coreboot image has its own filesystem, CBFS, and within CBFS is the GRUB
|
If you only want to test your changes first, insert it first as `grubtest.cfg`
|
||||||
binary, and within the GRUB binary is another filesystem called memdisk, where
|
and ensure that no `grub.cfg` exists in flash. This will let you access the
|
||||||
the default GRUB configuration is located.
|
test config from the default menu, before deciding whether to make it the
|
||||||
|
main config, as `grub.cfg`, overriding the one in GRUB memdisk.
|
||||||
You can insert a `grub.cfg` into CBFS and it will override the one in memdisk.
|
|
||||||
|
|
||||||
Check your board, e.g. `x200_8mb`, look at the file: `config/coreboot/x200_8mb/target.cfg`
|
|
||||||
and check for `grubtree` - if it's not sot, then it's `default`, otherwise check
|
|
||||||
what it's set to.
|
|
||||||
|
|
||||||
We'll assume it's `default`, so the
|
|
||||||
file `config/grub/default/config/payload` is your GRUB config; this will be the
|
|
||||||
same as what yo uhave in memdisk.
|
|
||||||
|
|
||||||
Modify *that* file, or the one you extracted if you already inserted a custom
|
|
||||||
one before, and you will re-insert it when you're done.
|
|
||||||
|
|
||||||
Flash the modified ROM image
|
Flash the modified ROM image
|
||||||
============================
|
============================
|
||||||
|
|
|
@ -3,316 +3,40 @@ title: Hardening GRUB
|
||||||
x-toc-enable: true
|
x-toc-enable: true
|
||||||
...
|
...
|
||||||
|
|
||||||
**NOTE: [Encrypted /boot with LUKS2 on argon2 key derivation is now
|
GRUB supports various security mechanisms that are not enabled by default.
|
||||||
possible](../../news/argon2.md). This is covered in
|
This page will tell you how to enable them, for the purpose of boot security,
|
||||||
the [main Linux guide](./).**
|
both detecting and attempting to prevent certain types of attack.
|
||||||
|
|
||||||
GRUB can have password protection at boot, prevent unauthorised access to the
|
**Make sure you have an [external SPI programmer](../install/spi.md), for
|
||||||
shell and to menuentries. You can also boot from fully encrypted distros, where
|
recovery purposes, just in case you brick your machine. The modifications
|
||||||
the `/boot` directory is already encrypted, containing your kernel. You can
|
documented here are highly invasive and it would be easy to make mistakes.**
|
||||||
additionally verify each file, including GRUB configuration files and Linux
|
|
||||||
kernels, using GPG; GRUB supports putting a GPG pubkey in CBFS, and using it
|
|
||||||
to verify all files that it accesses.
|
|
||||||
|
|
||||||
Let's begin.
|
Full disk encryption
|
||||||
|
====================
|
||||||
|
|
||||||
**Disable security before flashing**
|
[Encrypted /boot with LUKS2 on argon2 key derivation is now
|
||||||
================================
|
possible](../../news/argon2.md).
|
||||||
|
|
||||||
**Before internal flashing, you must first disable `/dev/mem` protections. Make
|
This is covered in
|
||||||
sure to re-enable them after you're finished.**
|
the [main Linux guide](./#encrypted-boot-via-luks2-with-argon2), in the
|
||||||
|
section pertaining to LUKS2/argon2.
|
||||||
|
|
||||||
**See: [Disabling /dev/mem protection](../install/devmem.md)**
|
You are strongly advised to create an encrypted Linux installation, before
|
||||||
|
setting up GRUB as shown in the guide below. Adapt it for whichever distro
|
||||||
|
you're installing (documenting every distro on the Libreboot documentation
|
||||||
|
would be a futile exercise and will not be attempted).
|
||||||
|
|
||||||
This only applies if you're following these instructions via internal
|
You are advised to do this *first*, because steps below depend on certain
|
||||||
flashing, from an existing installation.
|
configuration changes to be made on your installed Linux distro.
|
||||||
|
|
||||||
Back up your flash first!
|
**Dependencies (do this first)**
|
||||||
=========================
|
=============================
|
||||||
|
|
||||||
Make sure you also back up the current flash contents, before you proceed with
|
**Please read this: [Modifying GRUB in CBFS](grub_cbfs.md)**
|
||||||
this guide. See: [Libreboot flashing guides](../install/) (it also says how
|
|
||||||
to read the flash, in addition to writing it)
|
|
||||||
|
|
||||||
Build dependencies
|
**Assimilate that knowledge before continuing with the instructions below,
|
||||||
==================
|
which tells you what modifications to actually perform, whereas the guide
|
||||||
|
linked above tells you how to apply your modifications for flashing.**
|
||||||
You need `cbfstool` from coreboot. For whatever board you have, check which
|
|
||||||
coreboot tree it uses in Libreboot's build system, lbmk. For example, let's
|
|
||||||
say your board is `x200_8mb`, you would do:
|
|
||||||
|
|
||||||
grep tree= config/coreboot/x200_8mb/target.cfg
|
|
||||||
|
|
||||||
In this example, the output might be:
|
|
||||||
|
|
||||||
tree="default"
|
|
||||||
|
|
||||||
This means you should compile `cbfstool` from the `default` coreboot tree,
|
|
||||||
like so:
|
|
||||||
|
|
||||||
./mk -d coreboot default
|
|
||||||
|
|
||||||
This will result in the following binary: `elf/cbfstool/default/cbfstool`
|
|
||||||
|
|
||||||
We won't assume the path to cbfstool, in the remainder of this guide, so
|
|
||||||
adapt accordingly.
|
|
||||||
|
|
||||||
Background information
|
|
||||||
=========================
|
|
||||||
|
|
||||||
By default, the `grub.cfg` file and `grubtest.cfg` file are not present in
|
|
||||||
CBFS, because the GRUB memdisk, contained within the GRUB binary itself, within
|
|
||||||
CBFS, contains a GRUB configuration file.
|
|
||||||
|
|
||||||
Libreboot will switch to `grub.cfg` from flash instead, if it exists,
|
|
||||||
skipping the one in memdisk.
|
|
||||||
|
|
||||||
Because we need to put a signature next to each file, that would mean
|
|
||||||
re-building GRUB if you wanted to use the one in memdisk. Therefore, we can
|
|
||||||
insert a custom one in CBFS, to mitigate that fact.
|
|
||||||
|
|
||||||
By doing it this way, you can avoid re-building GRUB, or indeed anything inside
|
|
||||||
your current Libreboot images.
|
|
||||||
|
|
||||||
References:
|
|
||||||
|
|
||||||
* [GRUB manual](https://www.gnu.org/software/grub/manual/html_node/Security.html#Security)
|
|
||||||
* [GRUB info pages](http://git.savannah.gnu.org/cgit/grub.git/tree/docs/grub.texi)
|
|
||||||
* [Coreboot GRUB security howto](https://www.coreboot.org/GRUB2#Security)
|
|
||||||
|
|
||||||
GRUB Password
|
|
||||||
=============
|
|
||||||
|
|
||||||
The security of this setup depends on a good GRUB password as GPG signature
|
|
||||||
checking can be disabled through the interactive console:
|
|
||||||
|
|
||||||
set check_signatures=no
|
|
||||||
|
|
||||||
Disabling signatures, using the above command, is useful when you're booting
|
|
||||||
regular media such as live distros via USB.
|
|
||||||
|
|
||||||
You are strongly advised to use an *open diceware* passphrase (look that up).
|
|
||||||
Generate a strong passphrase of completely random words, at least 20 words in
|
|
||||||
total is ideal. Passphrases are better than pass*words* containing lots
|
|
||||||
of random letters and symbols, because pass*phrases* have higher entropy and
|
|
||||||
are therefore harder to crack.
|
|
||||||
|
|
||||||
The GRUB password can be stored in one of two ways:
|
|
||||||
|
|
||||||
* plaintext
|
|
||||||
* protected with [PBKDF2](https://en.wikipedia.org/wiki/Pbkdf2)
|
|
||||||
|
|
||||||
We will *obviously* use the latter method. Generating the PBKDF2 derived key is
|
|
||||||
done using the `grub-mkpasswd-pbkdf2` utility. You can get it by
|
|
||||||
installing GRUB version 2. Generate a key by giving it a password:
|
|
||||||
|
|
||||||
NOTE: This utility is included under the `grub/` directory, when you build
|
|
||||||
GRUB using the libreboot build system. Run the following commands (assuming
|
|
||||||
you have the correct build dependencies installed) to build GRUB, from the
|
|
||||||
libreboot Git repository:
|
|
||||||
|
|
||||||
./mk -b grub default
|
|
||||||
|
|
||||||
The following executable will then be available under `src/grub/default/`:
|
|
||||||
|
|
||||||
grub-mkpasswd-pbkdf2
|
|
||||||
|
|
||||||
Run that program. It will ask you to choose a new passphrase. Its output will
|
|
||||||
be a string of the following form:
|
|
||||||
|
|
||||||
grub.pbkdf2.sha512.10000.HEXDIGITS.MOREHEXDIGITS
|
|
||||||
|
|
||||||
Make sure to copy this into the correct GRUB config. The correct GRUB config
|
|
||||||
can be determined as follows. Again, let's assume that you have `x200_8mb`:
|
|
||||||
|
|
||||||
grep grubtree= config/coreboot/x200_8mb/target.cfg
|
|
||||||
|
|
||||||
It *may* or *may not* output anything. If it outputs *nothing*, then the
|
|
||||||
GRUB tree is `default`, otherwise it might output something like:
|
|
||||||
|
|
||||||
grubtree="nvme"
|
|
||||||
|
|
||||||
Make *sure* to use the correct GRUB tree. We will assume `default`, so you
|
|
||||||
should adapt accordingly, when doing this yourself:
|
|
||||||
|
|
||||||
cp config/grub/default/config/payload grub.cfg
|
|
||||||
|
|
||||||
Now, your `grub.cfg` file is correct for the board, and you can insert
|
|
||||||
the salted, hashed passphrase that you get from `grub-mkpasswd-pbkdf2` earlier.
|
|
||||||
|
|
||||||
Now open my.grubtest.cfg and put the following before the menu entries
|
|
||||||
(prefered above the functions and after other directives). Of course use
|
|
||||||
the pbdkf string that you had generated yourself:
|
|
||||||
|
|
||||||
Put this *before* the menuentries (just before) in `grub.cfg`, but note that
|
|
||||||
you should **not** literally use what is below; the hash below is not the one
|
|
||||||
you generated yourself. Make sure to adapt accordingly.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
set superusers="root"
|
|
||||||
password_pbkdf2 root grub.pbkdf2.sha512.10000.711F186347156BC105CD83A2ED7AF1EB971AA2B1EB2640172F34B0DEFFC97E654AF48E5F0C3B7622502B76458DA494270CC0EA6504411D676E6752FD1651E749.8DD11178EB8D1F633308FD8FCC64D0B243F949B9B99CCEADE2ECA11657A757D22025986B0FA116F1D5191E0A22677674C994EDBFADE62240E9D161688266A711
|
|
||||||
|
|
||||||
**Again**, replace it with the correct hash that you actually obtained for the
|
|
||||||
password you entered. In other words, *do not use the hash that you see above!*
|
|
||||||
|
|
||||||
Once this configuration is inserted, you will need to enter a passphrase every
|
|
||||||
time you boot. GRUB will also ask for a username. In the above example, we
|
|
||||||
made a username `root`, but you can set it to what you want and
|
|
||||||
adapt accordingly.
|
|
||||||
|
|
||||||
Another good thing to do, if we chose to load signed on-disk GRUB
|
|
||||||
configurations, is to remove (or comment out) `unset superusers`. Find any line
|
|
||||||
that says this, in your `grub.cfg` file:
|
|
||||||
|
|
||||||
unset superusers
|
|
||||||
|
|
||||||
Change it to this:
|
|
||||||
|
|
||||||
# unset superusers
|
|
||||||
|
|
||||||
The `unset superusers` command disables password authentication, which will
|
|
||||||
allow the attacker to boot an arbitrary operating system, regardless of
|
|
||||||
signature checking. The default libreboot configuration is tweaked for *ease of
|
|
||||||
use* by end users, and it is *not* done with security in mind (though security
|
|
||||||
is preferred). Thus, libreboot is less restrictive by default. What you are
|
|
||||||
doing, per this article, is making your system *more secure* but at the expense
|
|
||||||
of user-friendliness.
|
|
||||||
|
|
||||||
That just about covers it, where password setup is concerned!
|
|
||||||
|
|
||||||
SeaBIOS first?
|
|
||||||
==============
|
|
||||||
|
|
||||||
**Very important. Make sure you read this carefully.**
|
|
||||||
|
|
||||||
In releases after Libreboot 20240504, SeaBIOS is the primary payload on
|
|
||||||
all images, but GRUB is available in the boot menu. Select a ROM image
|
|
||||||
with `grubfirst` at the end, and do this to the ROM image:
|
|
||||||
|
|
||||||
cbfstool libreboot.rom add-int -i 0 -n etc/show-boot-menu
|
|
||||||
|
|
||||||
This disables the SeaBIOS menu, so that it only loads GRUB. The `grubfirst`
|
|
||||||
image had this done to it by lbmk (Libreboot build system) during build:
|
|
||||||
|
|
||||||
cbfstool libreboot.rom add -f config/grub/bootorder -n bootorder -t raw
|
|
||||||
|
|
||||||
This `bootorder` file has the following contents:
|
|
||||||
|
|
||||||
```
|
|
||||||
/rom@img/grub2
|
|
||||||
```
|
|
||||||
|
|
||||||
You can add it yourself if your image doesn't have it. With this, SeaBIOS
|
|
||||||
only loads GRUB first. You can still put a GRUB config in CBFS to override
|
|
||||||
the default one, as of Libreboot 20240612.
|
|
||||||
|
|
||||||
NOTE: Before disabling the boot menu, make sure GRUB works. Access it using
|
|
||||||
the `bootorder` file and/or press ESC in the SeaBIOS menu. Then disable the
|
|
||||||
SeaBIOS menu:
|
|
||||||
|
|
||||||
cbfstool libreboot.rom add-int -i 0 -n etc/show-boot-menu
|
|
||||||
|
|
||||||
Although the `bootorder` file only specifies *GRUB*, this just means that
|
|
||||||
SeaBIOS won't automatically try to boot anything else. The SeaBIOS menu is still
|
|
||||||
accessible, by pressing ESC when prompted; the above `add-int` command disables
|
|
||||||
that menu, so that *only* the GRUB payload will be executed.
|
|
||||||
|
|
||||||
SeaBIOS option ROMs
|
|
||||||
===================
|
|
||||||
|
|
||||||
SeaBIOS will also still execute PCI option ROMs. Depending on your preference,
|
|
||||||
you may wish to disable this, but please note that this will break certain
|
|
||||||
things like graphics cards. More information is available here:
|
|
||||||
|
|
||||||
<https://www.seabios.org/Runtime_config>
|
|
||||||
|
|
||||||
On a laptop, you probably don't have to worry about option ROMs at all, but
|
|
||||||
desktops are much more easily upgradeable; though, in practise, anyone
|
|
||||||
inclined to insert a card with a malicious option ROM on it wouldn't do that
|
|
||||||
anyway, because if they have access to your hardware, they could just
|
|
||||||
externally re-flash the machine anyway, so I wouldn't worry, but it's up to you.
|
|
||||||
|
|
||||||
If you're using a graphics card, you *need* VGA option ROMs at least.
|
|
||||||
|
|
||||||
GPG keys
|
|
||||||
========
|
|
||||||
|
|
||||||
First, generate a GPG keypair to use for signing. Option RSA (sign only)
|
|
||||||
is ok.
|
|
||||||
|
|
||||||
WARNING: GRUB does not read ASCII armored keys. When attempting to
|
|
||||||
trust ... a key filename it will print `error: bad signature` on the screen.
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir --mode 0700 keys
|
|
||||||
gpg --homedir keys --gen-key
|
|
||||||
gpg --homedir keys --export-secret-keys --armor > boot.secret.key # backup
|
|
||||||
gpg --homedir keys --export > boot.key
|
|
||||||
```
|
|
||||||
|
|
||||||
Now that we have a key, we can sign some files with it. We must sign:
|
|
||||||
|
|
||||||
- a kernel
|
|
||||||
- (if we have one) an initramfs
|
|
||||||
- (if we wish to transfer control to it) an on-disk `grub.cfg`
|
|
||||||
- `grubtest.cfg` (so that you can go back to `grubtest.cfg` after signature
|
|
||||||
checking is enforced. You can always get back to `grub.cfg` by pressing ESC,
|
|
||||||
but, afterwards, `grubtest.cfg` is not signed and it will not load. The
|
|
||||||
GRUB config we made earlier can be copied to `grubtest.cfg` and inserted,
|
|
||||||
but please only do this at the end of the guide when it tells you to insert
|
|
||||||
the GRUB config, because there are still osme things you need to do.
|
|
||||||
|
|
||||||
Suppose that we have a pair of `my.kernel` and `my.initramfs` and an
|
|
||||||
on-disk `libreboot_grub.cfg`. We will sign them by running the following
|
|
||||||
commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
gpg --homedir keys --detach-sign my.initramfs
|
|
||||||
gpg --homedir keys --detach-sign my.kernel
|
|
||||||
gpg --homedir keys --detach-sign libreboot_grub.cfg
|
|
||||||
gpg --homedir keys --detach-sign my.grubtest.cfg
|
|
||||||
```
|
|
||||||
|
|
||||||
Of course, some further modifications to grubtest.cfg will be required. We
|
|
||||||
need to *trust* the key and enable signature enforcement (put this before menu
|
|
||||||
entries):
|
|
||||||
|
|
||||||
```
|
|
||||||
trust (cbfsdisk)/boot.key
|
|
||||||
set check_signatures=enforce
|
|
||||||
```
|
|
||||||
|
|
||||||
What remains now is to include the modifications into the libreboot image
|
|
||||||
(ROM):
|
|
||||||
|
|
||||||
```
|
|
||||||
cbfstool libreboot.rom add -n boot.key -f boot.key -t raw
|
|
||||||
|
|
||||||
# You might consider copying `grub.cfg` to `grubtest.cfg` and adding that.
|
|
||||||
# Otherwise, adding just `grub.cfg` is also fine.
|
|
||||||
|
|
||||||
cbfstool libreboot.rom add -n grub.cfg -f my.grub.cfg -t raw
|
|
||||||
cbfstool libreboot.rom add -n grub.cfg.sig -f my.grub.cfg.sig -t raw
|
|
||||||
|
|
||||||
cbfstool libreboot.rom add -n grubtest.cfg -f my.grubtest.cfg -t raw
|
|
||||||
cbfstool libreboot.rom add -n grubtest.cfg.sig -f my.grubtest.cfg.sig -t raw
|
|
||||||
```
|
|
||||||
|
|
||||||
Congratulations!
|
|
||||||
================
|
|
||||||
|
|
||||||
With any luck, this should work perfectly. Your system will no longer boot
|
|
||||||
anything unless it's signed by your key.
|
|
||||||
|
|
||||||
If your entire system is also encrypted, including `/boot`, then that protects
|
|
||||||
everything including the privkey much more robustly, and it further prevents
|
|
||||||
tampering with your kernel (where GPG only detects tampering, encryption can
|
|
||||||
prevent it).
|
|
||||||
|
|
||||||
Encryption, combined with a GRUB passphrase, combined with a GPG check, should
|
|
||||||
make you pretty damn secure at boot time. All that's left now is one final,
|
|
||||||
optional step:
|
|
||||||
|
|
||||||
Flash write protection
|
Flash write protection
|
||||||
======================
|
======================
|
||||||
|
@ -322,47 +46,9 @@ except you from overwriting the flash without permission. This is important,
|
||||||
because you don't want some malicious software running as root from overwriting
|
because you don't want some malicious software running as root from overwriting
|
||||||
your flash, thus removing any of the above protections.
|
your flash, thus removing any of the above protections.
|
||||||
|
|
||||||
The simplest way is to just do this:
|
Build-time write protect
|
||||||
|
|
||||||
ifdtool -x libreboot.rom -O libreboot.rom
|
|
||||||
|
|
||||||
If you did the step before, to compile `cbfstool`, you can find ifdtool in
|
|
||||||
the `elf/` directory, e.g. `elf/ifdtool/default/ifdtool`. Make sure to use
|
|
||||||
the correct version, as per `tree=` (same as before when deciding to which
|
|
||||||
cbfstool version to use based on the coreboot tree used by your board).
|
|
||||||
|
|
||||||
Note that this only works for Intel-based systems that use an Intel Flash
|
|
||||||
Descriptor, which is actually most Intel systems that Libreboot supports.
|
|
||||||
|
|
||||||
You can still flash externally, or strap `HDA_SDO` (`HDA_DOCK_EN` on older
|
|
||||||
GM45 machines) accordingly. Note that the x4x/ich10-based machines don't have
|
|
||||||
flash descriptors, and neither do the i945 machines, but the GM45 and newer
|
|
||||||
Intel platforms do.
|
|
||||||
|
|
||||||
Other facts
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Strapping `HDA_SDO` or `HDA_DOCK_EN` requires physical access, because you have
|
|
||||||
to short a pin on the HDA chip on the motherboard, or there will be a header
|
|
||||||
for this on the board (e.g. "service mode" jumper).
|
|
||||||
|
|
||||||
On *Dell Latitude* laptops specifically, the EC can unlock flash by setting
|
|
||||||
the SDO/DOCK\_EN signal as described, and this is in fact what
|
|
||||||
the `dell-flash-unlock` utility does, so you can consider IFD locking there
|
|
||||||
to be basically useless.
|
|
||||||
|
|
||||||
In addition to the above, you may also consider `/dev/mem` protection.
|
|
||||||
Enable `CONFIG_STRICT_DEVMEM` in your Linux kernel, or set `securelevel` above
|
|
||||||
zero on your BSD setup (but BSD cannot be booted with GRUB very easily so
|
|
||||||
it's a moot point).
|
|
||||||
|
|
||||||
Other write-protect methods
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
The steps above do not require recompilation of the Libreboot images. However,
|
|
||||||
coreboot offers additional security at build time, which you can select if you
|
|
||||||
wish.
|
|
||||||
|
|
||||||
Let's assume your board is `x200_8mb`, do:
|
Let's assume your board is `x200_8mb`, do:
|
||||||
|
|
||||||
./mk -m coreboot x200_8mb
|
./mk -m coreboot x200_8mb
|
||||||
|
@ -393,6 +79,207 @@ Anyway, when you're done, save the config and then build it from source in lbmk.
|
||||||
|
|
||||||
See: [build from source](../build/)
|
See: [build from source](../build/)
|
||||||
|
|
||||||
|
IFD-based flash protection
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The simplest way is to just do this:
|
||||||
|
|
||||||
|
ifdtool -x libreboot.rom -O libreboot.rom
|
||||||
|
|
||||||
|
If you did the step before, to compile `cbfstool`, you can find ifdtool in
|
||||||
|
the `elf/` directory, e.g. `elf/ifdtool/default/ifdtool`. Use the ifdtool
|
||||||
|
version matching the coreboot tree for your mainboard.
|
||||||
|
|
||||||
|
Note that this only works for Intel-based systems that use an Intel Flash
|
||||||
|
Descriptor, which is actually most Intel systems that Libreboot supports.
|
||||||
|
|
||||||
|
Other facts
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Strapping `HDA_SDO` or `HDA_DOCK_EN` requires physical access, because you have
|
||||||
|
to short a pin on the HDA chip on the motherboard, or there will be a header
|
||||||
|
for this on the board (e.g. "service mode" jumper). If you strap those pins,
|
||||||
|
it disables descriptor-based flash protections.
|
||||||
|
|
||||||
|
On *Dell Latitude* laptops specifically, the EC can unlock flash by setting
|
||||||
|
the SDO/DOCK\_EN signal as described, and this is in fact what
|
||||||
|
the `dell-flash-unlock` utility does, so you can consider IFD locking there
|
||||||
|
to be basically useless.
|
||||||
|
|
||||||
|
In addition to the above, you may also consider `/dev/mem` protection.
|
||||||
|
Enable `CONFIG_STRICT_DEVMEM` in your Linux kernel, or set `securelevel` above
|
||||||
|
zero on your BSD setup (but BSD cannot be booted with GRUB very easily so
|
||||||
|
it's a moot point).
|
||||||
|
|
||||||
|
FLILL
|
||||||
|
-----
|
||||||
|
|
||||||
|
On Intel Flash Descriptor, you can insert up to four (4) commands on a list
|
||||||
|
within, called *FLILL*; not yet documented, but any SPI command listed here
|
||||||
|
would no longer work during internal flash operations. For example, you could
|
||||||
|
use it to disable certain erase/write commands. You could also use it to
|
||||||
|
disable *reads*.
|
||||||
|
|
||||||
|
PRx registers
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Protected Range registers are available on Intel platforms, to disable flash
|
||||||
|
writes. This is not yet documented, and it varies per platform.
|
||||||
|
|
||||||
|
GRUB Password
|
||||||
|
=============
|
||||||
|
|
||||||
|
The security of this setup depends on a good GRUB password as GPG signature
|
||||||
|
checking can be disabled through the GRUB console with this command:
|
||||||
|
|
||||||
|
set check_signatures=no
|
||||||
|
|
||||||
|
The above GRUB shell command is required when you want to live USB media,
|
||||||
|
or other Linux setups that don't yet have signatures on files e.g. linux.
|
||||||
|
|
||||||
|
We will assume that you're using the `default` GRUB tree; the GRUB CBFS guide
|
||||||
|
linked above tells you how to determine which GRUB tree to use.
|
||||||
|
|
||||||
|
The following executable will then be available under `src/grub/default/`:
|
||||||
|
|
||||||
|
grub-mkpasswd-pbkdf2
|
||||||
|
|
||||||
|
Run that program. It will ask you to choose a new passphrase. Its output will
|
||||||
|
be a string of the following form:
|
||||||
|
|
||||||
|
grub.pbkdf2.sha512.10000.HEXDIGITS.MOREHEXDIGITS
|
||||||
|
|
||||||
|
Put this *before* the menuentries (just before) in `grub.cfg`, but note that
|
||||||
|
you should **not** literally use what is below; the hash below is not the one
|
||||||
|
you generated yourself. Make sure to adapt accordingly.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
set superusers="root"
|
||||||
|
password_pbkdf2 root grub.pbkdf2.sha512.10000.711F186347156BC105CD83A2ED7AF1EB971AA2B1EB2640172F34B0DEFFC97E654AF48E5F0C3B7622502B76458DA494270CC0EA6504411D676E6752FD1651E749.8DD11178EB8D1F633308FD8FCC64D0B243F949B9B99CCEADE2ECA11657A757D22025986B0FA116F1D5191E0A22677674C994EDBFADE62240E9D161688266A711
|
||||||
|
|
||||||
|
**Again**, replace it with the correct hash that you actually obtained for the
|
||||||
|
password you entered. In other words, *do not use the hash that you see above!*
|
||||||
|
|
||||||
|
GRUB will also ask for a username in addition to the password; the "root" user
|
||||||
|
is specified above, but you can cahnge it to whatever you want.
|
||||||
|
|
||||||
|
Unset superusers
|
||||||
|
================
|
||||||
|
|
||||||
|
Find this line in `grub.cfg`:
|
||||||
|
|
||||||
|
unset superusers
|
||||||
|
|
||||||
|
Change it to this:
|
||||||
|
|
||||||
|
# unset superusers
|
||||||
|
|
||||||
|
Commenting it, as shown above, ensures that password authentication works,
|
||||||
|
because `unset superusers` in fact disables passwordh authentication, so it's
|
||||||
|
very important that you comment out this line.
|
||||||
|
|
||||||
|
Disable the SeaBIOS menu
|
||||||
|
====================
|
||||||
|
|
||||||
|
**Very important. Make sure you read this carefully.**
|
||||||
|
|
||||||
|
In releases after Libreboot 20240504, SeaBIOS is the primary payload on
|
||||||
|
all images, but GRUB is available in the boot menu.
|
||||||
|
|
||||||
|
Do this:
|
||||||
|
|
||||||
|
cbfstool libreboot.rom add-int -i 0 -n etc/show-boot-menu
|
||||||
|
|
||||||
|
This disables the SeaBIOS menu, so that it only loads GRUB.
|
||||||
|
|
||||||
|
If your ROM image doesn't auto-start GRUB, you should also insert the
|
||||||
|
bootorder file:
|
||||||
|
|
||||||
|
cbfstool libreboot.rom add -f config/grub/bootorder -n bootorder -t raw
|
||||||
|
|
||||||
|
This `bootorder` file has the following contents:
|
||||||
|
|
||||||
|
```
|
||||||
|
/rom@img/grub2
|
||||||
|
```
|
||||||
|
|
||||||
|
Release images with `seagrub` in the name already have this bootorder file,
|
||||||
|
so you only need to disable the menu on these images. If you have the
|
||||||
|
image with `seabios` in the name (instead of `seagrub`), you must do both.
|
||||||
|
|
||||||
|
SeaBIOS option ROMs
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
SeaBIOS will also still execute PCI option ROMs. Depending on your preference,
|
||||||
|
you may wish to disable this, but please note that this will break certain
|
||||||
|
things like graphics cards. More information is available here:
|
||||||
|
|
||||||
|
<https://www.seabios.org/Runtime_config>
|
||||||
|
|
||||||
|
If you're using a graphics card, you *need* VGA option ROMs at least.
|
||||||
|
|
||||||
|
GPG keys
|
||||||
|
========
|
||||||
|
|
||||||
|
First, generate a GPG keypair to use for signing. Option RSA (sign only)
|
||||||
|
is ok.
|
||||||
|
|
||||||
|
WARNING: GRUB does not read ASCII armored keys. When attempting to
|
||||||
|
trust ASCII armor keys, it will print `error: bad signature` on the screen.
|
||||||
|
|
||||||
|
```
|
||||||
|
mkdir --mode 0700 keys
|
||||||
|
gpg --homedir keys --gen-key
|
||||||
|
gpg --homedir keys --export-secret-keys --armor > boot.secret.key # backup
|
||||||
|
gpg --homedir keys --export > boot.key
|
||||||
|
```
|
||||||
|
|
||||||
|
Now that we have a key, we can sign some files with it. We must sign:
|
||||||
|
|
||||||
|
- a kernel
|
||||||
|
- (if we have one) an initramfs
|
||||||
|
- (if we wish to transfer control to it) an on-disk `grub.cfg`
|
||||||
|
- `grubtest.cfg` in CBFS, if it exists
|
||||||
|
- `grub.cfg` in CBFS, if it exists
|
||||||
|
|
||||||
|
You must provide a *detached signature* alongside each file. For example, if
|
||||||
|
a file in a directory is named `foo`, and GRUB uses this file, an accompaning
|
||||||
|
file `foo.sig` must exist alongside it.
|
||||||
|
|
||||||
|
Suppose that we have a pair of `my.kernel`, `my.initramfs` and an
|
||||||
|
on-disk `grub.cfg`. We will sign them by running the following
|
||||||
|
commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
gpg --homedir keys --detach-sign my.initramfs
|
||||||
|
gpg --homedir keys --detach-sign my.kernel
|
||||||
|
gpg --homedir keys --detach-sign grub.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
You must also do the above on any file that goes in CBFS, and insert it
|
||||||
|
into CBFS, using instructions already provided on the GRUB CBFS guide linked
|
||||||
|
above, earlier on in this guide.
|
||||||
|
|
||||||
|
Enforce GPG check in GRUB
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The following must be present in `grub.cfg`, but please note that the
|
||||||
|
background image used by GRUB is in the memdisk by default, not CBFS, so you
|
||||||
|
might want to put it *after* the command that enables a background:
|
||||||
|
|
||||||
|
```
|
||||||
|
trust (cbfsdisk)/boot.key
|
||||||
|
set check_signatures=enforce
|
||||||
|
```
|
||||||
|
|
||||||
|
What remains now is to include the modifications into the libreboot image
|
||||||
|
(ROM):
|
||||||
|
|
||||||
|
Please read and follow the [GRUB configuration guide](grub_cbfs.md); this is
|
||||||
|
the GRUB CBFS guide that was also linked above, earlier on in the article
|
||||||
|
you're currently reading.
|
||||||
|
|
||||||
Install the new image
|
Install the new image
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -404,3 +291,10 @@ up just fine. Shut it down and wait a few seconds. If you screwed it up
|
||||||
and the system is now unbootable, that's OK because you can use an
|
and the system is now unbootable, that's OK because you can use an
|
||||||
external flasher; please
|
external flasher; please
|
||||||
read [external flashing instructions](../install/spi.md)
|
read [external flashing instructions](../install/spi.md)
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
* [GRUB manual](https://www.gnu.org/software/grub/manual/html_node/Security.html#Security)
|
||||||
|
* [GRUB info pages](http://git.savannah.gnu.org/cgit/grub.git/tree/docs/grub.texi)
|
||||||
|
* [Coreboot GRUB security howto](https://www.coreboot.org/GRUB2#Security)
|
||||||
|
|
Loading…
Reference in New Issue