346 lines
14 KiB
ReStructuredText
346 lines
14 KiB
ReStructuredText
|
|
.. fyl1552681364538
|
|
.. _use-uefi-secure-boot:
|
|
|
|
====================
|
|
Use UEFI Secure Boot
|
|
====================
|
|
|
|
Secure Boot is supported in |UEFI| installations only. It is not used when
|
|
booting |prod| as a legacy boot target.
|
|
|
|
|prod| currently does not support switching from legacy to |UEFI| mode after a
|
|
system has been installed. Doing so requires a reinstall of the system. This
|
|
also means that upgrading from a legacy install to a secure boot install
|
|
\(UEFI) is not supported.
|
|
|
|
When upgrading a |prod| system from a version which does not support secure
|
|
boot to a version that does, do not enable secure boot in |UEFI| firmware until
|
|
the upgrade is complete.
|
|
|
|
For each node that is going to use secure boot, you must populate the |prod|
|
|
public certificate/key in the |UEFI| Secure Boot authorized database in
|
|
accordance with the board manufacturer's process. This must be done for each
|
|
node before starting installation.
|
|
|
|
You may need to work with your hardware vendor to have the certificate
|
|
installed.
|
|
|
|
There is often an option in the UEFI setup utility which allows a user to
|
|
browse to a file containing a certificate to be loaded in the authorized
|
|
database. This option may be hidden in the UEFI setup utility unless UEFI
|
|
mode is enabled, and secure boot is enabled.
|
|
|
|
Many motherboards ship with Microsoft secure boot certificates
|
|
pre-programmed in the |UEFI| certificate database. These certificates may be
|
|
required to boot |UEFI| drivers for video cards, RAID controllers, or NICs
|
|
\(for example, the |PXE| boot software for a NIC may have been signed by a
|
|
Microsoft certificate). While certificates can usually be removed from the
|
|
certificate database (again, this is UEFI implementation specific) it
|
|
may be required that you keep the Microsoft certificates to allow for
|
|
complete system operation.
|
|
|
|
Mixed combinations of secure boot and non-secure boot nodes are supported.
|
|
For example, a controller node may secure boot, while a worker node may not.
|
|
Secure boot must be enabled in the |UEFI| firmware of each node for that node
|
|
to be protected by secure boot.
|
|
|
|
.. only:: partner
|
|
|
|
.. include:: /_includes/extract-certificate-from-iso-181be684e2e5.rest
|
|
|
|
.. only:: starlingx
|
|
|
|
------------------------------------------------------------------------------
|
|
Build considerations for signing packages for UEFI Secure Boot -- CentOS build
|
|
------------------------------------------------------------------------------
|
|
|
|
The |prod| build environment has provisions for calling out to a signing
|
|
server for purposes of creating a secure boot load. At this time |prod|
|
|
does not include an implementation of the signing server. The following
|
|
describes how the signing process is intended to work in the context of a
|
|
CentOS build. You may find it helpful in implementing your own signing
|
|
server.
|
|
|
|
The following environmental variables should be defined before attempting
|
|
to request a secure boot signing:
|
|
|
|
.. code-block:: none
|
|
|
|
export SIGNING_SERVER=<signing-host>
|
|
export SIGNING_USER=<signing-user>
|
|
export SIGNING_SERVER_SCRIPT=<path-to-signing-script>
|
|
|
|
'build-pkgs' further requires that "$USER" == "jenkins", and
|
|
|
|
export FORMAL_BUILD=1
|
|
|
|
If the above criteria is met, it calls into ``sign-secure-boot``.
|
|
|
|
This is an example of the call sequence:
|
|
|
|
.. code-block:: none
|
|
|
|
# Set up the server side directory for files transfers.
|
|
UPLOAD_PATH=`ssh $SIGNING_USER@$SIGNING_SERVER sudo $SIGNING_SCRIPT -r`
|
|
|
|
# upload the original package
|
|
scp -q $FILE $SIGNING_USER@$SIGNING_SERVER:$UPLOAD_PATH
|
|
|
|
# Request that the package be signed
|
|
ssh $SIGNING_USER@$SIGNING_SERVER sudo $SIGNING_SCRIPT -v -i $UPLOAD_PATH/$(basename $FILE) $UNSIGNED_OPTION -t $TYPE > $TMPFILE
|
|
|
|
# Download the file from the signing server
|
|
DOWNLOAD_FILENAME=$(basename $OUTPUT_FILE)
|
|
scp -q $SIGNING_USER@$SIGNING_SERVER:$OUTPUT_FILE $(dirname $FILE)
|
|
|
|
|
|
Within the signing server there are two keys used for signing, known as
|
|
the `boot` key and the `shim` key. The public half of the `boot` key
|
|
must be manually added to the secure boot keychain in the firmware. The
|
|
`boot` key signs the first executable loaded, contained in the `shim`
|
|
package. The first executable must then install the public half of the
|
|
`shim` key (automatically) before passing control to the grub, and
|
|
ultimately the kernel, both of which are signed by the private `shim`
|
|
key.
|
|
|
|
Three packages need to be passed to the signing server. The RPMs need
|
|
to be unpacked, the relevant binaries signed with the correct keys, and
|
|
the RPMs reassembled.
|
|
|
|
.. code-block:: none
|
|
|
|
package key files to sign
|
|
========= ==== ===========================
|
|
shim boot BOOTX64, shim, shimx64
|
|
shim MokManager, fallback, mmx64, fbx64
|
|
grub shim grubx64.efi, gcdx64.efi
|
|
kernel shim
|
|
|
|
.. note::
|
|
|
|
`shim` files that are required to be signed might might include a ``.efi``
|
|
or ``.EFI`` suffix.
|
|
|
|
Some files may be absent in newer packages.
|
|
|
|
Example:
|
|
|
|
.. code-block:: none
|
|
|
|
sbsign --key $KEYPATH/$KEYNAME.key --cert $KEYPATH/$KEYNAME.crt --output $SIGNEDFILE $UNSIGNEDFILE
|
|
|
|
Keys and certificates:
|
|
|
|
.. code-block:: none
|
|
|
|
boot.crt - Certificate to boot (to be programmed in firmware)
|
|
boot.key - Private key with which to sign shim
|
|
shim.crt - Certificated embedded within shim used to validate kernel, grub
|
|
shim.key - Private key with which to sign kernel/grub
|
|
|
|
Key generation:
|
|
|
|
.. code-block:: none
|
|
|
|
openssl req -new -x509 -newkey rsa:2048 -keyout $KEY.key -out $KEY.pem -days 3650
|
|
openssl x509 -in $KEY.pem -out $KEY.crt -outform DER
|
|
|
|
.. note::
|
|
|
|
``boot.crt`` should be copied to
|
|
``cgcs-root/build-tools/certificates/TiBoot.crt`` for inclusion during the
|
|
``build-iso`` step.
|
|
|
|
------------------------------------------------------------------------------
|
|
Build considerations for signing packages for UEFI Secure Boot -- Debian build
|
|
------------------------------------------------------------------------------
|
|
|
|
The |prod| build environment has provisions for calling out to a signing
|
|
server for purposes of creating a secure boot load. At this time |prod|
|
|
does not include an implementation of the signing server. The following
|
|
describes how the signing process is intended to work in the context of a
|
|
``Debian`` build. You may find it helpful in implementing your own signing
|
|
server.
|
|
|
|
The secure boot verification sequence of StarlingX Debian is:
|
|
UEFI firmware verify shim image;
|
|
shim verify grub image;
|
|
grub verify kernel image and initramfs image.
|
|
|
|
Bootloader shim will enroll the public key to verify grub image.
|
|
Bootloader grub-efi will enroll the public key to verify kernel and initramfs image.
|
|
|
|
The following process should be followed to request a secure boot signing:
|
|
|
|
.. code-block:: none
|
|
|
|
......
|
|
stx control keys-add --key-type=signing-server --key=[key file]
|
|
stx shell
|
|
downloader
|
|
build-pkgs
|
|
export SIGNING_SERVER="signing_user@signing_server_ip"
|
|
sign-secure-boot_debian
|
|
build-image
|
|
|
|
The "key file" is the private key generated by "ssh-keygen -t rsa"
|
|
and used to setup signing server access without password.
|
|
|
|
The signing script ``sign-secure-boot_debian`` does secure boot signing for
|
|
|prod| Debian in this way:
|
|
|
|
.. code-block:: none
|
|
|
|
(1) Sign shim / grub images
|
|
The shim/grub efi images are obtained from extracted shim/grub
|
|
packages, and they are sent to signing server and signed there and
|
|
copied back. Then the shim/grub packages are repacked with the
|
|
signed efi images.
|
|
|
|
(2) Sign kernel images and LockDown.efi
|
|
The file sign_rootfs-post-scripts is inserted to where the
|
|
hook script "rootfs-post-scripts" is defined in the LAT config file
|
|
base-bullseye.yaml. This will sign kernel images and LockDown.efi
|
|
on signing server in the LAT build process.
|
|
The "rootfs-post-scripts" is the hook in LAT tool running after rootfs
|
|
is created.
|
|
|
|
(3) Sign initramfs and mini initrd
|
|
The file sign_initramfs-sign-script is inserted to where the hook
|
|
script "initramfs-sign-script" is defined in the LAT config file
|
|
base-bullseye.yaml. This will sign initramfs and mini initrd on signing server in
|
|
the LAT build process.
|
|
The "initramfs-sign-script" is the hook in LAT tool running after initramfs
|
|
is created.
|
|
|
|
Above (2) and (3) prepare the signing codes in LAT config file.
|
|
After build-image is triggered, the signing codes inserted in LAT config files will
|
|
run on LAT container in the right sequence.
|
|
|
|
Here is an example for signing an image file in sign-secure-boot_debian:
|
|
|
|
.. code-block:: none
|
|
|
|
# Request upload path from signing server.
|
|
REQUEST=$(ssh ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER} sudo /opt/signing/sign-debian.sh -r)
|
|
UPLOAD_PATH=${REQUEST#*Upload: }
|
|
|
|
# Copy shimx64.efi to signing server
|
|
scp ${SSH_OPTION_NOCHECKING} shimx64.efi ${SIGNING_SERVER}:${UPLOAD_PATH}
|
|
# Sign shimx64.efi
|
|
ssh ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER} sudo /opt/signing/sign-debian.sh -i ${UPLOAD_PATH}/shimx64.efi -t shim
|
|
# Copy back signed shimx64.efi which is renamed as bootx64.efi
|
|
sudo scp ${SSH_OPTION_NOCHECKING} ${SIGNING_SERVER}:${UPLOAD_PATH}/bootx64.efi ./
|
|
|
|
The sign-debian.sh in above code is the script running on signing server whose interface
|
|
is defined as below:
|
|
|
|
.. code-block:: none
|
|
|
|
Usage:
|
|
sign-debian.sh [options]
|
|
|
|
[-i <file>] - input unsigned file
|
|
[-t <type>] - type of signing to do
|
|
[-r] - request an upload path
|
|
|
|
Types of signing:
|
|
-t shim - signs a shim EFI binary with the boot key
|
|
-t grub - signs a GRUB EFI binary with the shim key
|
|
-t shimtool - signs a shim tool EFI binary with the shim key
|
|
-t grub-gpg - signs a kernel/initrd/grub.cfg with the grub gpg key
|
|
|
|
|
|
Keys management:
|
|
|
|
.. code-block:: none
|
|
|
|
Upstream stx public keys repo: https://opendev.org/starlingx/public-keys
|
|
|
|
The keys under cgcs-root/public-keys are the public keys used in
|
|
the verification process of secure boot process for StarlingX
|
|
Debian.
|
|
|
|
Keys Introduction:
|
|
tis-boot.crt: it is the public key flashed into UEFI to verify
|
|
bootx64.efi (signed shim image shimx64.efi);
|
|
tis-shim.der: it is the public key used by shim to verify
|
|
grubx64.efi (signed grub image) and mmx64.efi
|
|
(signed shim tool image);
|
|
boot_pub_key: it is the public key used by grub to verify signed
|
|
kernel image and initramfs image and efitools image and so on.
|
|
TiBoot.crt: it is the same pub key with tis-boot.crt (pem) as a
|
|
der format. It is installed as /CERTS/TiBoot.crt in the efi.img
|
|
which is in the iso image.
|
|
|
|
The following ways can be used to create substitute keys:
|
|
(1)example to create tis-boot.crt/TiBoot.crt
|
|
openssl req -new -x509 -newkey rsa:2048 -keyout BOOT.priv -outform DER -out BOOT.der -days 36500 -subj "/CN=My Boot/" -nodes
|
|
openssl x509 -inform der -in BOOT.der -out BOOT.pem
|
|
cp BOOT.pem tis-boot.crt
|
|
cp BOOT.priv tis-boot.key
|
|
cp BOOT.der TiBoot.crt
|
|
The tis-boot.crt and tis-boot.key are used to sign images mentioned above (shim image).
|
|
|
|
The tis-shim.crt/tis-shim.der/tis-shim.key can be created in the same way, and used to sign images mentioned above (grub image and shim tool image).
|
|
|
|
(2)example to create boot_pub_key
|
|
|
|
#!/bin/bash
|
|
key_dir="./"
|
|
priv_key="${key_dir}/BOOT-GPG-PRIVKEY-SecureBootCore"
|
|
pub_key="${key_dir}/BOOT-GPG-KEY-SecureBootCore"
|
|
name_real="SecureBootCore"
|
|
pw="PASSWORD"
|
|
USE_PW="Passphrase: PASSWORD"
|
|
cat >"${key_dir}/gen_keyring" <<EOF
|
|
Key-Type: RSA
|
|
Key-Length: 4096
|
|
Name-Real: ${name_real}
|
|
Name-Comment: EXAMPLE
|
|
Name-Email: a@b.com
|
|
Expire-Date: 0
|
|
${USE_PW}
|
|
%commit
|
|
%echo keyring ${name_real} created
|
|
EOF
|
|
|
|
gpg --homedir "${key_dir}" --batch --yes --gen-key "${key_dir}/gen_keyring"
|
|
gpg --homedir "${key_dir}" -k
|
|
gpg --homedir "${key_dir}" --export --armor "${name_real}" > "${pub_key}"
|
|
gpg --homedir "${key_dir}" --export-secret-keys --pinentry-mode=loopback --passphrase "${pw}" --armor "${name_real}" > "${priv_key}"
|
|
gpg --homedir "${key_dir}" --export "${name_real}" > ${key_dir}/boot_pub_key
|
|
|
|
The BOOT-GPG-PRIVKEY-SecureBootCore is used to sign images mentioned above (kernel image and initramfs image and efitools image and so on).
|
|
|
|
Signing commands to sign image files:
|
|
|
|
.. code-block:: none
|
|
|
|
Signing command to sign type shim/grub/shimtool image files:
|
|
sbsign --key $KEYPATH/$KEYNAME.key \
|
|
--cert $KEYPATH/$KEYNAME.crt \
|
|
--output $SIGNEDFILE \
|
|
$UNSIGNEDFILE
|
|
|
|
for "-t shim", the output file name is bootx64.efi;
|
|
for "-t grub", the output file name is grubx64.efi;
|
|
for "-t shimtool", the output file name is ${UNSIGNEDFILE}.signed.
|
|
|
|
Signing command to sign type grub-gpg files:
|
|
gpg2 --batch \
|
|
--homedir ${GPGHOME} \
|
|
--passphrase PASSWORD \
|
|
--import ${KEYPATH}/${BOOT_GPG_PRI_KEY}
|
|
echo 'PASSWORD' | \
|
|
gpg2 --pinentry-mode loopback \
|
|
--batch \
|
|
--homedir ${GPGHOME} \
|
|
-u SecureBootCore \
|
|
--detach-sign \
|
|
--passphrase-fd 0 \
|
|
${FILEIN}
|
|
|
|
Please pay attention to the keys they should use according to [Keys management] section.
|