mirror of
https://github.com/systemd/systemd.git
synced 2024-12-27 07:22:31 +03:00
Merge pull request #26287 from medhefgo/mkosi-auto-enroll
ci: Test with secure boot enabled under mkosi
This commit is contained in:
commit
e5cf396181
5
.github/workflows/mkosi.yml
vendored
5
.github/workflows/mkosi.yml
vendored
@ -95,8 +95,11 @@ jobs:
|
||||
KernelCommandLine=${{ env.KERNEL_CMDLINE }}
|
||||
EOF
|
||||
|
||||
- name: Generate secure boot key
|
||||
run: sudo mkosi genkey
|
||||
|
||||
- name: Build ${{ matrix.distro }}
|
||||
run: sudo mkosi --idmap no
|
||||
run: sudo mkosi --idmap no --secure-boot
|
||||
|
||||
- name: Show ${{ matrix.distro }} image summary
|
||||
run: sudo mkosi summary
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -33,6 +33,7 @@ __pycache__/
|
||||
/mkosi.output/
|
||||
/mkosi.default
|
||||
/mkosi.installdir/
|
||||
/mkosi.secure-boot.*
|
||||
# Ignore any mkosi config files with "local" in the name
|
||||
/mkosi.default.d/**/*local*.conf
|
||||
/tags
|
||||
|
@ -227,12 +227,33 @@
|
||||
|
||||
<listitem><para>Danger: this feature might soft-brick your device if used improperly.</para>
|
||||
|
||||
<para>Takes one of <literal>off</literal>, <literal>manual</literal> or <literal>force</literal>.
|
||||
Controls the enrollment of Secure Boot keys. If set to <literal>off</literal>, no action whatsoever
|
||||
is taken. If set to <literal>manual</literal> (the default) and the UEFI firmware is in setup-mode
|
||||
then entries to manually enroll Secure Boot variables are created in the boot menu. If set to
|
||||
<literal>force</literal>, in addition, if a directory named <filename>/loader/keys/auto/</filename>
|
||||
exists on the ESP then the keys in that directory are enrolled automatically.</para>
|
||||
<para>Controls enrollment of secure boot keys found on the ESP if the system is in setup mode:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>off</option></term>
|
||||
<listitem><para>No action is taken.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>manual</option></term>
|
||||
<listitem><para>Boot entries for found secure boot keys are created that allow manual
|
||||
enrollment.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>if-safe</option></term>
|
||||
<listitem><para>Same behavior as <option>manual</option>, but will try to automatically
|
||||
enroll the key <literal>auto</literal> if it is considered to be safe. Currently, this is only
|
||||
the case if the system is running inside a virtual machine.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>force</option></term>
|
||||
<listitem><para>Always enroll the <literal>auto</literal> key if found. Note that a warning
|
||||
message with a timeout will still be shown if this operation is unknown to be safe.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>The different sets of variables can be set up under
|
||||
<filename>/loader/keys/<replaceable>NAME</replaceable></filename> where
|
||||
@ -254,8 +275,8 @@
|
||||
<programlisting>uuid=$(systemd-id128 new --uuid)
|
||||
for key in PK KEK db; do
|
||||
openssl req -new -x509 -subj "/CN=${key}/" -keyout "${key}.key" -out "${key}.crt"
|
||||
openssl x509 -outform DER -in "${key}.crt" -out "${key}.cer"
|
||||
cert-to-efi-sig-list -g "${uuid}" "${key}.crt" "${key}.esl"
|
||||
openssl x509 -outform DER -in "${key}.crt" -out "${key}.der"
|
||||
sbsiglist --owner "${uuid}" --type x509 --output "${key}.esl" "${key}.der"
|
||||
done
|
||||
|
||||
for key in MicWinProPCA2011_2011-10-19.crt MicCorUEFCA2011_2011-06-27.crt MicCorKEKCA2011_2011-06-24.crt; do
|
||||
@ -266,7 +287,7 @@ done
|
||||
# Optionally add Microsoft Windows Production CA 2011 (needed to boot into Windows).
|
||||
cat MicWinProPCA2011_2011-10-19.esl >> db.esl
|
||||
|
||||
# Optionally add Microsoft Corporation UEFI CA 2011 (for firmware drivers / option ROMs
|
||||
# Optionally add Microsoft Corporation UEFI CA 2011 for firmware drivers / option ROMs
|
||||
# and third-party boot loaders (including shim). This is highly recommended on real
|
||||
# hardware as not including this may soft-brick your device (see next paragraph).
|
||||
cat MicCorUEFCA2011_2011-06-27.esl >> db.esl
|
||||
@ -276,9 +297,10 @@ cat MicCorUEFCA2011_2011-06-27.esl >> db.esl
|
||||
# key. The revocation database can be updated with <citerefentry><refentrytitle>fwupdmgr</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||
cat MicCorKEKCA2011_2011-06-24.esl >> KEK.esl
|
||||
|
||||
sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth
|
||||
sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth
|
||||
sign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth
|
||||
attr=NON_VOLATILE,RUNTIME_ACCESS,BOOTSERVICE_ACCESS,TIME_BASED_AUTHENTICATED_WRITE_ACCESS
|
||||
sbvarsign --attr ${attr} --key PK.key --cert PK.crt --output PK.auth PK PK.esl
|
||||
sbvarsign --attr ${attr} --key PK.key --cert PK.crt --output KEK.auth KEK KEK.esl
|
||||
sbvarsign --attr ${attr} --key KEK.key --cert KEK.crt --output db.auth db db.esl
|
||||
</programlisting>
|
||||
|
||||
<para>This feature is considered dangerous because even if all the required files are signed with the
|
||||
|
@ -526,6 +526,9 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
|
||||
case ENROLL_MANUAL:
|
||||
printf(" secure-boot-enroll: manual\n");
|
||||
break;
|
||||
case ENROLL_IF_SAFE:
|
||||
printf(" secure-boot-enroll: if-safe\n");
|
||||
break;
|
||||
case ENROLL_FORCE:
|
||||
printf(" secure-boot-enroll: force\n");
|
||||
break;
|
||||
@ -1259,6 +1262,8 @@ static void config_defaults_load_from_file(Config *config, char *content) {
|
||||
config->secure_boot_enroll = ENROLL_MANUAL;
|
||||
else if (streq8(value, "force"))
|
||||
config->secure_boot_enroll = ENROLL_FORCE;
|
||||
else if (streq8(value, "if-safe"))
|
||||
config->secure_boot_enroll = ENROLL_IF_SAFE;
|
||||
else if (streq8(value, "off"))
|
||||
config->secure_boot_enroll = ENROLL_OFF;
|
||||
else
|
||||
@ -1572,7 +1577,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
|
||||
.auto_entries = true,
|
||||
.auto_firmware = true,
|
||||
.reboot_for_bitlocker = false,
|
||||
.secure_boot_enroll = ENROLL_MANUAL,
|
||||
.secure_boot_enroll = ENROLL_IF_SAFE,
|
||||
.idx_default_efivar = IDX_INVALID,
|
||||
.console_mode = CONSOLE_MODE_KEEP,
|
||||
.console_mode_efivar = CONSOLE_MODE_KEEP,
|
||||
@ -2511,10 +2516,11 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir)
|
||||
};
|
||||
config_add_entry(config, entry);
|
||||
|
||||
if (config->secure_boot_enroll == ENROLL_FORCE && strcaseeq16(dirent->FileName, u"auto"))
|
||||
if (IN_SET(config->secure_boot_enroll, ENROLL_IF_SAFE, ENROLL_FORCE) &&
|
||||
strcaseeq16(dirent->FileName, u"auto"))
|
||||
/* if we auto enroll successfully this call does not return, if it fails we still
|
||||
* want to add other potential entries to the menu */
|
||||
secure_boot_enroll_at(root_dir, entry->path);
|
||||
secure_boot_enroll_at(root_dir, entry->path, config->secure_boot_enroll == ENROLL_FORCE);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@ -2700,7 +2706,7 @@ static EFI_STATUS run(EFI_HANDLE image) {
|
||||
|
||||
/* if auto enrollment is activated, we try to load keys for the given entry. */
|
||||
if (entry->type == LOADER_SECURE_BOOT_KEYS && config.secure_boot_enroll != ENROLL_OFF) {
|
||||
err = secure_boot_enroll_at(root_dir, entry->path);
|
||||
err = secure_boot_enroll_at(root_dir, entry->path, /*force=*/ true);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
continue;
|
||||
|
@ -36,7 +36,7 @@ SecureBootMode secure_boot_mode(void) {
|
||||
static const char sbat[] _used_ _section_(".sbat") = SBAT_SECTION_TEXT;
|
||||
#endif
|
||||
|
||||
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
|
||||
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force) {
|
||||
assert(root_dir);
|
||||
assert(path);
|
||||
|
||||
@ -44,11 +44,16 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) {
|
||||
|
||||
clear_screen(COLOR_NORMAL);
|
||||
|
||||
printf("Enrolling secure boot keys from directory: %ls\n", path);
|
||||
|
||||
/* Enrolling secure boot keys is safe to do in virtualized environments as there is nothing
|
||||
* we can brick there. */
|
||||
if (!in_hypervisor()) {
|
||||
bool is_safe = in_hypervisor();
|
||||
|
||||
if (!is_safe && !force)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
printf("Enrolling secure boot keys from directory: %ls\n", path);
|
||||
|
||||
if (!is_safe) {
|
||||
printf("Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n");
|
||||
|
||||
unsigned timeout_sec = 15;
|
||||
|
@ -9,13 +9,14 @@
|
||||
typedef enum {
|
||||
ENROLL_OFF, /* no Secure Boot key enrollment whatsoever, even manual entries are not generated */
|
||||
ENROLL_MANUAL, /* Secure Boot key enrollment is strictly manual: manual entries are generated and need to be selected by the user */
|
||||
ENROLL_IF_SAFE, /* Automatically enroll if it is safe (if we are running inside a VM, for example). */
|
||||
ENROLL_FORCE, /* Secure Boot key enrollment may be automatic if it is available but might not be safe */
|
||||
} secure_boot_enroll;
|
||||
|
||||
bool secure_boot_enabled(void);
|
||||
SecureBootMode secure_boot_mode(void);
|
||||
|
||||
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path);
|
||||
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force);
|
||||
|
||||
typedef bool (*security_validator_t)(
|
||||
const void *ctx,
|
||||
|
@ -3,6 +3,12 @@
|
||||
|
||||
systemctl --failed --no-legend | tee /failed-services
|
||||
|
||||
# Check that secure boot keys were properly enrolled.
|
||||
if [[ -d /sys/firmware/efi/efivars/ ]]; then
|
||||
cmp /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\1')
|
||||
cmp /sys/firmware/efi/efivars/SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\0')
|
||||
fi
|
||||
|
||||
# Exit with non-zero EC if the /failed-services file is not empty (we have -e set)
|
||||
[[ ! -s /failed-services ]]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user