From 0b0460085861048b80fe640d6468e8384defdc72 Mon Sep 17 00:00:00 2001 From: shibedrill Date: Mon, 14 Apr 2025 10:50:18 -0400 Subject: [PATCH] Better configs --- .env | 3 ++ README.md | 13 +++++++ build/build-image.sh | 81 +++++++++++++++++++++++++++++++++++++------- compose.yml | 9 +++++ 4 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..d314829 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +SECBOOT=true +TPM=true +REQSIG=true \ No newline at end of file diff --git a/README.md b/README.md index 8c84efb..b10fe46 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,16 @@ This repo holds a set of files necessary for creating bootable HalogenOS images. - Submodules that contain code for binaries These files allow a server to build a working image, sign it with a release key, and distribute it to clients running HalogenOS configured to update from that server. Performing updates on the server side allows for easier testing, development, and reproducibility, while removing complexity and performance demands from clients. + +## Configurations + +There are a few overridable variables that control configuration elements of HalogenOS. These are set at build time, and are permanently immutable throughout the lifetime of the OS, unless the values are changed, the image is rebuilt with the same keys and URL, and the installation is updated. + +- `DISTURL`: Unset by default. The URL that HalogenOS files will be served at. If it is not set, OTA updates from a server are disabled, but updating can be done manually as long as the images are signed. +- `TPM`: Default is `true`. This will control automatic decryption of the root partition. Disable if your system does not have TPM 2.0. +- `SECBOOT`: Default is `true`. This will control whether or not Secure Boot keys are generated and enrolled. Disable if your system does not support Secure Boot. +- `REQSIG`: Default is `true`. This will control whether or not update images and overlays require signatures. Disable ONLY for testing or development purposes. + +## Signing Keys + +Unless you disable `REQSIG`, HalogenOS will require a signing key for updates and for overlays. If you do disable `REQSIG`, HalogenOS will still attempt to verify updates and overlays, but will not enforce these checks, and will not panic if there is no public signing key. To totally disable the inclusion of the signing key, you must remove `signing_key_public` from `build` in [compose.yml](/compose.yml). diff --git a/build/build-image.sh b/build/build-image.sh index 6e53233..7f216a1 100755 --- a/build/build-image.sh +++ b/build/build-image.sh @@ -1,10 +1,37 @@ #!/bin/bash -set -euxo pipefail +set -eo pipefail -# Clean build dir and remake -rm -rf /build/artifacts/* -mkdir -p /build/artifacts/dist +NPROC=$(nproc) +VERSION=$(date +%Y%m%d)$MINOR + +# This variable gets unset if any security-critical elements are disabled +SECURESYS=true + +echo "========== VERSION ===========" +echo "Version: $VERSION" +echo "Distfiles path: $DISTPATH" +echo -n "Distribution URL: " +if [ -n "$DISTURL" ]; then echo "Not set, OTA disabled" +else echo "$DISTURL"; fi +echo "========== SECURITY ==========" +echo -en "Secure Boot: \t\t" +if [ "$SECBOOT" == "true" ]; then echo "Enabled" +else echo "Disabled"; SECURESYS="false"; fi +echo -en "TPM Security: \t" +if [ "$TPM" == "true" ]; then echo "Enabled" +else echo "Disabled"; fi +echo -en "Signature required: \t" +if [ "$REQSIG" == "true" ]; then echo "Enabled" +else echo "Disabled"; unset SECURESYS="false"; fi +echo -en "Overall security: \t" +if [ "$SECURESYS" == "true" ]; then echo "Intact" +else echo "Degraded"; fi +echo "==============================" + +set -x + +mkdir -p "$DISTPATH" # Gentoo setup mkdir -p /var/db/repos/gentoo @@ -13,34 +40,64 @@ emerge-webrsync --quiet eselect profile set default/linux/amd64/23.0/musl/hardened/selinux # SquashFS tools needed for image generation -emerge squashfstools +emerge --quiet squashfs-tools # Copy in package list mkdir -p /etc/portage/sets cp /build/packages.txt /etc/portage/sets/halogenos # Set install location -export ROOT="/build/artifacts/dist" +export ROOT="$DISTPATH" + +# Update any existing packages +emerge -j "$NPROC" --quiet --update --deep --newuse @world # Emerge all packages -emerge -j $(nproc) --quiet @halogenos +emerge -j "$NPROC" --quiet @halogenos # Fix directory locations -mv /build/artifacts/dist/bin /build/artifacts/dist/usr/bin -mv /build/artifacts/dist/lib /build/artifacts/dist/usr/lib -mv /build/artifacts/dist/sbin /build/artifacts/dist/usr/sbin +mv "$DISTPATH"/bin "$DISTPATH"/usr/bin +mv "$DISTPATH"/lib "$DISTPATH"/usr/lib +mv "$DISTPATH"/sbin "$DISTPATH"/usr/sbin # Include any additional files +mkdir -p "$DISTPATH"/usr/share/halogenos +mkdir "$DISTPATH"/usr/share/halogenos/keys +mkdir "$DISTPATH"/usr/share/halogenos/bin + +# Require inclusion of public key if $REQSIG is true +if [ "$REQSIG" == "true" ]; then + cp /run/secrets/signing_key_public "$DISTPATH"/usr/share/halogenos/keys/release_key_pub.asc +else + # Otherwise, attempt to copy the key, but don't freak out if it does not exist + if [ -f /run/secrets/signing_key_public ]; then + cp /run/secrets/signing_key_public "$DISTPATH"/usr/share/halogenos/keys/release_key_pub.asc + else + echo "Signing key not found, but not enforcing signatures, so it's okay." + fi +fi + +# Metadata & build-time configs +mkdir "$DISTPATH"/usr/share/halogenos/meta +echo "$VERSION" > "$DISTPATH"/usr/share/halogenos/meta/version +if [ -n "$DISTURL" ]; then echo "$DISTURL" > "$DISTPATH"/usr/share/halogenos/meta/ota +else echo "DISABLED" > "$DISTPATH"/usr/share/halogenos/meta/ota; fi +if [ "$SECBOOT" == "true" ]; then echo "ENABLED" > "$DISTPATH"/usr/share/halogenos/meta/secboot +else echo "DISABLED" > "$DISTPATH"/usr/share/halogenos/meta/secboot; fi +if [ "$TPM" == "true" ]; then echo "ENABLED" > "$DISTPATH"/usr/share/halogenos/meta/tpm +else echo "DISABLED" > "$DISTPATH"/usr/share/halogenos/meta/tpm; fi +if [ "$SECURESYS" == "true" ]; then echo "TRUE" > "$DISTPATH"/usr/share/halogenos/meta/securesys +else echo "FALSE" > "$DISTPATH"/usr/share/halogenos/meta/securesys; fi # Make any additional config changes # Create images dir and img files -mkdir -p /build/artifacts/images +mkdir -p /build/images dd if=/dev/zero of=/build/images/usr.img bs=1 count=0 seek=2G dd if=/dev/zero of=/build/images/verity.img bs=1 count=0 seek=2000M # Create squashfs -mksquashfs /build/artifacts/dist /build/artifacts/usr.squashfs +mksquashfs "$DISTPATH" /build/artifacts/usr.squashfs # Image squashfs filesystem onto usr img dd if=/build/artifacts/usr.squashfs of=/build/images/usr.img diff --git a/compose.yml b/compose.yml index c2bafeb..3774282 100644 --- a/compose.yml +++ b/compose.yml @@ -2,6 +2,15 @@ services: build: image: docker.io/gentoo/stage3:musl-hardened command: /build/build-image.sh + environment: + DISTPATH: "/build/artifacts/dist" + IMGPATH: "/build/images" + MINOR: ${MINOR} + SECBOOT: ${SECBOOT} + TPM: ${TPM} + REQSIG: ${REQSIG} + secrets: + - signing_key_public volumes: - ./build:/build sign: