2015-03-16 19:38:36 +00:00
# grub2-signing-extension for GRUB2
2015-03-17 06:23:23 +00:00
GRUB2 has got a function called "check\_signatures" which automatically checks if your GRUB2 files are signed and have a good signature. If the files aren't signed or have a bad signature GRUB2 won't run them to prevent running malicious software.
2015-03-16 19:38:36 +00:00
The GRUB2 signing extension are some scripts which helps you to verify, sign and unsign your GRUB2 bootloader files using gpg.
## Requirements
You need
* GRUB2 ( sys-boot/grub:2 )
2018-01-12 20:56:23 +00:00
* GNUpg >= 2.1 ( >= app-crypt/gnupg-2.1 )
2015-03-16 19:38:36 +00:00
2018-05-28 10:52:07 +00:00
## Installation
### Arch Linux (AUR)
- Import [Bandie's GPG key ](https://bandie.org/assets/bandie.pub.asc ) through running `gpg --recv-keys E2D7876915312785DC086BFCC1E133BC65A822DD` .
- Use your favourite AUR helper to install [grub2-signing-extension ](https://aur.archlinux.org/packages/grub2-signing-extension/ ).
### From github
- Import [Bandie's GPG key ](https://bandie.org/assets/bandie.pub.asc ) through running `gpg --recv-keys E2D7876915312785DC086BFCC1E133BC65A822DD` .
2018-08-05 19:57:48 +00:00
- Download the [grub2-signing-extension ](https://github.com/Bandie/grub2-signing-extension/releases/download/0.1.2/grub2-signing-extension-0.1.2.tar.gz ) and it's [signature ](https://github.com/Bandie/grub2-signing-extension/releases/download/0.1.2/grub2-signing-extension-0.1.2.tar.gz.asc ).
2018-05-28 10:52:07 +00:00
- Run `gpg --verify grub2-signing-extension*.tar.gz.asc` to make sure that everything is alright.
- Unpack the tar archive. `tar xvf grub2-signing-extension*.tar.gz`
- Change into the grub2-signing-extension directory.
- Run `make install` as root.
2019-12-11 18:49:09 +00:00
You will now have `grub-sign` , `grub-unsign` , `grub-verify` and `grub-update-kernel-signature` as runable scripts.
2018-05-28 10:52:07 +00:00
## Enabling GRUB2 check\_signatures feature
Before you can use the signing and verification feature you need to generate a keypair as root.
- Run `gpg --gen-key` as root. Please use a secure passphrase.
- Activate the `gpg-agent` for root so that you are able to sign and verify files in a `su` environment. To do that:
- Edit the file _/root/.gnupg/gpg.conf_ and add the line `use-agent` . Save the file.
- Create _/root/.gnupg/gpg-agent.conf_ with the following content
```
pinentry-program /usr/bin/pinentry-curses
no-grab
default-cache-ttl 1800
```
- Export your public key through running `gpg --export -o ~/pubkey` .
- `mount /boot` (assuming your /boot partition is in your /etc/fstab)
2020-01-25 10:17:05 +00:00
- (Re)install GRUB2. The following command will install root's public key into the core and instruct to load the modules `gcry_sha256` , `gcry_sha512` `gcry_dsa` and `gcry_rsa` at start so that GRUB2 will be able to do verifications. GRUB2 will take the right crypto for you then, depending on your system's configuration.
2018-05-28 10:52:07 +00:00
- `grub-install /dev/sda -k /root/pubkey --modules="gcry_sha256 gcry_dsa gcry_rsa"`
- Enable GRUB2's check\_signatures feature:
- Insert the following content at the end of the file of */etc/grub.d/00_header*
```
cat < < EOF
set check_signatures=enforce
EOF
```
- Run`grub-mkconfig -o /boot/grub/grub.cfg` to make the new configuration valid.
2019-12-11 18:49:09 +00:00
- Sign your bootloader running `grub-sign` and enter your GPG passphrase.
2018-05-28 10:52:07 +00:00
**It is also recommended to install a password in GRUB2! [See ADDENDUM]**
## How to update the signatures on changes
2018-01-17 23:56:00 +00:00
2019-12-11 18:49:09 +00:00
On every change at the GRUB2 core files you need to run `grub-unsign` first before you make your changes. Please notice, if you reinstall GRUB2, you should do it as it is said above. Otherwise the signature check won't work.
2018-01-17 23:56:00 +00:00
2019-12-11 18:49:09 +00:00
If you do some changes or updates for the kernel or initramfs, you may want to use `grub-update-kernel-signature` instead.
2018-01-17 23:56:00 +00:00
2015-03-16 20:43:11 +00:00
## Files
If you didn't read the instruction above here is what the scripts does:
2019-12-11 18:49:09 +00:00
* `grub-sign` is signing the bootloader files with root's keypair.
* `grub-unsign` is removing the signatures of the bootloader files.
* `grub-verify` is checking if your signatures are good. If not, you will see which signature is bad.
* `grub-update-kernel-signature` is renewing the signatures in /boot/ (without subdirs) and grub.cfg, regardless if grub-verify fails.
2015-03-16 20:43:11 +00:00
2018-03-22 12:47:16 +00:00
## Exit codes
2019-12-11 18:49:09 +00:00
You might be interested in the exit codes of `grub-verify` to use it in your monitoring tools:
2018-03-22 12:47:16 +00:00
```
0 - Everything is okay
1 - Found bad signatures
2 - No signatures found at all [GRUB2 is completely unsigned]
3 - Missing signatures [There are correct signatures but some files are unsigned]
```
2015-03-16 20:43:11 +00:00
## Troubleshooting
2018-03-22 13:50:46 +00:00
### I receive an error
#### gpg: signing failed: Permission denied
2018-03-22 13:48:38 +00:00
2018-03-22 13:52:14 +00:00
Make sure that the tty you are in belongs to you (root). Do:
```
chown root:root $(tty)
```
2018-03-22 13:50:46 +00:00
2018-03-22 13:48:38 +00:00
2015-03-16 20:43:11 +00:00
### I forgot to run grub2-unsign before I made changes. What now?
2019-12-11 18:49:09 +00:00
Run `grub-verify` to see, which signature is bad. Remove the signature and run `grub-unsign` , after this `grub-sign` .
Alternatively, if you just updated your kernel/initramfs/grub.cfg, run `grub-update-kernel-signatures` .
2015-03-16 20:43:11 +00:00
2018-01-17 23:56:00 +00:00
### How can I switch off GRUB2's check\_signature feature?
2015-03-16 20:43:11 +00:00
Open */etc/grub.d/00_header* and remove the part
cat < < EOF
set check_signatures=enforce
EOF
2019-12-11 18:49:09 +00:00
Run `grub-unsign` and `grub-mkconfig -o /boot/grub/grub.cfg` .
2015-03-16 20:43:11 +00:00
2018-01-17 23:56:00 +00:00
Also you should reinstall grub2, using something like `grub-install /dev/sda` .
2015-03-16 20:43:11 +00:00
### Suddenly I can't boot! This is YOUR FAULT!
No. An important signature is bad. So GRUB2 didn't run this part of code/configuration/kernel/whatever.
2019-12-11 18:49:09 +00:00
You could do a chroot using an USB dongle with a GNU/Linux distribution on it. If you're chrooted to your system run `grub-verify` .
If you think this happened through an update shortly done by you, you may want to run `gpg-agent --daemon ; grub-update-kernel-signatures` .
2015-03-16 20:43:11 +00:00
2018-01-17 23:56:00 +00:00
### Okay, I really got some bad signatures not caused by me. What do I do now?
2015-03-16 20:43:11 +00:00
2018-01-17 23:56:00 +00:00
Check your system thoroughly. Check it about malicious software. Check it about malicious connections. CHECK EVERYTHING.
2015-03-16 20:43:11 +00:00
# ADDENDUM
2015-03-16 19:38:36 +00:00
## How to install a GRUB2 password
2018-05-28 10:52:07 +00:00
- Generate a GRUB2 password string through running `grub-mkpasswd-pbkdf2` . Please take care because in the GRUB2 standard installation the keyboard layout is set to en\_US.
- Copy the generated *grub.pbkdf2.[...]* string to your clipboard.
- Open the file */etc/grub.d/00_header* and insert this at the end of the file
```
2015-03-16 19:38:36 +00:00
cat < < EOF
set superusers="yourUsername"
export superusers
2018-05-28 10:52:07 +00:00
password_pbkdf2 yourUsername [...this grub.pbkdf2.* string from the clipboard...]
2015-03-16 19:38:36 +00:00
EOF
2018-05-28 10:52:07 +00:00
```
- To boot GNU/Linux automatically and without authentication open */etc/grub.d/10_linux* and change the following lines from
```
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
2015-03-16 19:38:36 +00:00
else
2018-05-28 10:52:07 +00:00
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
2015-03-16 19:38:36 +00:00
fi
2018-05-28 10:52:07 +00:00
```
to
2015-03-16 19:38:36 +00:00
2018-05-28 10:52:07 +00:00
```
echo "menuentry '$(echo "$title" | grub_quote)' --unrestricted ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
2015-03-16 19:38:36 +00:00
else
2018-05-28 10:52:07 +00:00
echo "menuentry '$(echo "$os" | grub_quote)' --unrestricted ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
2015-03-16 19:38:36 +00:00
fi
2018-05-28 10:52:07 +00:00
```
The important changing is the flag *--unrestricted* .
2019-12-11 18:49:09 +00:00
- Run `grub-unsign` to unsign the bootloader.
2018-05-28 10:52:07 +00:00
- Run `grub-mkconfig -o /boot/grub/grub.cfg` to write the new config.
2019-12-11 18:49:09 +00:00
- Run `grub-sign` to sign the new changings.