From 3fc5003676b3065af29068dadb8725f4c5a3da546a162604bbd066ae1b5559d3 Mon Sep 17 00:00:00 2001 From: "Marc S. Weidner" Date: Sun, 7 Jun 2026 09:11:26 +0100 Subject: [PATCH] V9.14.018.2026.06.07 Signed-off-by: Marc S. Weidner --- .../usr/lib/live/boot/0024-ciss-crypt-squash | 215 ++++++++++++++---- docs/AUDIT_LYNIS.md | 60 +++-- docs/CHANGELOG.md | 1 + 3 files changed, 212 insertions(+), 64 deletions(-) diff --git a/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash b/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash index 81bf303..e2c2b88 100644 --- a/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash +++ b/config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash @@ -25,6 +25,98 @@ _SAVED_SET_OPTS="$(set +o)" set -eu +####################################### +# Ensure the minimal device nodes required by this early boot script exist. +# Globals: +# None +# Arguments: +# None +# Returns: +# 0: always, device-node setup is best-effort only +####################################### +ensure_minimal_dev_nodes() { + mknod_cmd="" + busybox_cmd="" + + [ -d /dev ] || mkdir -p /dev || return 0 + + if [ -c /dev/null ] && [ -c /dev/console ]; then + + return 0 + + fi + + mknod_cmd="$(command -v mknod 2>&- || printf '')" + if [ -z "${mknod_cmd}" ]; then + + busybox_cmd="$(command -v busybox 2>&- || printf '')" + + fi + + if [ ! -c /dev/null ]; then + + rm -f /dev/null || true + if [ -n "${mknod_cmd}" ]; then + + "${mknod_cmd}" -m 666 /dev/null c 1 3 || true + + elif [ -n "${busybox_cmd}" ]; then + + "${busybox_cmd}" mknod -m 666 /dev/null c 1 3 || true + + fi + + fi + + if [ ! -c /dev/console ]; then + + rm -f /dev/console || true + if [ -n "${mknod_cmd}" ]; then + + "${mknod_cmd}" -m 600 /dev/console c 5 1 || true + + elif [ -n "${busybox_cmd}" ]; then + + "${busybox_cmd}" mknod -m 600 /dev/console c 5 1 || true + + fi + + fi + + return 0 +} + +####################################### +# Console logging helper that does not assume /dev/console is always present. +# Globals: +# None +# Arguments: +# 1: printf format +# *: printf arguments +# Returns: +# 0: always, logging failure is not fatal +####################################### +console_printf() { + console_format="$1" + shift + + if [ -c /dev/console ]; then + + # shellcheck disable=SC2059 + printf "${console_format}" "$@" > /dev/console || : + + elif [ -e /proc/1/fd/1 ]; then + + # shellcheck disable=SC2059 + printf "${console_format}" "$@" > /proc/1/fd/1 || : + + fi + + return 0 +} + +ensure_minimal_dev_nodes + printf "\e[95m[INFO] Starting : [/usr/lib/live/boot/0024-ciss-crypt-squash] \n\e[0m" ####################################### @@ -41,11 +133,21 @@ ask_pass_console() { PASSPHRASE="" SAVED_STTY="" + ensure_minimal_dev_nodes + + [ -c /dev/console ] || return 1 + exec 8<>/dev/console || return 1 + ### Save current console settings. - SAVED_STTY=$(stty -g /dev/null || printf '') + SAVED_STTY=$(stty -g <&8 2>&- || printf '') ### Non-canonical mode, no echo, 1 byte at a time. - stty -echo -icanon time 0 min 1 /dev/null || return 1 + if ! stty -echo -icanon time 0 min 1 <&8 2>&-; then + + exec 8>&- + return 1 + + fi cr=$(printf '\r') bs=$(printf '\b') @@ -54,11 +156,11 @@ ask_pass_console() { while :; do ### Read exactly one byte from the console. - c=$(dd bs=1 count=1 2>/dev/null &- <&8) if [ -z "${c}" ]; then - printf '\n' > /dev/console + printf '\n' >&8 break fi @@ -70,7 +172,7 @@ ask_pass_console() { "${cr}") ### Enter: finish input. - printf '\n' > /dev/console + printf '\n' >&8 break ;; @@ -79,7 +181,7 @@ ask_pass_console() { if [ -n "${PASSPHRASE}" ]; then PASSPHRASE=${PASSPHRASE%?} - printf '\b \b' > /dev/console + printf '\b \b' >&8 fi ;; @@ -87,14 +189,20 @@ ask_pass_console() { *) ### Normal character: append and mask output. PASSPHRASE="${PASSPHRASE}${c}" - printf '*' > /dev/console + printf '*' >&8 ;; esac done - [ -n "${SAVED_STTY}" ] && stty "${SAVED_STTY}" /dev/null || : + if [ -n "${SAVED_STTY}" ]; then + + stty "${SAVED_STTY}" <&8 2>&- || : + + fi + + exec 8>&- printf '%s' "${PASSPHRASE}" @@ -130,7 +238,7 @@ _PARAMETER="" _dev="" ### Read the kernel cmdline once. ---------------------------------------------------------------------------------------------- -CMDLINE="$(cat /proc/cmdline 2>/dev/null || printf '')" +CMDLINE="$(cat /proc/cmdline 2>&- || printf '')" for _PARAMETER in ${CMDLINE}; do @@ -153,8 +261,8 @@ if ! mountpoint -q "${CDLB_MNT_MEDIUM}"; then if [ -n "${CDLB_ISO_LABEL}" ] && [ -e "/dev/disk/by-label/${CDLB_ISO_LABEL}" ]; then - mount -r -t iso9660 "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${CDLB_MNT_MEDIUM}" 2>/dev/null \ - || mount -r -t udf "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${CDLB_MNT_MEDIUM}" 2>/dev/null \ + mount -r -t iso9660 "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${CDLB_MNT_MEDIUM}" 2>&- \ + || mount -r -t udf "/dev/disk/by-label/${CDLB_ISO_LABEL}" "${CDLB_MNT_MEDIUM}" 2>&- \ || log "could not mount label=${CDLB_ISO_LABEL} (iso9660/udf)" fi @@ -170,13 +278,13 @@ if ! mountpoint -q "${CDLB_MNT_MEDIUM}"; then [ -b "${_dev}" ] || continue ### Try ISO9660 first, then UDF; only unmount on failure. - if mount -r -t iso9660 "${_dev}" "${CDLB_MNT_MEDIUM}" 2>/dev/null || mount -r -t udf "${_dev}" "${CDLB_MNT_MEDIUM}" 2>/dev/null; then + if mount -r -t iso9660 "${_dev}" "${CDLB_MNT_MEDIUM}" 2>&- || mount -r -t udf "${_dev}" "${CDLB_MNT_MEDIUM}" 2>&-; then - mountpoint -q "${CDLB_MNT_MEDIUM}" 2>/dev/null && break + mountpoint -q "${CDLB_MNT_MEDIUM}" 2>&- && break else - umount "${CDLB_MNT_MEDIUM}" 2>/dev/null || true + umount "${CDLB_MNT_MEDIUM}" 2>&- || true fi @@ -220,24 +328,24 @@ fi printf "\e[92m[INFO] Loop device : [%s] \n\e[0m" "${LOOP}" ### Expose the loop device for unlock-wrapper.sh, dropbear forced-command. ----------------------------------------------------- -mkdir -p /run 2>/dev/null || true +mkdir -p /run 2>&- || true -echo "${LOOP}" > /run/ciss-loopdev 2>/dev/null || true +echo "${LOOP}" > /run/ciss-loopdev 2>&- || true -chmod 0600 /run/ciss-loopdev 2>/dev/null || true +chmod 0600 /run/ciss-loopdev 2>&- || true printf "\e[92m[INFO] Exposed LOOP : [/run/ciss-loopdev] -> [%s]\n\e[0m" "${LOOP}" ### Prepare fifo for passphrase. ----------------------------------------------------------------------------------------------- -mkdir -p /lib/cryptsetup 2>/dev/null || true +mkdir -p /lib/cryptsetup 2>&- || true if [ -p /lib/cryptsetup/passfifo ]; then - rm -f /lib/cryptsetup/passfifo 2>/dev/null || true + rm -f /lib/cryptsetup/passfifo 2>&- || true fi -if ! mkfifo /lib/cryptsetup/passfifo 2>/dev/null; then +if ! mkfifo /lib/cryptsetup/passfifo 2>&-; then printf "\e[92m[WARN] Boot failure : Failed to create [/lib/cryptsetup/passfifo] \n\e[0m" sleep 60 @@ -246,7 +354,7 @@ if ! mkfifo /lib/cryptsetup/passfifo 2>/dev/null; then fi -chmod 0600 /lib/cryptsetup/passfifo 2>/dev/null || true +chmod 0600 /lib/cryptsetup/passfifo 2>&- || true ### Background broker: read FIFO, try cryptsetup per line. --------------------------------------------------------------------- ( @@ -271,18 +379,29 @@ chmod 0600 /lib/cryptsetup/passfifo 2>/dev/null || true [ -n "${PASS}" ] || continue - printf "\e[93m[INFO] CISS LUKS decryption : LUKS mapper [%s] trying to unlock via cryptsetup ... \n\e[0m" "${CDLB_MAPPER_DEV}" >/dev/console 2>/dev/null || true + console_printf "\e[93m[INFO] CISS LUKS decryption : LUKS mapper [%s] trying to unlock via cryptsetup ... \n\e[0m" "${CDLB_MAPPER_DEV}" KEYLEN=${#PASS} - printf '%s' "${PASS}" | cryptsetup open --tries 1 \ - --type luks \ - --keyfile-size="${KEYLEN}" \ - --readonly "${LOOP}" "${CDLB_MAPPER_NAME}" --key-file - 2>/dev/console + if [ -c /dev/console ]; then + + printf '%s' "${PASS}" | cryptsetup open --tries 1 \ + --type luks \ + --keyfile-size="${KEYLEN}" \ + --readonly "${LOOP}" "${CDLB_MAPPER_NAME}" --key-file - 2>/dev/console + + else + + printf '%s' "${PASS}" | cryptsetup open --tries 1 \ + --type luks \ + --keyfile-size="${KEYLEN}" \ + --readonly "${LOOP}" "${CDLB_MAPPER_NAME}" --key-file - 2>&- + + fi if [ -b "${CDLB_MAPPER_DEV}" ]; then - printf "\e[92m[INFO] CISS LUKS decryption : LUKS mapper [%s] successfully opened. \n\e[0m" "${CDLB_MAPPER_DEV}" >/dev/console 2>/dev/null || true + console_printf "\e[92m[INFO] CISS LUKS decryption : LUKS mapper [%s] successfully opened. \n\e[0m" "${CDLB_MAPPER_DEV}" break fi @@ -309,12 +428,12 @@ PID_BROKER="$!" if [ "${PASS_SENT}" -eq 0 ]; then - printf '\e[93m[INFO] Enter LUKS passphrase: \n\e[0m' > /dev/console + console_printf '\e[93m[INFO] Enter LUKS passphrase: \n\e[0m' # shellcheck disable=SC2310 PASS="$(ask_pass_console)" || continue - printf '%s\n' "${PASS}" >| /lib/cryptsetup/passfifo 2>/dev/null || : + printf '%s\n' "${PASS}" >| /lib/cryptsetup/passfifo 2>&- || : PASS_SENT=1 WAIT_LOOP=0 @@ -325,7 +444,7 @@ PID_BROKER="$!" if [ "${WAIT_LOOP}" -ge 160 ]; then - printf '\e[91m[WARN] Please try again : \n\e[0m' > /dev/console + console_printf '\e[91m[WARN] Please try again : \n\e[0m' PASS_SENT=0 WAIT_LOOP=0 @@ -369,12 +488,12 @@ if [ ! -b "${CDLB_MAPPER_DEV}" ]; then printf "\e[91m[WARN] CISS LUKS decryption : Timeout LUKS mapper [%s] not present after %s seconds. \n\e[0m" "${CDLB_MAPPER_DEV}" "${CDLB_REMOTE_WAIT_SECS}" - kill "${PID_PROMPT}" 2>/dev/null || true - kill "${PID_BROKER}" 2>/dev/null || true - wait "${PID_PROMPT}" 2>/dev/null || true - wait "${PID_BROKER}" 2>/dev/null || true + kill "${PID_PROMPT}" 2>&- || true + kill "${PID_BROKER}" 2>&- || true + wait "${PID_PROMPT}" 2>&- || true + wait "${PID_BROKER}" 2>&- || true - rm -f /lib/cryptsetup/passfifo 2>/dev/null || true + rm -f /lib/cryptsetup/passfifo 2>&- || true sleep 60 @@ -383,12 +502,12 @@ if [ ! -b "${CDLB_MAPPER_DEV}" ]; then fi -kill "${PID_PROMPT}" 2>/dev/null || true -kill "${PID_BROKER}" 2>/dev/null || true -wait "${PID_PROMPT}" 2>/dev/null || true -wait "${PID_BROKER}" 2>/dev/null || true +kill "${PID_PROMPT}" 2>&- || true +kill "${PID_BROKER}" 2>&- || true +wait "${PID_PROMPT}" 2>&- || true +wait "${PID_BROKER}" 2>&- || true -rm -f /lib/cryptsetup/passfifo 2>/dev/null || true +rm -f /lib/cryptsetup/passfifo 2>&- || true printf "\e[92m[INFO] CISS LUKS decryption : [%s] is now present.\n\e[0m" "${CDLB_MAPPER_DEV}" @@ -403,7 +522,7 @@ export CDLB_MNT_MEDIUM=${CDLB_MNT_MEDIUM} export CDLB_MNT_ROOTFS=${CDLB_MNT_ROOTFS} export CDLB_REMOTE_WAIT_SECS=${CDLB_REMOTE_WAIT_SECS} EOF -chmod 0444 /run/ciss-rootdev 2>/dev/null || true +chmod 0444 /run/ciss-rootdev 2>&- || true ### Override '9990-main.sh' behavior to ensure 'Verify_checksums()' functions properly. ---------------------------------------- if [ ! -e /conf/param.conf ]; then @@ -413,20 +532,28 @@ if [ ! -e /conf/param.conf ]; then fi -if ! grep -q '^PLAIN_ROOT=' /conf/param.conf 2>/dev/null; then +if ! grep -q '^PLAIN_ROOT=' /conf/param.conf 2>&-; then printf 'PLAIN_ROOT=1\n' >> /conf/param.conf fi -if ! grep -q '^livefs_root=' /conf/param.conf 2>/dev/null; then +if ! grep -q '^livefs_root=' /conf/param.conf 2>&-; then printf 'livefs_root=%s\n' "/run/live/medium" >> /conf/param.conf fi printf "\e[92m[INFO] CISS LUKS decryption : Final state [/conf/param.conf] \n\e[0m" -cat /conf/param.conf >/dev/console 2>&1 || : +if [ -c /dev/console ]; then + + cat /conf/param.conf >/dev/console 2>&1 || : + +elif [ -e /proc/1/fd/1 ]; then + + cat /conf/param.conf >/proc/1/fd/1 2>&1 || : + +fi log "Decrypted root device exposed at [/run/ciss-rootdev] -> [${CDLB_MAPPER_DEV}]" printf "\e[92m[INFO] CISS LUKS decryption : Decrypted root device exposed at: [/run/ciss-rootdev] -> [%s] \n\e[0m" "${CDLB_MAPPER_DEV}" diff --git a/docs/AUDIT_LYNIS.md b/docs/AUDIT_LYNIS.md index 4fbbe31..8cffa20 100644 --- a/docs/AUDIT_LYNIS.md +++ b/docs/AUDIT_LYNIS.md @@ -12,6 +12,8 @@ include_toc: true # 2. Lynis Audit: +Lynis may report only 127.0.0.53 as a configured nameserver when systemd-resolved stub mode is active. This is expected. The effective hardened upstream resolvers, if opted in, must be verified via resolvectl dns, resolvectl status and networkctl status. + ````text [ Lynis 3.1.6 ] @@ -36,7 +38,7 @@ include_toc: true Operating system name: Debian Operating system version: 13 End-of-life: UNKNOWN - Kernel version: 6.16.3+deb13 + Kernel version: 7.0.10+deb13 Hardware platform: x86_64 Hostname: live --------------------------------------------------- @@ -53,6 +55,24 @@ include_toc: true --------------------------------------------------- - Program update status... [ NO UPDATE ] + =============================================================================== + Lynis might be outdated + =============================================================================== + + Current version is more than 6 months old + This version might be Please check if there is a more recent version available. + + Please check if there is a more recent version available. + + Download locations: + + Packages (DEB/RPM) - https://packages.cisofy.com/ + Website (TAR) - https://cisofy.com/downloads/ + GitHub - https://github.com/CISOfy/lynis + + =============================================================================== + + [+] System tools ------------------------------------ - Scanning available tools... @@ -71,14 +91,15 @@ include_toc: true - Checking Secure Boot [ DISABLED ] - Boot loader [ NONE FOUND ] - Check running services (systemctl) [ DONE ] - Result: found 16 running services + Result: found 18 running services - Check enabled services at boot (systemctl) [ DONE ] - Result: found 30 enabled services + Result: found 33 enabled services - Check startup files (permissions) [ OK ] - Running 'systemd-analyze security' Unit name (exposure value) and predicate -------------------------------- - auditd.service (value=8.9) [ EXPOSED ] + - cdi-starter.service (value=9.6) [ UNSAFE ] - chrony.service (value=3.5) [ PROTECTED ] - cron.service (value=9.6) [ UNSAFE ] - dbus.service (value=9.3) [ UNSAFE ] @@ -86,8 +107,6 @@ include_toc: true - emergency.service (value=9.5) [ UNSAFE ] - fail2ban.service (value=6.5) [ MEDIUM ] - getty@tty1.service (value=9.6) [ UNSAFE ] - - ifup@ens3.service (value=9.5) [ UNSAFE ] - - ifup@ens4.service (value=9.5) [ UNSAFE ] - jitterentropy.service (value=2.5) [ PROTECTED ] - lvm2-lvmpolld.service (value=9.5) [ UNSAFE ] - rc-local.service (value=9.6) [ UNSAFE ] @@ -104,6 +123,7 @@ include_toc: true - systemd-journald.service (value=4.9) [ PROTECTED ] - systemd-logind.service (value=2.8) [ PROTECTED ] - systemd-networkd.service (value=2.9) [ PROTECTED ] + - systemd-resolved.service (value=2.2) [ PROTECTED ] - systemd-rfkill.service (value=9.4) [ UNSAFE ] - systemd-udevd.service (value=7.1) [ MEDIUM ] - unattended-upgrades.service (value=9.6) [ UNSAFE ] @@ -120,7 +140,7 @@ include_toc: true - Checking kernel version and release [ DONE ] - Checking kernel type [ DONE ] - Checking loaded kernel modules [ DONE ] - Found 139 active modules + Found 137 active modules - Checking Linux kernel configuration file [ FOUND ] - Checking default I/O kernel scheduler [ NOT FOUND ] - Checking core dumps configuration @@ -202,7 +222,7 @@ include_toc: true - Mount options of /dev/shm [ PARTIALLY HARDENED ] - Mount options of /run [ HARDENED ] - Mount options of /tmp [ PARTIALLY HARDENED ] - - Total without nodev:8 noexec:11 nosuid:6 ro or noexec (W^X): 8 of total 28 + - Total without nodev:8 noexec:11 nosuid:6 ro or noexec (W^X): 7 of total 32 - Checking Locate database [ FOUND ] - Disable kernel support of some filesystems @@ -232,6 +252,7 @@ include_toc: true [+] Name services ------------------------------------ + - Checking search domains [ FOUND ] - Checking /etc/resolv.conf options [ FOUND ] - Searching DNS domain name [ FOUND ] Domain name: local @@ -252,11 +273,7 @@ include_toc: true - Checking security repository in sources.list file [ OK ] - Checking security repository in sources.list.d directory [ OK ] - Checking APT package database [ OK ] -W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will reject signature within a year, see --audit for details - Checking vulnerable packages (apt-get only) [ DONE ] - - [WARNING]: Test PKGS-7392 had a long execution: 21.028694 seconds - - Checking upgradeable packages [ NONE ] - Checking package audit tool [ INSTALLED ] Found: apt-get @@ -269,15 +286,13 @@ W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will re IPv6 only [ NO ] - Checking configured nameservers - Testing nameservers - Nameserver: 135.181.207.105 [ OK ] - Nameserver: 89.58.62.53 [ OK ] - Nameserver: 138.199.237.109 [ OK ] - - Minimal of 2 responsive nameservers [ OK ] + Nameserver: 127.0.0.53 [ OK ] + - DNSSEC supported (systemd-resolved) [ UNKNOWN ] - Checking default gateway [ DONE ] - Getting listening ports (TCP/UDP) [ DONE ] - Checking promiscuous interfaces [ OK ] - Checking waiting connections [ OK ] - - Checking status DHCP client [ RUNNING ] + - Checking status DHCP client [ NOT ACTIVE ] - Checking for ARP monitoring software [ NOT FOUND ] - Uncommon network protocols [ NOT FOUND ] @@ -410,9 +425,9 @@ W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will re ------------------------------------ - Checking for expired SSL certificates [0/151] [ NONE ] - [WARNING]: Test CRYP-7902 had a long execution: 31.463606 seconds + [WARNING]: Test CRYP-7902 had a long execution: 22.283800 seconds - - Found 10 LUKS encrypted block devices. [ OK ] + - Found 11 LUKS encrypted block devices. [ OK ] - Found 0 encrypted and 0 unencrypted swap devices in use. [ OK ] - Kernel entropy is sufficient [ YES ] - HW RNG & rngd [ NO ] @@ -429,7 +444,7 @@ W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will re ------------------------------------ - Checking presence AppArmor [ FOUND ] - Checking AppArmor status [ ENABLED ] - Found 43 unconfined processes + Found 28 unconfined processes - Checking presence SELinux [ NOT FOUND ] - Checking presence TOMOYO Linux [ NOT FOUND ] - Checking presence grsecurity [ NOT FOUND ] @@ -441,7 +456,8 @@ W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will re - AIDE [ FOUND ] - AIDE config file [ FOUND ] - AIDE database [ FOUND ] - - dm-integrity (status) [ DISABLED ] + - dm-integrity (status) [ FOUND ] + - dm-integrity (status) [ ENABLED ] - dm-verity (status) [ DISABLED ] - AIDE config (Checksum) [ OK ] - Checking presence integrity tool [ FOUND ] @@ -611,6 +627,10 @@ W: https://deb.nodesource.com/node_22.x/dists/nodistro/InRelease: Policy will re - Test and debug information : /var/log/lynis.log - Report data : /var/log/lynis-report.dat +================================================================================ + + Notice: This version of Lynis is older than 6 months and might be outdated. Check the project page if a newer version is available. + ================================================================================ Notice: No OS entry was found in the end-of-life database diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8391c20..2654e0b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -23,6 +23,7 @@ include_toc: true * **Added**: [9990-overlay.sh](../config/includes.chroot/usr/lib/live/boot/9990-overlay.sh) Module summary * **Changed**: [9999_cdi_starter.sh](../scripts/usr/local/sbin/9999_cdi_starter.sh) Fixed: ``sysctl -p /etc/sysctl.d/90-ciss-local.hardened`` * **Changed**: [0042_ciss_post_decrypt_attest](../config/includes.chroot/usr/lib/live/boot/0042_ciss_post_decrypt_attest) Fixed: Signature checksum verification. +* **Changed**: [0024-ciss-crypt-squash](../config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash) Added: ``ensure_minimal_dev_nodes()`` ## V9.14.016.2026.06.06 * **Changed**: [zzzz_ciss_uki_build.hook.binary](../config/hooks/live/zzzz_ciss_uki_build.hook.binary)