T861: add UEFI Secure Boot support

This adds support for UEFI Secure Boot. It adds the missing pieces to the Linux
Kernel and enforces module signing. This results in an additional security
layer where untrusted (unsigned) Kernel modules can no longer be loaded into
the live system.

NOTE: This commit will not work unless signing keys are present. Arbitrary
keys can be generated using instructions found in:

  data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md
This commit is contained in:
Christian Breunig 2024-09-04 21:37:11 +02:00
parent beb3df0733
commit fd737172f1
9 changed files with 240 additions and 36 deletions

8
.gitignore vendored
View File

@ -5,6 +5,8 @@ packer_cache/*
key/* key/*
packages/* packages/*
!packages/*/ !packages/*/
testinstall*.img data/live-build-config/includes.chroot/var/lib/shim-signed/mok/*
*.qcow2 /testinstall*.img
*.tar /testinstall*.efivars
/*.qcow2
/*.tar

View File

@ -38,6 +38,11 @@ testc: checkiso
testraid: checkiso testraid: checkiso
scripts/check-qemu-install --debug --configd --raid build/live-image-amd64.hybrid.iso $(filter-out $@,$(MAKECMDGOALS)) scripts/check-qemu-install --debug --configd --raid build/live-image-amd64.hybrid.iso $(filter-out $@,$(MAKECMDGOALS))
.PHONY: testsb
.ONESHELL:
testsb: checkiso
scripts/check-qemu-install --debug --uefi --sbtest build/live-image-amd64.hybrid.iso $(filter-out $@,$(MAKECMDGOALS))
.PHONY: testtpm .PHONY: testtpm
.ONESHELL: .ONESHELL:
testtpm: checkiso testtpm: checkiso

View File

@ -0,0 +1,18 @@
#!/bin/sh
SIGN_FILE=$(find /usr/lib -name sign-file)
MOK_KEY="/var/lib/shim-signed/mok/kernel.key"
MOK_CERT="/var/lib/shim-signed/mok/kernel.pem"
kernel_elf=$(readlink /boot/vmlinuz)
if [ ! -f ${MOK_KEY} ]; then
echo "I: Signing key for Linux Kernel not found - Secure Boot not possible"
else
echo "I: Signing Linux Kernel for Secure Boot"
sbsign --key $MOK_KEY --cert $MOK_CERT /boot/${kernel_elf} --output /boot/${kernel_elf}
sbverify --list /boot/${kernel_elf}
find /lib/modules -type f -name \*.ko -o -name \*.ko.xz | while read module; do
$SIGN_FILE sha512 $MOK_KEY $MOK_CERT $module
done
fi

View File

@ -0,0 +1,22 @@
# Secure Boot
## CA
Create Certificate Authority used for Kernel signing. CA is loaded into the
Machine Owner Key store on the target system.
```bash
openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -outform DER -out MOK.der -days 36500 -subj "/CN=VyOS Secure Boot CA/" -nodes
openssl x509 -inform der -in MOK.der -out MOK.pem
```
## Kernel Module Signing Key
We do not make use of ephemeral keys for Kernel module signing. Instead a key
is generated and signed by the VyOS Secure Boot CA which signs all the Kernel
modules during ISO assembly if present.
```bash
openssl req -newkey rsa:2048 -keyout kernel.key -out kernel.csr -subj "/CN=VyOS Secure Boot Signer 2024 - linux/" -nodes
openssl x509 -req -in kernel.csr -CA MOK.pem -CAkey MOK.key -CAcreateserial -out kernel.pem -days 730 -sha256
```

View File

@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/x86 6.6.16 Kernel Configuration # Linux/x86 6.6.48 Kernel Configuration
# #
CONFIG_CC_VERSION_TEXT="gcc (Debian 12.2.0-14) 12.2.0" CONFIG_CC_VERSION_TEXT="gcc (Debian 12.2.0-14) 12.2.0"
CONFIG_CC_IS_GCC=y CONFIG_CC_IS_GCC=y
@ -15,6 +15,7 @@ CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_TOOLS_SUPPORT_RELR=y
CONFIG_CC_HAS_ASM_INLINE=y CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
@ -181,7 +182,7 @@ CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_HAS_INT128=y CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC11_NO_ARRAY_BOUNDS=y CONFIG_GCC10_NO_ARRAY_BOUNDS=y
CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CC_NO_ARRAY_BOUNDS=y
CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_ARCH_SUPPORTS_INT128=y
CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING=y
@ -193,13 +194,16 @@ CONFIG_MEMCG=y
CONFIG_MEMCG_KMEM=y CONFIG_MEMCG_KMEM=y
# CONFIG_BLK_CGROUP is not set # CONFIG_BLK_CGROUP is not set
CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=y CONFIG_CFS_BANDWIDTH=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_SCHED_MM_CID=y CONFIG_SCHED_MM_CID=y
CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_PIDS=y
# CONFIG_CGROUP_RDMA is not set # CONFIG_CGROUP_RDMA is not set
# CONFIG_CGROUP_FREEZER is not set # CONFIG_CGROUP_FREEZER is not set
# CONFIG_CGROUP_HUGETLB is not set # CONFIG_CGROUP_HUGETLB is not set
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
# CONFIG_CGROUP_DEVICE is not set # CONFIG_CGROUP_DEVICE is not set
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
# CONFIG_CGROUP_PERF is not set # CONFIG_CGROUP_PERF is not set
@ -439,7 +443,6 @@ CONFIG_X86_64_ACPI_NUMA=y
CONFIG_NODES_SHIFT=6 CONFIG_NODES_SHIFT=6
CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y
# CONFIG_ARCH_MEMORY_PROBE is not set
CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ARCH_PROC_KCORE_TEXT=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
CONFIG_X86_PMEM_LEGACY_DEVICE=y CONFIG_X86_PMEM_LEGACY_DEVICE=y
@ -509,7 +512,7 @@ CONFIG_CALL_PADDING=y
CONFIG_HAVE_CALL_THUNKS=y CONFIG_HAVE_CALL_THUNKS=y
CONFIG_CALL_THUNKS=y CONFIG_CALL_THUNKS=y
CONFIG_PREFIX_SYMBOLS=y CONFIG_PREFIX_SYMBOLS=y
CONFIG_SPECULATION_MITIGATIONS=y CONFIG_CPU_MITIGATIONS=y
CONFIG_PAGE_TABLE_ISOLATION=y CONFIG_PAGE_TABLE_ISOLATION=y
CONFIG_RETPOLINE=y CONFIG_RETPOLINE=y
CONFIG_RETHUNK=y CONFIG_RETHUNK=y
@ -521,6 +524,8 @@ CONFIG_CPU_IBRS_ENTRY=y
CONFIG_CPU_SRSO=y CONFIG_CPU_SRSO=y
# CONFIG_SLS is not set # CONFIG_SLS is not set
# CONFIG_GDS_FORCE_MITIGATION is not set # CONFIG_GDS_FORCE_MITIGATION is not set
CONFIG_MITIGATION_RFDS=y
CONFIG_MITIGATION_SPECTRE_BHI=y
CONFIG_ARCH_HAS_ADD_PAGES=y CONFIG_ARCH_HAS_ADD_PAGES=y
# #
@ -573,7 +578,6 @@ CONFIG_ACPI_TABLE_UPGRADE=y
# CONFIG_ACPI_DEBUG is not set # CONFIG_ACPI_DEBUG is not set
CONFIG_ACPI_PCI_SLOT=y CONFIG_ACPI_PCI_SLOT=y
CONFIG_ACPI_CONTAINER=y CONFIG_ACPI_CONTAINER=y
CONFIG_ACPI_HOTPLUG_MEMORY=y
CONFIG_ACPI_HOTPLUG_IOAPIC=y CONFIG_ACPI_HOTPLUG_IOAPIC=y
# CONFIG_ACPI_SBS is not set # CONFIG_ACPI_SBS is not set
CONFIG_ACPI_HED=y CONFIG_ACPI_HED=y
@ -686,6 +690,7 @@ CONFIG_AS_SHA256_NI=y
CONFIG_AS_TPAUSE=y CONFIG_AS_TPAUSE=y
CONFIG_AS_GFNI=y CONFIG_AS_GFNI=y
CONFIG_AS_WRUSS=y CONFIG_AS_WRUSS=y
CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS=y
# #
# General architecture-dependent options # General architecture-dependent options
@ -970,13 +975,8 @@ CONFIG_HAVE_FAST_GUP=y
CONFIG_NUMA_KEEP_MEMINFO=y CONFIG_NUMA_KEEP_MEMINFO=y
CONFIG_MEMORY_ISOLATION=y CONFIG_MEMORY_ISOLATION=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_HAVE_BOOTMEM_INFO_NODE=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y # CONFIG_MEMORY_HOTPLUG is not set
CONFIG_MEMORY_HOTPLUG=y
# CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE is not set
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_MHP_MEMMAP_ON_MEMORY=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
@ -989,6 +989,7 @@ CONFIG_MIGRATION=y
CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y
CONFIG_ARCH_ENABLE_THP_MIGRATION=y CONFIG_ARCH_ENABLE_THP_MIGRATION=y
CONFIG_CONTIG_ALLOC=y CONFIG_CONTIG_ALLOC=y
CONFIG_PCP_BATCH_SCALE_MAX=5
CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_MMU_NOTIFIER=y CONFIG_MMU_NOTIFIER=y
CONFIG_KSM=y CONFIG_KSM=y
@ -1020,7 +1021,6 @@ CONFIG_ARCH_HAS_PTE_DEVMAP=y
CONFIG_ARCH_HAS_ZONE_DMA_SET=y CONFIG_ARCH_HAS_ZONE_DMA_SET=y
CONFIG_ZONE_DMA=y CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y CONFIG_ZONE_DMA32=y
# CONFIG_ZONE_DEVICE is not set
CONFIG_HMM_MIRROR=y CONFIG_HMM_MIRROR=y
CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y CONFIG_ARCH_USES_HIGH_VMA_FLAGS=y
CONFIG_ARCH_HAS_PKEYS=y CONFIG_ARCH_HAS_PKEYS=y
@ -3075,6 +3075,7 @@ CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_NETDEV_BACKEND=m CONFIG_XEN_NETDEV_BACKEND=m
CONFIG_VMXNET3=m CONFIG_VMXNET3=m
# CONFIG_FUJITSU_ES is not set # CONFIG_FUJITSU_ES is not set
CONFIG_USB4_NET=m
CONFIG_HYPERV_NET=m CONFIG_HYPERV_NET=m
# CONFIG_NETDEVSIM is not set # CONFIG_NETDEVSIM is not set
CONFIG_NET_FAILOVER=m CONFIG_NET_FAILOVER=m
@ -4201,6 +4202,7 @@ CONFIG_REGULATOR_TPS65132=m
# Graphics support # Graphics support
# #
CONFIG_APERTURE_HELPERS=y CONFIG_APERTURE_HELPERS=y
CONFIG_SCREEN_INFO=y
CONFIG_VIDEO_CMDLINE=y CONFIG_VIDEO_CMDLINE=y
# CONFIG_AUXDISPLAY is not set # CONFIG_AUXDISPLAY is not set
# CONFIG_PANEL is not set # CONFIG_PANEL is not set
@ -4268,6 +4270,7 @@ CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_FOREIGN_ENDIAN is not set
CONFIG_FB_IOMEM_FOPS=y
CONFIG_FB_IOMEM_HELPERS=y CONFIG_FB_IOMEM_HELPERS=y
# CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_TILEBLITTING is not set
@ -5008,7 +5011,6 @@ CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_PCI_LEGACY=y
# CONFIG_VIRTIO_PMEM is not set # CONFIG_VIRTIO_PMEM is not set
CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_MEM=m
CONFIG_VIRTIO_INPUT=m CONFIG_VIRTIO_INPUT=m
CONFIG_VIRTIO_MMIO=m CONFIG_VIRTIO_MMIO=m
CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
@ -5035,8 +5037,6 @@ CONFIG_HYPERV_BALLOON=m
# Xen driver support # Xen driver support
# #
CONFIG_XEN_BALLOON=y CONFIG_XEN_BALLOON=y
CONFIG_XEN_BALLOON_MEMORY_HOTPLUG=y
CONFIG_XEN_MEMORY_HOTPLUG_LIMIT=512
CONFIG_XEN_SCRUB_PAGES_DEFAULT=y CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
CONFIG_XEN_DEV_EVTCHN=m CONFIG_XEN_DEV_EVTCHN=m
CONFIG_XEN_BACKEND=y CONFIG_XEN_BACKEND=y
@ -5316,7 +5316,8 @@ CONFIG_IDLE_INJECT=y
CONFIG_RAS=y CONFIG_RAS=y
# CONFIG_RAS_CEC is not set # CONFIG_RAS_CEC is not set
CONFIG_USB4=m CONFIG_USB4=m
CONFIG_USB4_NET=m # CONFIG_USB4_DEBUGFS_WRITE is not set
# CONFIG_USB4_DMA_TEST is not set
# #
# Android # Android
@ -5638,6 +5639,7 @@ CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_SIG=y
CONFIG_CRYPTO_SIG2=y CONFIG_CRYPTO_SIG2=y
CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER=y
CONFIG_CRYPTO_SKCIPHER2=y CONFIG_CRYPTO_SKCIPHER2=y
@ -5750,7 +5752,7 @@ CONFIG_CRYPTO_POLY1305=m
CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_SHA3=m CONFIG_CRYPTO_SHA3=m
# CONFIG_CRYPTO_SM3_GENERIC is not set # CONFIG_CRYPTO_SM3_GENERIC is not set
CONFIG_CRYPTO_STREEBOG=m CONFIG_CRYPTO_STREEBOG=m
@ -6007,7 +6009,6 @@ CONFIG_SWIOTLB=y
CONFIG_SGL_ALLOC=y CONFIG_SGL_ALLOC=y
CONFIG_IOMMU_HELPER=y CONFIG_IOMMU_HELPER=y
CONFIG_CHECK_SIGNATURE=y CONFIG_CHECK_SIGNATURE=y
# CONFIG_FORCE_NR_CPUS is not set
CONFIG_CPU_RMAP=y CONFIG_CPU_RMAP=y
CONFIG_DQL=y CONFIG_DQL=y
CONFIG_GLOB=y CONFIG_GLOB=y
@ -6033,7 +6034,6 @@ CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAS_COPY_MC=y CONFIG_ARCH_HAS_COPY_MC=y
CONFIG_ARCH_STACKWALK=y CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_SBITMAP=y CONFIG_SBITMAP=y
CONFIG_PARMAN=m CONFIG_PARMAN=m
CONFIG_OBJAGG=m CONFIG_OBJAGG=m
@ -6117,8 +6117,7 @@ CONFIG_HAVE_KCSAN_COMPILER=y
# #
CONFIG_PAGE_EXTENSION=y CONFIG_PAGE_EXTENSION=y
# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_SLUB_DEBUG=y # CONFIG_SLUB_DEBUG is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_OWNER is not set
# CONFIG_PAGE_TABLE_CHECK is not set # CONFIG_PAGE_TABLE_CHECK is not set
CONFIG_PAGE_POISONING=y CONFIG_PAGE_POISONING=y
@ -6331,6 +6330,7 @@ CONFIG_X86_DEBUG_FPU=y
# CONFIG_PUNIT_ATOM_DEBUG is not set # CONFIG_PUNIT_ATOM_DEBUG is not set
CONFIG_UNWINDER_ORC=y CONFIG_UNWINDER_ORC=y
# CONFIG_UNWINDER_FRAME_POINTER is not set # CONFIG_UNWINDER_FRAME_POINTER is not set
# CONFIG_UNWINDER_GUESS is not set
# end of x86 Debugging # end of x86 Debugging
# #

View File

@ -19,6 +19,7 @@ git reset --hard HEAD
KERNEL_VERSION=$(make kernelversion) KERNEL_VERSION=$(make kernelversion)
KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../data/defaults.toml | tr -d \") KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../data/defaults.toml | tr -d \")
KERNEL_CONFIG=arch/x86/configs/vyos_defconfig
# VyOS requires some small Kernel Patches - apply them here # VyOS requires some small Kernel Patches - apply them here
# It's easier to habe them here and make use of the upstream # It's easier to habe them here and make use of the upstream
@ -31,6 +32,28 @@ do
patch -p1 < ${PATCH_DIR}/${patch} patch -p1 < ${PATCH_DIR}/${patch}
done done
TRUSTED_KEYS_FILE=trusted_keys.pem
# start with empty key file
echo -n "" > $TRUSTED_KEYS_FILE
CERTS=$(ls ../../../data/live-build-config/includes.chroot/var/lib/shim-signed/mok/*.pem)
if [ ! -z "${CERTS}" ]; then
# add known public keys to Kernel certificate chain
for file in $CERTS; do
cat $file >> $TRUSTED_KEYS_FILE
done
# Force Kernel module signing and embed public keys
echo "CONFIG_MODULE_SIG_FORMAT=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_FORCE=y" >> $KERNEL_CONFIG
echo "# CONFIG_MODULE_SIG_ALL is not set" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_SHA512=y" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_HASH=\"sha512\"" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_KEY=\"\"" >> $KERNEL_CONFIG
echo "CONFIG_MODULE_SIG_KEY_TYPE_RSA=y" >> $KERNEL_CONFIG
echo "CONFIG_SYSTEM_TRUSTED_KEYS=\"$TRUSTED_KEYS_FILE\"" >> $KERNEL_CONFIG
fi
echo "I: make vyos_defconfig" echo "I: make vyos_defconfig"
# Select Kernel configuration - currently there is only one # Select Kernel configuration - currently there is only one
make vyos_defconfig make vyos_defconfig

View File

@ -43,6 +43,7 @@ import traceback
import logging import logging
import re import re
import tomli import tomli
import shutil
from io import BytesIO from io import BytesIO
from datetime import datetime from datetime import datetime
@ -52,6 +53,17 @@ now = datetime.now()
tpm_folder = '/tmp/vyos_tpm_test' tpm_folder = '/tmp/vyos_tpm_test'
qemu_name = 'VyOS-QEMU' qemu_name = 'VyOS-QEMU'
# getch.py
KEY_F2 = chr(27) + chr(91) + chr(49) + chr(50) + chr(126)
KEY_F10 = chr(27) + chr(91) + chr(50) + chr(49) + chr(126)
KEY_DOWN = chr(27) + chr(91) + chr(66)
KEY_SPACE = chr(32)
KEY_RETURN = chr(13)
KEY_ESC = chr(27)
KEY_Y = chr(121)
mok_password = '1234'
parser = argparse.ArgumentParser(description='Install and start a test VyOS vm.') parser = argparse.ArgumentParser(description='Install and start a test VyOS vm.')
parser.add_argument('iso', help='ISO file to install') parser.add_argument('iso', help='ISO file to install')
parser.add_argument('disk', help='name of disk image file', nargs='?', parser.add_argument('disk', help='name of disk image file', nargs='?',
@ -78,6 +90,8 @@ parser.add_argument('--configtest', help='Execute load/commit config tests',
action='store_true', default=False) action='store_true', default=False)
parser.add_argument('--tpmtest', help='Execute TPM encrypted config tests', parser.add_argument('--tpmtest', help='Execute TPM encrypted config tests',
action='store_true', default=False) action='store_true', default=False)
parser.add_argument('--sbtest', help='Execute Secure Boot tests',
action='store_true', default=False)
parser.add_argument('--qemu-cmd', help='Only generate QEMU launch command', parser.add_argument('--qemu-cmd', help='Only generate QEMU launch command',
action='store_true', default=False) action='store_true', default=False)
@ -114,17 +128,33 @@ def get_half_cpus():
cpu /= 2 cpu /= 2
return int(cpu) return int(cpu)
def get_qemu_cmd(name, enable_uefi, disk_img, raid=None, iso_img=None, tpm=False, vnc_enabled=False): OVMF_CODE = '/usr/share/OVMF/OVMF_CODE_4M.secboot.fd'
OVMF_VARS_TMP = args.disk.replace('.img', '.efivars')
if args.sbtest:
shutil.copy('/usr/share/OVMF/OVMF_VARS_4M.ms.fd', OVMF_VARS_TMP)
def get_qemu_cmd(name, enable_uefi, disk_img, raid=None, iso_img=None, tpm=False, vnc_enabled=False, secure_boot=False):
uefi = "" uefi = ""
uuid = "f48b60b2-e6ad-49ef-9d09-4245d0585e52" uuid = "f48b60b2-e6ad-49ef-9d09-4245d0585e52"
machine = 'pc'
vga = '-vga none'
vnc = ''
if vnc_enabled:
vga = '-vga virtio'
vnc = '-vnc :0'
if enable_uefi: if enable_uefi:
uefi = '-bios /usr/share/OVMF/OVMF_CODE.fd' uefi = '-bios /usr/share/OVMF/OVMF_CODE.fd'
name = f'{name}-UEFI' name = f'{name}-UEFI'
uuid = 'd27cf29e-4419-4407-8f82-dc73d1acd184'
vga = '-vga none' if secure_boot:
if vnc_enabled: name = f'{name}-SECURE-BOOT'
vga = ' -vga virtio -vnc :0' machine = 'q35,smm=on'
uefi = f'-drive "if=pflash,unit=0,format=raw,readonly=on,file={OVMF_CODE}" ' \
f'-drive "if=pflash,unit=1,format=raw,file={OVMF_VARS_TMP}"'
# Changing UEFI settings require a display
vga = '-vga virtio'
cdrom = "" cdrom = ""
if iso_img: if iso_img:
@ -140,12 +170,12 @@ def get_qemu_cmd(name, enable_uefi, disk_img, raid=None, iso_img=None, tpm=False
-name "{name}" \ -name "{name}" \
-smp {cpucount},sockets=1,cores={cpucount},threads=1 \ -smp {cpucount},sockets=1,cores={cpucount},threads=1 \
-cpu host \ -cpu host \
-machine {machine},accel=kvm \
{uefi} \ {uefi} \
-m 4G \ -m 4G \
-vga none \ -vga none \
-nographic \ -nographic \
{vga} \ {vga} {vnc}\
-machine accel=kvm \
-uuid {uuid} \ -uuid {uuid} \
-cpu host \ -cpu host \
{cdrom} \ {cdrom} \
@ -280,8 +310,50 @@ def start_swtpm():
tpm_process.start() tpm_process.start()
return tpm_process return tpm_process
def toggleUEFISecureBoot(c):
def UEFIKeyPress(c, key):
UEFI_SLEEP = 1
c.send(key)
time.sleep(UEFI_SLEEP)
# Enter UEFI
for ii in range(1, 10):
c.send(KEY_F2)
time.sleep(0.250)
time.sleep(10)
# Device Manager
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_RETURN)
# Secure Boot Configuration
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_RETURN)
# Attempt Secure Boot Toggle
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_RETURN)
UEFIKeyPress(c, KEY_RETURN)
# Save Secure Boot
UEFIKeyPress(c, KEY_F10)
UEFIKeyPress(c, KEY_Y)
# Go Back to Menu
UEFIKeyPress(c, KEY_ESC)
UEFIKeyPress(c, KEY_ESC)
# Go Down for reset
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_DOWN)
UEFIKeyPress(c, KEY_RETURN)
if args.qemu_cmd: if args.qemu_cmd:
tmp = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid, iso_img=args.iso, vnc_enabled=args.vnc) tmp = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid, iso_img=args.iso, vnc_enabled=args.vnc, secure_boot=args.sbtest)
os.system(tmp) os.system(tmp)
exit(0) exit(0)
@ -292,7 +364,7 @@ try:
# Installing image to disk # Installing image to disk
################################################# #################################################
log.info('Installing system') log.info('Installing system')
cmd = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid, iso_img=args.iso, vnc_enabled=args.vnc) cmd = get_qemu_cmd(qemu_name, args.uefi, args.disk, raid=diskname_raid, iso_img=args.iso, vnc_enabled=args.vnc, secure_boot=args.sbtest)
log.debug(f'Executing command: {cmd}') log.debug(f'Executing command: {cmd}')
c = pexpect.spawn(cmd, logfile=stl, timeout=60) c = pexpect.spawn(cmd, logfile=stl, timeout=60)
@ -304,6 +376,10 @@ try:
default_user = 'vyos' default_user = 'vyos'
default_password = 'vyos' default_password = 'vyos'
if args.sbtest:
log.info('Disable UEFI Secure Boot for initial installation')
toggleUEFISecureBoot(c)
try: try:
c.expect('Automatic boot in', timeout=10) c.expect('Automatic boot in', timeout=10)
c.sendline('') c.sendline('')
@ -348,9 +424,63 @@ try:
c.sendline('') c.sendline('')
c.expect(op_mode_prompt) c.expect(op_mode_prompt)
if args.sbtest:
c.sendline('install mok')
c.expect('input password:.*')
c.sendline(mok_password)
c.expect('input password again:.*')
c.sendline(mok_password)
c.expect(op_mode_prompt)
log.info('system installed, rebooting') log.info('system installed, rebooting')
c.sendline('reboot now') c.sendline('reboot now')
#################################################
# SHIM Mok Manager
#################################################
if args.sbtest:
log.info('Install Secure Boot Machine Owner Key')
MOK_SLEEP = 0.5
c.expect('BdsDxe: starting Boot00.*')
time.sleep(3)
# press any key
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
# Enroll MOK
c.send(KEY_DOWN)
time.sleep(MOK_SLEEP)
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
# Continue
c.send(KEY_DOWN)
time.sleep(MOK_SLEEP)
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
# Enroll Keys
c.send(KEY_DOWN)
time.sleep(MOK_SLEEP)
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
c.sendline(mok_password)
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
# Reboot
c.send(KEY_RETURN)
time.sleep(MOK_SLEEP)
#################################################
# Re-Enable Secure Boot
#################################################
if args.sbtest:
log.info('Enable UEFI Secure Boot for initial installation')
toggleUEFISecureBoot(c)
################################################# #################################################
# Removing CD installation media # Removing CD installation media
################################################# #################################################
@ -588,7 +718,6 @@ try:
log.debug(f'Executing command: {cmd}') log.debug(f'Executing command: {cmd}')
c = pexpect.spawn(cmd, logfile=stl) c = pexpect.spawn(cmd, logfile=stl)
################################################# #################################################
# Logging into VyOS system # Logging into VyOS system
################################################# #################################################
@ -710,7 +839,10 @@ try:
tmp = 'Configtest failed :/ - check debug output' tmp = 'Configtest failed :/ - check debug output'
log.error(tmp) log.error(tmp)
raise Exception(tmp) raise Exception(tmp)
elif args.sbtest:
c.sendline('show secure-boot')
c.expect('SecureBoot enabled')
c.expect(op_mode_prompt)
else: else:
log.info('No testcase selected!') log.info('No testcase selected!')
@ -748,6 +880,8 @@ if not args.keep:
os.remove(args.disk) os.remove(args.disk)
if diskname_raid: if diskname_raid:
os.remove(diskname_raid) os.remove(diskname_raid)
if args.sbtest:
os.remove(OVMF_VARS_TMP)
except Exception: except Exception:
log.error('Exception while removing diskimage!') log.error('Exception while removing diskimage!')
log.error(traceback.format_exc()) log.error(traceback.format_exc())

View File

@ -571,7 +571,7 @@ if __name__ == "__main__":
--checksums 'sha256 md5' \ --checksums 'sha256 md5' \
--chroot-squashfs-compression-type "{{squashfs_compression_type}}" \ --chroot-squashfs-compression-type "{{squashfs_compression_type}}" \
--debian-installer none \ --debian-installer none \
--debootstrap-options "--variant=minbase --exclude=isc-dhcp-client,isc-dhcp-common,ifupdown --include=apt-utils,ca-certificates,gnupg2" \ --debootstrap-options "--variant=minbase --exclude=isc-dhcp-client,isc-dhcp-common,ifupdown --include=apt-utils,ca-certificates,gnupg2,linux-kbuild-6.1" \
--distribution {{debian_distribution}} \ --distribution {{debian_distribution}} \
--firmware-binary false \ --firmware-binary false \
--firmware-chroot false \ --firmware-chroot false \