19 Commits

Author SHA256 Message Date
msw a8454eeadf V9.14.028.2026.06.18
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-18 10:49:41 +01:00
msw f31ac3503f V9.14.026.2026.06.17
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-18 06:46:41 +01:00
msw 0f28dad6c2 V9.14.026.2026.06.17
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-17 21:55:52 +01:00
msw 784c088c0e V9.14.026.2026.06.17
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-17 18:44:12 +01:00
msw 1d130a7027 V9.14.026.2026.06.17
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-17 17:14:45 +01:00
msw 7fb6ca2cd2 V9.14.026.2026.06.17
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-17 16:31:47 +01:00
msw 009f92aea1 V9.14.026.2026.06.17
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-17 15:49:17 +01:00
msw e11b6285ca V9.14.026.2026.06.12
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-12 06:26:46 +01:00
msw b59bca727e V9.14.026.2026.06.12
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-12 05:30:51 +01:00
msw 7bb871e3f7 V9.14.026.2026.06.12
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-12 05:24:03 +01:00
msw 4633ff5ea7 V9.14.026.2026.06.12
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-12 04:52:18 +01:00
msw bd5c7729a2 V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 21:15:37 +01:00
msw 666111df0e V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 20:39:50 +01:00
msw 5cc2110ecb V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 20:14:31 +01:00
msw f6ca83fb26 V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 18:54:19 +01:00
msw ab827e9c05 V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 18:13:13 +01:00
msw b81b9bf836 V9.14.024.2026.06.11
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 17:29:59 +01:00
msw 487d2b3ba8 V9.14.024.2026.06.11
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 17:12:23 +01:00
msw 97596fbcba V9.14.024.2026.06.11
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
2026-06-11 17:11:22 +01:00
70 changed files with 2144 additions and 772 deletions
@@ -46,20 +46,24 @@ Verify_checksums() {
LIVE_VERIFY_CHECKSUMS_SIGNATURES="false" LIVE_VERIFY_CHECKSUMS_SIGNATURES="false"
_KEYFILE="" _CHECKSUM_LOG_DIR="${LIVE_VERIFY_CHECKSUMS_LOG_DIR:-/run}"
_MANIFEST_FOUND="false" _KEYFILE=""
_MP="" _MP=""
_RETURN_PGP="" _MANIFEST_FOUND="false"
_RETURN_SHA="" _TOOL_FOUND="false"
_VERIFICATION_EXECUTED="false" _VERIFICATION_EXECUTED="false"
_VERIFICATION_SUCCEEDED="false" _VERIFICATION_SUCCEEDED="false"
_RETURN_PGP=""
_RETURN_SHA=""
### Parse commandline arguments ---------------------------------------------------------------------------------------------- ### Parse commandline arguments ----------------------------------------------------------------------------------------------
# shellcheck disable=SC2154 # shellcheck disable=SC2154
for _PARAMETER in ${LIVE_BOOT_CMDLINE}; do for _PARAMETER in ${LIVE_BOOT_CMDLINE}; do
@@ -118,6 +122,14 @@ Verify_checksums() {
done done
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ] && [ -z "${_KEYFILE}" ]; then
printf "\e[91m[FATAL] No pinned GPG key file found while checksum signature verification is enabled. \n\e[0m"
sleep 8
panic "No pinned GPG key file found while checksum signature verification is enabled."
fi
# shellcheck disable=SC2164 # shellcheck disable=SC2164
cd "${_MOUNTPOINT}" cd "${_MOUNTPOINT}"
@@ -215,11 +227,13 @@ Verify_checksums() {
if [ -e "${_CHECKSUM}" ]; then if [ -e "${_CHECKSUM}" ]; then
_MANIFEST_FOUND="true" _MANIFEST_FOUND="true"
printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "${_CHECKSUM}" printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "${_CHECKSUM}"
if [ -e "/usr/bin/${_DIGEST}sum" ]; then if [ -e "/usr/bin/${_DIGEST}sum" ]; then
_VERIFICATION_EXECUTED="true" _TOOL_FOUND="true"
printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "/usr/bin/${_DIGEST}sum" printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "/usr/bin/${_DIGEST}sum"
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
@@ -247,19 +261,34 @@ Verify_checksums() {
fi fi
# shellcheck disable=SC2312 # shellcheck disable=SC2312
if grep -v '^#' "${_CHECKSUM}" | /usr/bin/"${_DIGEST}"sum -c > "${_TTY}"; then _VERIFICATION_EXECUTED="true"
_CHECKSUM_LOG="${_CHECKSUM_LOG_DIR}/ciss-${_DIGEST}sum-check.log"
if ! grep -v '^#' "${_CHECKSUM}" | grep -q '[^[:space:]]'; then
_RETURN_SHA="254"
: > "${_CHECKSUM_LOG}"
printf "\e[91m[FATAL] Checksum manifest has no checksum entries: [%s] \n\e[0m" "${_CHECKSUM}"
elif grep -v '^#' "${_CHECKSUM}" | /usr/bin/"${_DIGEST}"sum -c > "${_CHECKSUM_LOG}" 2>&1; then
_RETURN_SHA="${?}" _RETURN_SHA="${?}"
_VERIFICATION_SUCCEEDED="true" cat "${_CHECKSUM_LOG}" > "${_TTY}"
printf "\e[92m[INFO] Found: [%s] successful verified: [%s] \n\e[0m" "/usr/bin/${_DIGEST}sum" "${_CHECKSUM}" printf "\e[92m[INFO] Found: [%s] successful verified: [%s] \n\e[0m" "/usr/bin/${_DIGEST}sum" "${_CHECKSUM}"
else else
_RETURN_SHA="${?}" _RETURN_SHA="${?}"
cat "${_CHECKSUM_LOG}" > "${_TTY}"
printf "\e[91m[FATAL] Found: [%s] unsuccessful verified: [%s] \n\e[0m" "/usr/bin/${_DIGEST}sum" "${_CHECKSUM}" printf "\e[91m[FATAL] Found: [%s] unsuccessful verified: [%s] \n\e[0m" "/usr/bin/${_DIGEST}sum" "${_CHECKSUM}"
fi fi
if { [ "${_RETURN_PGP}" = "0" ] || [ "${_RETURN_PGP}" = "na" ]; } && [ "${_RETURN_SHA}" = "0" ]; then
_VERIFICATION_SUCCEEDED="true"
fi
# Stop after the first verification. # Stop after the first verification.
break 2 break 2
@@ -281,28 +310,31 @@ Verify_checksums() {
if [ "${_MANIFEST_FOUND}" != "true" ]; then if [ "${_MANIFEST_FOUND}" != "true" ]; then
printf "\e[91m[FATAL] No supported checksum manifest found. \n\e[0m" printf "\e[91m[FATAL] No supported checksum manifest found. Checksum verification is fail-closed. \n\e[0m"
sleep 8 sleep 8
panic "No supported checksum manifest found." panic "No supported checksum manifest found. Checksum verification is fail-closed."
return 1
fi
if [ "${_TOOL_FOUND}" != "true" ]; then
printf "\e[91m[FATAL] Checksum manifest found, but no supported checksum tool is available. Checksum verification is fail-closed. \n\e[0m"
sleep 8
panic "Checksum manifest found, but no supported checksum tool is available. Checksum verification is fail-closed."
fi fi
if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then
printf "\e[91m[FATAL] No supported checksum verification tool was available. \n\e[0m" printf "\e[91m[FATAL] Checksum verification was not executed. Checksum verification is fail-closed. \n\e[0m"
sleep 8 sleep 8
panic "No supported checksum verification tool was available." panic "Checksum verification was not executed. Checksum verification is fail-closed."
return 1
fi fi
if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then
printf "\e[91m[FATAL] No supported checksum manifest was verified successfully. \n\e[0m" printf "\e[91m[FATAL] Checksum verification did not complete successfully. Evaluating fail-closed failure state. \n\e[0m"
sleep 8
panic "No supported checksum manifest was verified successfully."
return 1
fi fi
@@ -329,7 +361,6 @@ Verify_checksums() {
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}" printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
sleep 8 sleep 8
panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed." panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
return 1
;; ;;
*",0") *",0")
@@ -337,7 +368,6 @@ Verify_checksums() {
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}" printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
sleep 8 sleep 8
panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful." panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
return 1
;; ;;
"na,"*) "na,"*)
@@ -345,14 +375,12 @@ Verify_checksums() {
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}" printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
sleep 8 sleep 8
panic "Verification of checksum file failed." panic "Verification of checksum file failed."
return 1
;; ;;
*) *)
printf "\e[91m[FATAL] Checksum verification ended in an unsupported state. \n\e[0m" printf "\e[91m[FATAL] Unknown checksum verification state: [%s,%s]. \n\e[0m" "${_RETURN_PGP:-unset}" "${_RETURN_SHA:-unset}"
sleep 8 sleep 8
panic "Checksum verification ended in an unsupported state." panic "Unknown checksum verification state. Checksum verification is fail-closed."
return 1
;; ;;
esac esac
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔐 Generating a Private Live ISO TRIXIE. name: 🔐 Generating a Private Live ISO TRIXIE.
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔐 Generating a Private Live ISO TRIXIE. name: 🔐 Generating a Private Live ISO TRIXIE.
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 💙 Generating a PUBLIC Live ISO. name: 💙 Generating a PUBLIC Live ISO.
+1 -1
View File
@@ -25,7 +25,7 @@ body:
attributes: attributes:
label: "Version" label: "Version"
description: "Which version are you running? Use `./ciss_live_builder.sh -v`." description: "Which version are you running? Use `./ciss_live_builder.sh -v`."
placeholder: "e.g., Master V9.14.022.2026.06.10" placeholder: "e.g., Master V9.14.028.2026.06.18"
validations: validations:
required: true required: true
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
FROM debian:bookworm FROM debian:bookworm
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔁 Render README.md to README.html. name: 🔁 Render README.md to README.html.
@@ -11,5 +11,5 @@
build: build:
counter: 1023 counter: 1023
version: V9.14.022.2026.06.10 version: V9.14.028.2026.06.18
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml
+1 -1
View File
@@ -11,5 +11,5 @@
build: build:
counter: 1023 counter: 1023
version: V9.14.022.2026.06.10 version: V9.14.028.2026.06.18
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml
+1 -1
View File
@@ -11,5 +11,5 @@
build: build:
counter: 1023 counter: 1023
version: V9.14.022.2026.06.10 version: V9.14.028.2026.06.18
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔐 Generating a Private Live ISO TRIXIE. name: 🔐 Generating a Private Live ISO TRIXIE.
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔐 Generating a Private Live ISO TRIXIE. name: 🔐 Generating a Private Live ISO TRIXIE.
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 💙 Generating a PUBLIC Live ISO. name: 💙 Generating a PUBLIC Live ISO.
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
# Gitea Workflow: Shell-Script Linting # Gitea Workflow: Shell-Script Linting
# #
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🛡️ Retrieve DNSSEC status of coresecret.dev. name: 🛡️ Retrieve DNSSEC status of coresecret.dev.
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
name: 🔁 Render Graphviz Diagrams. name: 🔁 Render Graphviz Diagrams.
+1 -1
View File
@@ -15,5 +15,5 @@ properties_SPDX-License-Identifier="LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1 "
properties_SPDX-LicenseComment="This file is part of the CISS.debian.installer.secure framework." properties_SPDX-LicenseComment="This file is part of the CISS.debian.installer.secure framework."
properties_SPDX-PackageName="CISS.debian.live.builder" properties_SPDX-PackageName="CISS.debian.live.builder"
properties_SPDX-Security-Contact="security@coresecret.eu" properties_SPDX-Security-Contact="security@coresecret.eu"
properties_version="V9.14.022.2026.06.10" properties_version="V9.14.028.2026.06.18"
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
+1 -1
View File
@@ -6,7 +6,7 @@ Creator: Person: Marc S. Weidner (Centurion Intelligence Consulting Agency)
Created: 2025-05-07T12:00:00Z Created: 2025-05-07T12:00:00Z
Package: CISS.debian.live.builder Package: CISS.debian.live.builder
PackageName: CISS.debian.live.builder PackageName: CISS.debian.live.builder
PackageVersion: Master V9.14.022.2026.06.10 PackageVersion: Master V9.14.028.2026.06.18
PackageSupplier: Organization: Centurion Intelligence Consulting Agency PackageSupplier: Organization: Centurion Intelligence Consulting Agency
PackageDownloadLocation: https://git.coresecret.dev/msw/CISS.debian.live.builder PackageDownloadLocation: https://git.coresecret.dev/msw/CISS.debian.live.builder
PackageHomePage: https://git.coresecret.dev/msw/CISS.debian.live.builder PackageHomePage: https://git.coresecret.dev/msw/CISS.debian.live.builder
+38 -26
View File
@@ -2,7 +2,7 @@
gitea: none gitea: none
include_toc: true include_toc: true
--- ---
[![Static Badge](https://badges.coresecret.dev/badge/Release-V9.14.022.2026.06.10-white?style=plastic&logo=linux&logoColor=white&logoSize=auto&label=Release&color=%23FCC624)](https://git.coresecret.dev/msw/CISS.debian.live.builder) [![Static Badge](https://badges.coresecret.dev/badge/Release-V9.14.028.2026.06.18-white?style=plastic&logo=linux&logoColor=white&logoSize=auto&label=Release&color=%23FCC624)](https://git.coresecret.dev/msw/CISS.debian.live.builder)
&nbsp; &nbsp;
[![Static Badge](https://badges.coresecret.dev/badge/Licence-EUPL1.2-white?style=plastic&logo=europeanunion&logoColor=white&logoSize=auto&label=Licence&color=%23003399)](https://eupl.eu/1.2/en/) &nbsp; [![Static Badge](https://badges.coresecret.dev/badge/Licence-EUPL1.2-white?style=plastic&logo=europeanunion&logoColor=white&logoSize=auto&label=Licence&color=%23003399)](https://eupl.eu/1.2/en/) &nbsp;
[![Static Badge](https://badges.coresecret.dev/badge/opensourceinitiative-Compliant-white?style=plastic&logo=opensourceinitiative&logoColor=white&logoSize=auto&label=OSI&color=%233DA639)](https://opensource.org/license/eupl-1-2) &nbsp; [![Static Badge](https://badges.coresecret.dev/badge/opensourceinitiative-Compliant-white?style=plastic&logo=opensourceinitiative&logoColor=white&logoSize=auto&label=OSI&color=%233DA639)](https://opensource.org/license/eupl-1-2) &nbsp;
@@ -27,7 +27,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
**CISS.debian.live.builder — First of its own.**<br> **CISS.debian.live.builder — First of its own.**<br>
**World-class CIA: Designed, handcrafted, and powered by Centurion Intelligence Consulting Agency.** **World-class CIA: Designed, handcrafted, and powered by Centurion Intelligence Consulting Agency.**
@@ -46,9 +46,10 @@ Beyond a conventional live system, **CISS.debian.live.builder** assembles a **fu
in a single, deterministic build step: a LUKS2 container backed by `dm-integrity` hosting the SquashFS root filesystem, combined in a single, deterministic build step: a LUKS2 container backed by `dm-integrity` hosting the SquashFS root filesystem, combined
with a hardened initramfs chain including a dedicated Dropbear build pipeline for remote LUKS unlock. The resulting ISO ships with a hardened initramfs chain including a dedicated Dropbear build pipeline for remote LUKS unlock. The resulting ISO ships
with a hardened kernel configuration, strict sysctl and network tuning, pre-configured SSH hardening and fail2ban, and a with a hardened kernel configuration, strict sysctl and network tuning, pre-configured SSH hardening and fail2ban, and a
customised `verify-checksums` path providing both ISO-edge verification and runtime attestation of the live root. All components customised `verify-checksums` path providing fail-closed mounted-medium verification plus runtime attestation of the exact
are aligned with the `CISS.debian.installer` baseline, ensuring a unified cryptographic and security posture from first boot to final SquashFS payload bytes selected for the encrypted live root. All components are aligned with the `CISS.debian.installer`
an installed system. For an overview of the entire build process, see: baseline, ensuring a unified cryptographic and security posture from first boot to an installed system. For an overview of the
entire build process, see:
**[MAN_CISS_ISO_BOOT_CHAIN.md](docs/MAN_CISS_ISO_BOOT_CHAIN.md)** **[MAN_CISS_ISO_BOOT_CHAIN.md](docs/MAN_CISS_ISO_BOOT_CHAIN.md)**
When built with the ``--dhcp-centurion`` profile, the live system ships with a strict network and resolver policy: When built with the ``--dhcp-centurion`` profile, the live system ships with a strict network and resolver policy:
@@ -60,12 +61,17 @@ and spoofing surfaces.
Internally, the builder employs a dedicated secret-handling pipeline backed by a tmpfs-only secrets directory Internally, the builder employs a dedicated secret-handling pipeline backed by a tmpfs-only secrets directory
(`/dev/shm/cdlb_secrets`). Sensitive material such as root passwords, SSH keys, and signing keys never appears on the command (`/dev/shm/cdlb_secrets`). Sensitive material such as root passwords, SSH keys, and signing keys never appears on the command
line, is guarded by strict `0400 root:root` permissions, and any symlink inside the secret path is treated as a hard failure line. The secret root must be an existing `root:root` tmpfs or ramfs directory with `0700` permissions and no symlinks or
that aborts the run. Critical code paths temporarily disable Bash xtrace so that credentials never leak into debug logs, and special files below it. Filename-only secret arguments are rejected when they contain path separators, traversal names, shell
transient secret files are shredded (`shred -fzu`) as soon as they are no longer needed. GNUPG homes used for signing are metacharacters, or unsafe leading dashes. Critical code paths temporarily disable Bash xtrace so that credentials never leak
wiped, unencrypted chroot artifacts and includes are removed after `lb build`, and the final artifact is reduced to the into debug logs; the final exact-value sanitization pass runs only after xtrace has been stopped and its debug file descriptor
encrypted SquashFS inside the LUKS2 container. At runtime, LUKS passphrases in the live ISO and installer are transported via has been closed, then redacts still-known secret values from debug, variable, and error logs as defense in depth. Transient
named pipes inside the initramfs instead of process arguments, further minimizing exposure in process listings. secret files are shredded (`shred -fzu`) as soon as they are no longer needed; this is best-effort on SSD/NVMe media, so the
architecture relies primarily on tmpfs for secret staging. GNUPG homes used for signing are wiped,
unencrypted chroot artifacts and includes are removed after `lb build`, and cleanup is intentionally destructive only inside
the exact build directory carrying the `.ciss-live-builder-owned` marker. At runtime, LUKS passphrases in the live ISO and
installer are transported via named pipes inside the initramfs instead of process arguments, further minimizing exposure in
process listings.
Check out more leading world-class services powered by Centurion Intelligence Consulting Agency: Check out more leading world-class services powered by Centurion Intelligence Consulting Agency:
* [CenturionDNS Resolver](https://eddns.eu/) * [CenturionDNS Resolver](https://eddns.eu/)
@@ -123,7 +129,7 @@ lockstep avoids those mismatches and gives me predictable artifacts across build
The live ISO acts as a sealed, immutable execution environment. All relevant configuration, all installation logic, and all The live ISO acts as a sealed, immutable execution environment. All relevant configuration, all installation logic, and all
security decisions are rendered into the image at build time and treated as read-only at runtime. On top of that logical security decisions are rendered into the image at build time and treated as read-only at runtime. On top of that logical
immutability, I now layer cryptographic protection of the live root file system itself. The live image contains a LUKS2 container immutability, I now layer cryptographic protection of the live root file system itself. The live image contains a LUKS2 container
file with dm-integrity that wraps the SquashFS payload. The initramfs knows how to locate this container, unlock it, verify its file with dm-integrity that wraps the SquashFS payload. The initramfs knows how to locate this container, unlock it, verify its
integrity, and then present the decrypted SquashFS as the root component of an OverlayFS stack. The detailed boot and integrity, and then present the decrypted SquashFS as the root component of an OverlayFS stack. The detailed boot and
verification chain is documented separately in **[CISS ISO Boot Chain](docs/MAN_CISS_ISO_BOOT_CHAIN.md)**<br> verification chain is documented separately in **[CISS ISO Boot Chain](docs/MAN_CISS_ISO_BOOT_CHAIN.md)**<br>
@@ -131,7 +137,7 @@ verification chain is documented separately in **[CISS ISO Boot Chain](docs/MAN_
In compact form, my expectations for the system are:<br> In compact form, my expectations for the system are:<br>
* Every bit that matters for boot and provisioning is covered by checksums that I control and that are signed with keys under my solely authoritative HSM. * Every bit that matters for boot and provisioning is covered by checksums that I control and that are signed with keys under my solely authoritative HSM.
* The live root runs out of a LUKS2 dm-integrity container so that a tampered or bit-rotted SquashFS never becomes a trusted root. * The live root runs out of a LUKS2 dm-integrity container, and the final SquashFS byte stream copied into the decrypted mapper is verified against a signed rootfs attestation manifest, so a tampered or bit-rotted SquashFS never becomes a trusted root. During boot, `0024-ciss-crypt-squash` copies `/live/filesystem.squashfs.sha512sum.txt[.sig]` from the real ISO medium to `/run/ciss-rootfs-attestation/`; `0042_ciss_post_decrypt_attest` then verifies that cached manifest/signature pair against `/etc/ciss/keys/<FPR>.gpg` and the exact bytes read from `/dev/mapper/crypt_liveiso`.
* Verification steps are not advisory. Any anomaly causes a hard abort during boot. * Verification steps are not advisory. Any anomaly causes a hard abort during boot.
* After the live environment has reached a stable, verified state, it can hand off to ``CISS.debian.installer``. The installer operates from the same image, does not pull random payloads from the internet, and keeps the target system behind a hardened firewall until the entire provisioning process has completed. * After the live environment has reached a stable, verified state, it can hand off to ``CISS.debian.installer``. The installer operates from the same image, does not pull random payloads from the internet, and keeps the target system behind a hardened firewall until the entire provisioning process has completed.
* For unattended, headless scenarios I also support builds where the target system is installed without ever exposing a shell over the console. After installation and reboot, the machine waits for a decryption passphrase via an embedded Dropbear SSH instance in the initramfs, limited to public key authentication and guarded by strict cryptographic policies. In such variants even ``/boot`` can be encrypted, with GRUB taking care of unlocking the boot partition. * For unattended, headless scenarios I also support builds where the target system is installed without ever exposing a shell over the console. After installation and reboot, the machine waits for a decryption passphrase via an embedded Dropbear SSH instance in the initramfs, limited to public key authentication and guarded by strict cryptographic policies. In such variants even ``/boot`` can be encrypted, with GRUB taking care of unlocking the boot partition.
@@ -175,7 +181,7 @@ installer toolchain.
This project adheres strictly to a structured versioning scheme following the pattern x.y.z-Date. This project adheres strictly to a structured versioning scheme following the pattern x.y.z-Date.
Example: `V9.14.022.2026.06.10` Example: `V9.14.028.2026.06.18`
`x.y.z` represents major (x), minor (y), and patch (z) version increments. `x.y.z` represents major (x), minor (y), and patch (z) version increments.
@@ -369,7 +375,7 @@ For further details see: **[90-ciss-local.hardened.md](docs/documentation/90-cis
`--primordial-ssh <port>` configure the CDI Primordial overlay clone. `--primordial-ssh` also adds an outgoing-only UFW TCP `--primordial-ssh <port>` configure the CDI Primordial overlay clone. `--primordial-ssh` also adds an outgoing-only UFW TCP
exception for a bootstrap/recovery SSH port when the live system's UFW outgoing policy is `deny`. It adds no incoming firewall exception for a bootstrap/recovery SSH port when the live system's UFW outgoing policy is `deny`. It adds no incoming firewall
rule and does not replace `--ssh-port`. If the requested port already matches an existing outgoing SSH exception, the current rule and does not replace `--ssh-port`. If the requested port already matches an existing outgoing SSH exception, the current
hook still emits the requested labelled rule because this repository has no separate UFW rule deduplication layer. hook still emits the requested labeled rule because this repository has no separate UFW rule deduplication layer.
* **Rationale**: Implements a default-deny firewall, reducing lateral movement and data exfiltration risks immediately after * **Rationale**: Implements a default-deny firewall, reducing lateral movement and data exfiltration risks immediately after
deployment. deployment.
@@ -493,10 +499,13 @@ To use **``CISS.debian.live.builder``** as intended, the following baseline is e
2. Preparation: 2. Preparation:
1. Ensure you are root. 1. Ensure you are root.
2. Create the build directory `mkdir /opt/cdlb` and the tmpfs secrets directory `mkdir /dev/shm/cdlb_secrets`. 2. Create the build directory `install -d -m 0755 -o root -g root /opt/cdlb` and the tmpfs secrets directory
`install -d -m 0700 -o root -g root /dev/shm/cdlb_secrets`.
3. Place your desired SSH public key in the `authorized_keys` file, for example, in the `/dev/shm/cdlb_secrets` directory. 3. Place your desired SSH public key in the `authorized_keys` file, for example, in the `/dev/shm/cdlb_secrets` directory.
4. Place your desired Password in the `password.txt` file, for example, in the `/dev/shm/cdlb_secrets` directory. 4. Place your desired Password in the `password.txt` file, for example, in the `/dev/shm/cdlb_secrets` directory.
5. Make any other changes you need to. 5. Keep files below `/dev/shm/cdlb_secrets` as regular, non-symlink files owned by `root:root`; the builder normalizes them
to `0400` before use.
6. Make any other changes you need to.
3. Run the config builder script `./ciss_live_builder.sh` and the integrated `lb build` command (example): 3. Run the config builder script `./ciss_live_builder.sh` and the integrated `lb build` command (example):
@@ -505,7 +514,7 @@ To use **``CISS.debian.live.builder``** as intended, the following baseline is e
timestamp=$(date -u +%Y-%m-%dT%H:%M:%S%z) timestamp=$(date -u +%Y-%m-%dT%H:%M:%S%z)
./ciss_live_builder.sh \ ./ciss_live_builder.sh \
--architecture amd64 \ --architecture amd64 \
--autobuild=6.16.3+deb13-amd64 \ --autobuild=7.0.10+deb13-amd64 \
--build-directory /opt/cdlb \ --build-directory /opt/cdlb \
--cdi \ --cdi \
--change-splash hexagon \ --change-splash hexagon \
@@ -525,9 +534,9 @@ To use **``CISS.debian.live.builder``** as intended, the following baseline is e
--signing_key_pass=signing_key_pass.txt \ --signing_key_pass=signing_key_pass.txt \
--signing_key=signing_key.asc \ --signing_key=signing_key.asc \
--ssh-port 4242 \ --ssh-port 4242 \
--primordial-url https://git.coresecret.dev/ahz/PhysNet.primordial.git \ --primordial-key SSH-key-filename-for-Primordial-overlay-clone \
--primordial-key id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10 \ --primordial-ssh SSH-port-for-Primordial-overlay-clone \
--primordial-ssh 42842 \ --primordial-url URL-to-Primordial-overlay-clone \
--ssh-pubkey /dev/shm/cdlb_secrets \ --ssh-pubkey /dev/shm/cdlb_secrets \
--sshfp \ --sshfp \
--trixie --trixie
@@ -559,10 +568,13 @@ preview it or run it.
2. Preparation: 2. Preparation:
1. Ensure you are root. 1. Ensure you are root.
2. Create the build directory `mkdir /opt/cdlb` and the tmpfs secrets directory `mkdir /dev/shm/cdlb_secrets`. 2. Create the build directory `install -d -m 0755 -o root -g root /opt/cdlb` and the tmpfs secrets directory
`install -d -m 0700 -o root -g root /dev/shm/cdlb_secrets`.
3. Place your desired SSH public key in the `authorized_keys` file, for example, in the `/dev/shm/cdlb_secrets` directory. 3. Place your desired SSH public key in the `authorized_keys` file, for example, in the `/dev/shm/cdlb_secrets` directory.
4. Place your desired Password in the `password.txt` file, for example, in the `/dev/shm/cdlb_secrets` directory. 4. Place your desired Password in the `password.txt` file, for example, in the `/dev/shm/cdlb_secrets` directory.
5. Copy and edit the sample and set your options (no spaces around commas in lists): 5. Keep files below `/dev/shm/cdlb_secrets` as regular, non-symlink files owned by `root:root`; the builder normalizes them
to `0400` before use.
6. Copy and edit the sample and set your options (no spaces around commas in lists):
````bash ````bash
cp config.mk.sample config.mk cp config.mk.sample config.mk
@@ -577,9 +589,9 @@ preview it or run it.
SSH_PUBKEY=/dev/shm/cdlb_secrets SSH_PUBKEY=/dev/shm/cdlb_secrets
# Optional # Optional
PRIMORDIAL_URL=https://git.coresecret.dev/ahz/PhysNet.primordial.git PRIMORDIAL_KEY=SSH-key-filename-for-Primordial-overlay-clone
PRIMORDIAL_KEY=id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10 PRIMORDIAL_SSH_PORT=SSH-port-for-Primordial-overlay-clone
PRIMORDIAL_SSH_PORT=42842 PRIMORDIAL_URL=URL-to-Primordial-overlay-clone
PROVIDER_NETCUP_IPV6=2001:cdb::1 PROVIDER_NETCUP_IPV6=2001:cdb::1
# comma-separated; IPv6 in [] is fine # comma-separated; IPv6 in [] is fine
JUMP_HOSTS=[2001:db8::1],[2001:db8::2] JUMP_HOSTS=[2001:db8::1],[2001:db8::2]
+2 -2
View File
@@ -8,13 +8,13 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Repository Structure # 2. Repository Structure
**Project:** Centurion Intelligence Consulting Agency Information Security Standard (CISS) — Debian Live Builder **Project:** Centurion Intelligence Consulting Agency Information Security Standard (CISS) — Debian Live Builder
**Branch:** `master` **Branch:** `master`
**Repository State:** Master Version **9.14**, Build **V9.14.022.2026.06.10** (as of 2025-10-11) **Repository State:** Master Version **9.14**, Build **V9.14.028.2026.06.18** (as of 2025-10-11)
## 3.1. Top-Level Layout ## 3.1. Top-Level Layout
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. CISS Secure Boot Private Material # 2. CISS Secure Boot Private Material
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. CISS Secure Boot Public Material # 2. CISS Secure Boot Public Material
+33 -20
View File
@@ -41,6 +41,8 @@ declare -grx VAR_SETUP_PATH="$(cd "$(dirname "${0}")" && pwd)" # '/roo
declare -grx VAR_TMP_SECRET="/dev/shm/cdlb_secrets" # Fixed tmpfs path to store securely build artifacts. declare -grx VAR_TMP_SECRET="/dev/shm/cdlb_secrets" # Fixed tmpfs path to store securely build artifacts.
declare -grx VAR_WORKDIR="$(dirname "${VAR_SETUP_FULL}")" # '/root/git/CISS.debian.live.builder' declare -grx VAR_WORKDIR="$(dirname "${VAR_SETUP_FULL}")" # '/root/git/CISS.debian.live.builder'
clear
### PRELIMINARY CHECKS. ### PRELIMINARY CHECKS.
### No ash, dash, ksh, sh. ### No ash, dash, ksh, sh.
# shellcheck disable=SC2292 # shellcheck disable=SC2292
@@ -116,7 +118,6 @@ for arg in "$@"; do case "${arg,,}" in -v|--version) . ./lib/lib_version.sh ;
for arg in "$@"; do case "${arg,,}" in -d|--debug) . ./meta_sources_debug.sh; debugger "${@}";; esac; done for arg in "$@"; do case "${arg,,}" in -d|--debug) . ./meta_sources_debug.sh; debugger "${@}";; esac; done
### ALL CHECKS DONE. READY TO START THE SCRIPT. ### ALL CHECKS DONE. READY TO START THE SCRIPT.
clear
printf '\033[95m' printf '\033[95m'
cat bootscreen.txt cat bootscreen.txt
printf '\033[0m\n' printf '\033[0m\n'
@@ -143,6 +144,7 @@ find "${VAR_TMP_SECRET}" -type f -exec chown root:root {} +
[[ "${VAR_SETUP}" == true ]] && { [[ "${VAR_SETUP}" == true ]] && {
source_guard "./lib/lib_arg_parser.sh" source_guard "./lib/lib_arg_parser.sh"
source_guard "./lib/lib_arg_priority_check.sh" source_guard "./lib/lib_arg_priority_check.sh"
source_guard "./lib/lib_build_dir_safety.sh"
source_guard "./lib/lib_boot_screen.sh" source_guard "./lib/lib_boot_screen.sh"
source_guard "./lib/lib_cdi.sh" source_guard "./lib/lib_cdi.sh"
source_guard "./lib/lib_change_splash.sh" source_guard "./lib/lib_change_splash.sh"
@@ -160,6 +162,7 @@ find "${VAR_TMP_SECRET}" -type f -exec chown root:root {} +
source_guard "./lib/lib_clean_screen.sh" source_guard "./lib/lib_clean_screen.sh"
source_guard "./lib/lib_clean_up.sh" source_guard "./lib/lib_clean_up.sh"
source_guard "./lib/lib_copy_integrity.sh" source_guard "./lib/lib_copy_integrity.sh"
source_guard "./lib/lib_debug_sanitize.sh"
source_guard "./lib/lib_gnupg.sh" source_guard "./lib/lib_gnupg.sh"
source_guard "./lib/lib_hardening_root_pw.sh" source_guard "./lib/lib_hardening_root_pw.sh"
source_guard "./lib/lib_hardening_ssh_tcp.sh" source_guard "./lib/lib_hardening_ssh_tcp.sh"
@@ -173,6 +176,7 @@ find "${VAR_TMP_SECRET}" -type f -exec chown root:root {} +
source_guard "./lib/lib_provider_netcup.sh" source_guard "./lib/lib_provider_netcup.sh"
source_guard "./lib/lib_run_analysis.sh" source_guard "./lib/lib_run_analysis.sh"
source_guard "./lib/lib_sanitizer.sh" source_guard "./lib/lib_sanitizer.sh"
source_guard "./lib/lib_secret_validation.sh"
source_guard "./lib/lib_secureboot_profile.sh" source_guard "./lib/lib_secureboot_profile.sh"
source_guard "./lib/lib_trap_on_err.sh" source_guard "./lib/lib_trap_on_err.sh"
source_guard "./lib/lib_trap_on_exit.sh" source_guard "./lib/lib_trap_on_exit.sh"
@@ -180,22 +184,6 @@ find "${VAR_TMP_SECRET}" -type f -exec chown root:root {} +
source_guard "./lib/lib_usage.sh" source_guard "./lib/lib_usage.sh"
} }
### PRE-SCAN SECURE BOOT PROFILE FOR BUILD-HOST PACKAGE CHECKS.
### Formal validation still happens in arg_parser().
for ((idx=0; idx<${#ARY_PARAM_ARRAY[@]}; idx++)); do
case "${ARY_PARAM_ARRAY[idx],,}" in
--secure-boot-profile=*)
declare -gx VAR_CISS_SECUREBOOT_PROFILE="${ARY_PARAM_ARRAY[idx]#*=}"
;;
--secure-boot-profile)
if [[ -n "${ARY_PARAM_ARRAY[idx + 1]:-}" ]]; then
declare -gx VAR_CISS_SECUREBOOT_PROFILE="${ARY_PARAM_ARRAY[idx + 1]}"
fi
;;
esac
done
unset idx
### CHECKING REQUIRED PACKAGES. ### CHECKING REQUIRED PACKAGES.
check_pkgs check_pkgs
@@ -221,9 +209,30 @@ if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen; fi
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nInitialization done ... \nXXX\n15\n" >&3; fi if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nInitialization done ... \nXXX\n15\n" >&3; fi
### Updating Status of Dialog Gauge Bar. ### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nActivate traps ... \nXXX\n50\n" >&3; fi if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nValidating secrets artifacts ... \nXXX\n20\n" >&3; fi
validate_secret_root "${VAR_TMP_SECRET}"
harden_secret_root_files "${VAR_TMP_SECRET}"
### Following the CISS Bash naming and ordering scheme: ### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nPre-Scan Secure-Boot ... \nXXX\n30\n" >&3; fi
### PRE-SCAN SECURE BOOT PROFILE FOR BUILD-HOST PACKAGE CHECKS.
### Formal validation still happens in arg_parser().
for ((idx=0; idx<${#ARY_PARAM_ARRAY[@]}; idx++)); do
case "${ARY_PARAM_ARRAY[idx],,}" in
--secure-boot-profile=*)
declare -gx VAR_CISS_SECUREBOOT_PROFILE="${ARY_PARAM_ARRAY[idx]#*=}"
;;
--secure-boot-profile)
if [[ -n "${ARY_PARAM_ARRAY[idx + 1]:-}" ]]; then
declare -gx VAR_CISS_SECUREBOOT_PROFILE="${ARY_PARAM_ARRAY[idx + 1]}"
fi
;;
esac
done
unset idx
### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nTraps active ... \nXXX\n50\n" >&3; fi
trap 'trap_on_exit "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' EXIT trap 'trap_on_exit "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' EXIT
trap 'trap_on_err "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' ERR trap 'trap_on_err "$?" "${BASH_SOURCE[0]}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_COMMAND}"' ERR
@@ -234,9 +243,13 @@ declare -ar ARY_ARG_SANITIZED=("$@")
declare -grx VAR_ARG_SANITIZED="${ARY_ARG_SANITIZED[*]}" declare -grx VAR_ARG_SANITIZED="${ARY_ARG_SANITIZED[*]}"
### Updating Status of Dialog Gauge Bar. ### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nParsing Arguments ... \nXXX\n90\n" >&3; fi if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nParsing Arguments ... \nXXX\n80\n" >&3; fi
arg_parser "$@" arg_parser "$@"
### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nValidate secret Arguments ... \nXXX\n95\n" >&3; fi
validate_selected_secret_inputs
### Updating Status of Dialog Gauge Bar. ### Updating Status of Dialog Gauge Bar.
if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nFinal checks ... \nXXX\n95\n" >&3; fi if ! ${VAR_HANDLER_AUTOBUILD}; then printf "XXX\nFinal checks ... \nXXX\n95\n" >&3; fi
clean_ip clean_ip
@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# shellcheck disable=SC2154
# SPDX-Version: 3.0 # SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-10-11; WEIDNER, Marc S.; <msw@coresecret.dev> # SPDX-CreationInfo: 2025-10-11; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
@@ -9,90 +10,18 @@
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework. # SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2154
set -Ceuo pipefail set -Ceuo pipefail
# Final live-build binary hook for encrypted root filesystem packaging. Preallocate a LUKS2 container, format it with the # Final live-build binary hook for encrypted root filesystem packaging. It creates and signs a deterministic attestation
# generated build secret, copy the generated filesystem.squashfs into the opened encrypted mapping, generate and sign a # manifest for the final filesystem.squashfs byte stream, preallocates a LUKS2 container, formats it with the generated build
# SHA-512 attestation manifest for the complete decrypted mapper, then close the container, shred the temporary LUKS secret, # secret, copies the generated filesystem.squashfs into the opened encrypted mapping, then closes the container, shreds the
# and remove the plaintext SquashFS from the ISO payload. # temporary LUKS secret, and removes the plaintext SquashFS from the ISO payload.
printf "\e[95m🧪 '%s' starting ... \e[0m\n" "${0}" printf "\e[95m🧪 '%s' starting ... \e[0m\n" "${0}"
__umask=$(umask) __umask=$(umask)
umask 0077 umask 0077
#######################################
# Prints a fatal error message and terminates the hook.
# Globals:
# None
# Arguments:
# 1: Error message
# Returns:
# 42: always exits with failure
#######################################
die() {
declare message="${1}"
printf "\e[91m❌ %s \e[0m\n" "${message}" >&2
exit 42
}
#######################################
# Checks whether a required command exists.
# Globals:
# None
# Arguments:
# 1: Command name
# Returns:
# 0: on success
# 42: if the command is missing
#######################################
require_command() {
declare command_name="${1}"
command -v "${command_name}" >/dev/null 2>&1 || die "Required command not found: '${command_name}'."
return 0
}
#######################################
# Checks whether a required file exists and is readable.
# Globals:
# None
# Arguments:
# 1: File path
# 2: Human-readable file description
# Returns:
# 0: on success
# 42: if the file is missing or unreadable
#######################################
require_file() {
declare file_path="${1}"
declare description="${2}"
[[ -f "${file_path}" && -r "${file_path}" ]] || die "Missing or unreadable ${description}: '${file_path}'."
return 0
}
#######################################
# Checks whether a required environment variable is non-empty.
# Globals:
# None
# Arguments:
# 1: Variable name
# Returns:
# 0: on success
# 42: if the variable is empty or unset
#######################################
require_variable() {
declare variable_name="${1}"
[[ -n "${!variable_name:-}" ]] || die "Required environment variable is empty or unset: '${variable_name}'."
return 0
}
####################################### #######################################
# Pre allocates space for LUKS container. # Pre allocates space for LUKS container.
# Globals: # Globals:
@@ -136,29 +65,163 @@ preallocate() {
# shellcheck disable=SC2034 # shellcheck disable=SC2034
readonly -f preallocate readonly -f preallocate
declare ROOTFS="${VAR_HANDLER_BUILD_DIR}/binary/live/filesystem.squashfs" #######################################
declare LUKSFS="${VAR_HANDLER_BUILD_DIR}/binary/live/ciss_rootfs.crypt" # Validate that the rootfs attestation artifacts exist in the final ISO payload tree.
declare MAPPER_DEV="/dev/mapper/crypt_liveiso" # Globals:
declare ROOTFS_ATTESTATION="${LUKSFS}.decrypted.sha512sum.txt" # None
declare ROOTFS_ATTESTATION_SIG="${ROOTFS_ATTESTATION}.sig" # Arguments:
declare KEYFD="" # 1: Rootfs attestation manifest path
# Returns:
# 0: on success
# 42: on failure
#######################################
require_rootfs_attestation_artifacts() {
declare manifest="${1}"
declare signature="${manifest}.sig"
declare artifact=""
require_command gpg for artifact in "${manifest}" "${signature}"; do
require_command gpgv
require_command sha512sum
require_file "${ROOTFS}" "final SquashFS payload"
require_variable VAR_SIGNING_KEY_FPR
require_variable VAR_SIGNING_KEY_PASSFILE
require_variable VAR_VERIFY_KEYRING
require_file "${VAR_SIGNING_KEY_PASSFILE}" "GPG signing passphrase file"
require_file "${VAR_VERIFY_KEYRING}" "GPG verification keyring"
[[ "${VAR_SIGNER:-false}" == "true" ]] || die "Rootfs attestation requires an enabled artifact signer." if [[ ! -e "${artifact}" ]]; then
rm -f -- "${ROOTFS_ATTESTATION}" "${ROOTFS_ATTESTATION_SIG}" printf "\e[91m❌ Required rootfs attestation artifact missing: [%s]. \e[0m\n" "${artifact}" >&2
return 42
fi
if [[ -L "${artifact}" || ! -f "${artifact}" ]]; then
printf "\e[91m❌ Required rootfs attestation artifact is not a regular file: [%s]. \e[0m\n" "${artifact}" >&2
return 42
fi
if [[ ! -s "${artifact}" ]]; then
printf "\e[91m❌ Required rootfs attestation artifact is empty: [%s]. \e[0m\n" "${artifact}" >&2
return 42
fi
if [[ ! -r "${artifact}" ]]; then
printf "\e[91m❌ Required rootfs attestation artifact is not readable: [%s]. \e[0m\n" "${artifact}" >&2
return 42
fi
done
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f require_rootfs_attestation_artifacts
#######################################
# Create and sign the rootfs attestation manifest for the exact SquashFS payload copied into the LUKS mapper.
# Globals:
# VAR_SIGNING_KEY_FPR
# VAR_SIGNING_KEY_PASSFILE
# VAR_VERIFY_KEYRING
# Arguments:
# 1: Final SquashFS payload file
# 2: Manifest path below binary/live
# Returns:
# 0: on success
# 42: on failure
#######################################
create_attestation() {
declare rootfs_file="${1}"
declare rootfs_attestation="${2}"
declare rootfs_hash=""
declare rootfs_size=""
rootfs_size="$(stat -c%s -- "${rootfs_file}")"
rootfs_hash="$(LC_ALL=C sha512sum "${rootfs_file}")"
rootfs_hash="${rootfs_hash%% *}"
if printf '%s %s\n' "${rootfs_hash}" "${rootfs_file}" | LC_ALL=C sha512sum -c --strict --quiet; then
printf "\e[92m✅ [LC_ALL=C sha512sum -c --strict --quiet of %s] successful. \e[0m\n" "${rootfs_file}"
else
printf "\e[91m❌ [LC_ALL=C sha512sum -c --strict --quiet of %s] NOT successful. \e[0m\n" "${rootfs_file}"
return 42
fi
# The attested boundary is the final SquashFS byte stream before LUKS wrapping. The boot verifier reads exactly this many
# bytes from the decrypted mapper and intentionally excludes the LUKS allocation slack after the SquashFS payload.
cat << EOF >| "${rootfs_attestation}"
# CISS.debian.live.builder Master ${VAR_VERSION}
# Attestation file for filesystem.squashfs Version 1.0.0
# Boundary : Final filesystem.squashfs byte stream copied into /dev/mapper/crypt_liveiso
# Bytes : Final filesystem.squashfs ${rootfs_size}
${rootfs_hash} filesystem.squashfs
EOF
chmod 0444 "${rootfs_attestation}"
if gpg --batch --yes --pinentry-mode loopback --passphrase-file "${VAR_SIGNING_KEY_PASSFILE}" --local-user "${VAR_SIGNING_KEY_FPR}" \
--detach-sign --output "${rootfs_attestation}.sig" "${rootfs_attestation}"; then
printf "\e[92m✅ [gpg of %s] successful. \e[0m\n" "${rootfs_attestation}"
else
printf "\e[91m❌ [gpg of %s] NOT successful. \e[0m\n" "${rootfs_attestation}"
return 42
fi
chmod 0444 "${rootfs_attestation}.sig"
if gpgv --keyring "${VAR_VERIFY_KEYRING}" "${rootfs_attestation}.sig" "${rootfs_attestation}"; then
printf "\e[92m✅ [gpgv of %s] successful. \e[0m\n" "${rootfs_attestation}.sig"
else
printf "\e[91m❌ [gpgv of %s] NOT successful. \e[0m\n" "${rootfs_attestation}.sig"
return 42
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f create_attestation
declare LIVE_PAYLOAD_DIR="${VAR_HANDLER_BUILD_DIR}/binary/live"
declare ROOTFS_ATTESTATION_NAME="filesystem.squashfs.sha512sum.txt"
declare ROOTFS_ATTESTATION_REL="live/${ROOTFS_ATTESTATION_NAME}"
declare LUKSFS="${LIVE_PAYLOAD_DIR}/ciss_rootfs.crypt"
declare ROOTFS="${LIVE_PAYLOAD_DIR}/filesystem.squashfs"
declare ROOTFS_ATTESTATION="${VAR_HANDLER_BUILD_DIR}/binary/${ROOTFS_ATTESTATION_REL}"
declare DM_LAB="crypt_liveiso"
declare DEVMAP="/dev/mapper/${DM_LAB}"
declare LUKS_KEY_FILE="${VAR_TMP_SECRET}/${VAR_LUKS_KEY:-luks.txt}"
declare KEYFD=""
# Keep Argon2 keyslot memory and parallel costs bounded for later initramfs unlocks on smaller systems.
declare -i LUKS_PBKDF_MEMORY_KIB=262144
declare -i LUKS_PBKDF_PARALLEL=1
# shellcheck disable=SC2155 # shellcheck disable=SC2155
declare -i VAR_ROOTFS_SIZE=$(stat -c%s -- "${ROOTFS}") declare -i VAR_ROOTFS_SIZE="$(stat -c%s -- "${ROOTFS}")"
### Attestation Boundary
# - The attested boundary is the final SquashFS byte stream before LUKS wrapping.
# - The boot verifier reads exactly this many bytes from the decrypted mapper and intentionally excludes the LUKS allocation
# slack after the SquashFS payload.
printf "\e[95m🧪 Attestation of filesystem.squashfs ... \e[0m\n"
create_attestation "${ROOTFS}" "${ROOTFS_ATTESTATION}"
require_rootfs_attestation_artifacts "${ROOTFS_ATTESTATION}"
printf "\e[92m✅ Attestation of filesystem.squashfs successful: ISO paths [/%s] and [/%s.sig]. \e[0m\n" \
"${ROOTFS_ATTESTATION_REL}" "${ROOTFS_ATTESTATION_REL}"
### Safety margin: ### Safety margin:
# - LUKS2-Header and Metadata # - LUKS2-Header and Metadata
@@ -172,7 +235,7 @@ declare -i VAR_LUKSFS_SIZE=$(( ( (BASE_SIZE + ALIGN_BYTES - 1) / ALIGN_BYTES ) *
preallocate "${LUKSFS}" "${VAR_LUKSFS_SIZE}" preallocate "${LUKSFS}" "${VAR_LUKSFS_SIZE}"
exec {KEYFD}<"${VAR_TMP_SECRET}/luks.txt" exec {KEYFD}<"${LUKS_KEY_FILE}"
if [[ "${VAR_CDLB_INSIDE_RUNNER}" == "false" ]]; then if [[ "${VAR_CDLB_INSIDE_RUNNER}" == "false" ]]; then
@@ -183,10 +246,12 @@ if [[ "${VAR_CDLB_INSIDE_RUNNER}" == "false" ]]; then
--iter-time 1000 \ --iter-time 1000 \
--key-file "/proc/$$/fd/${KEYFD}" \ --key-file "/proc/$$/fd/${KEYFD}" \
--key-size 512 \ --key-size 512 \
--label crypt_liveiso \ --label "${DM_LAB}" \
--luks2-keyslots-size 16777216 \ --luks2-keyslots-size 16777216 \
--luks2-metadata-size 4194304 \ --luks2-metadata-size 4194304 \
--pbkdf argon2id \ --pbkdf argon2id \
--pbkdf-memory "${LUKS_PBKDF_MEMORY_KIB}" \
--pbkdf-parallel "${LUKS_PBKDF_PARALLEL}" \
--sector-size 4096 \ --sector-size 4096 \
--type luks2 \ --type luks2 \
--use-random \ --use-random \
@@ -198,13 +263,16 @@ elif [[ "${VAR_CDLB_INSIDE_RUNNER}" == "true" ]]; then
cryptsetup luksFormat \ cryptsetup luksFormat \
--batch-mode \ --batch-mode \
--cipher aes-xts-plain64 \ --cipher aes-xts-plain64 \
--integrity hmac-sha512 \
--iter-time 1000 \ --iter-time 1000 \
--key-file "/proc/$$/fd/${KEYFD}" \ --key-file "/proc/$$/fd/${KEYFD}" \
--key-size 512 \ --key-size 512 \
--label crypt_liveiso \ --label "${DM_LAB}" \
--luks2-keyslots-size 16777216 \ --luks2-keyslots-size 16777216 \
--luks2-metadata-size 4194304 \ --luks2-metadata-size 4194304 \
--pbkdf argon2id \ --pbkdf argon2id \
--pbkdf-memory "${LUKS_PBKDF_MEMORY_KIB}" \
--pbkdf-parallel "${LUKS_PBKDF_PARALLEL}" \
--sector-size 4096 \ --sector-size 4096 \
--type luks2 \ --type luks2 \
--use-random \ --use-random \
@@ -213,10 +281,10 @@ elif [[ "${VAR_CDLB_INSIDE_RUNNER}" == "true" ]]; then
fi fi
cryptsetup open --key-file "/proc/$$/fd/${KEYFD}" "${LUKSFS}" crypt_liveiso cryptsetup open --key-file "/proc/$$/fd/${KEYFD}" "${LUKSFS}" "${DM_LAB}"
# shellcheck disable=SC2155 # shellcheck disable=SC2155
declare -i LUKS_FREE=$(blockdev --getsize64 "${MAPPER_DEV}") declare -i LUKS_FREE=$(blockdev --getsize64 "${DEVMAP}")
declare -i SQUASH_FS="${VAR_ROOTFS_SIZE}" declare -i SQUASH_FS="${VAR_ROOTFS_SIZE}"
if (( LUKS_FREE >= SQUASH_FS )); then if (( LUKS_FREE >= SQUASH_FS )); then
@@ -230,30 +298,18 @@ else
fi fi
dd if="${ROOTFS}" of="${MAPPER_DEV}" bs=8M status=progress conv=fsync dd if="${ROOTFS}" of="${DEVMAP}" bs=8M status=progress conv=fsync
sync sync
cryptsetup close "${DM_LAB}"
# The selected boot root is the complete decrypted mapper. Hashing this exact block payload binds the signed manifest to the
# bytes later mounted as SquashFS, including the mapper padding after the SquashFS image.
LC_ALL=C sha512sum "${MAPPER_DEV}" >| "${ROOTFS_ATTESTATION}"
gpg --batch --yes --pinentry-mode loopback --passphrase-file "${VAR_SIGNING_KEY_PASSFILE}" --local-user "${VAR_SIGNING_KEY_FPR}" \
--detach-sign --output "${ROOTFS_ATTESTATION_SIG}" "${ROOTFS_ATTESTATION}"
gpgv --keyring "${VAR_VERIFY_KEYRING}" "${ROOTFS_ATTESTATION_SIG}" "${ROOTFS_ATTESTATION}"
(cd / && LC_ALL=C sha512sum -c --strict --quiet "${ROOTFS_ATTESTATION}")
chmod 0444 "${ROOTFS_ATTESTATION}" "${ROOTFS_ATTESTATION_SIG}"
cryptsetup close crypt_liveiso
exec {KEYFD}<&- exec {KEYFD}<&-
shred -fzu -n 5 -- "${VAR_TMP_SECRET}/luks.txt" shred -fzu -n 5 -- "${LUKS_KEY_FILE}"
rm -f -- "${ROOTFS}" rm -f -- "${ROOTFS}"
require_rootfs_attestation_artifacts "${ROOTFS_ATTESTATION}"
umask "${__umask}" umask "${__umask}"
__umask="" __umask=""
@@ -39,7 +39,7 @@ install -d -m 0755 "${DESTDIR}/usr/sbin"
### Include binaries ----------------------------------------------------------------------------------------------------------- ### Include binaries -----------------------------------------------------------------------------------------------------------
for bin in bash blkid busybox dd dmsetup gpgv losetup lsblk mkpasswd mountpoint sha384sum sha512sum sort stty timeout tr tree udevadm whois; do for bin in awk bash blkid busybox dd dmsetup gawk gpgv losetup lsblk mkpasswd mountpoint sha384sum sha512sum sort stty timeout tr tree udevadm whois; do
path="$(command -v "${bin}" 2>/dev/null || true)" path="$(command -v "${bin}" 2>/dev/null || true)"
@@ -123,7 +123,6 @@ if [ -d "${src_dir}" ]; then
fi fi
### Install Dropbear configuration --------------------------------------------------------------------------------------------- ### Install Dropbear configuration ---------------------------------------------------------------------------------------------
install -m 0444 /etc/dropbear/initramfs/dropbear.conf "${DESTDIR}/etc/dropbear/dropbear.conf" install -m 0444 /etc/dropbear/initramfs/dropbear.conf "${DESTDIR}/etc/dropbear/dropbear.conf"
printf "\e[92mSuccessfully executed: [install -m 0444 /etc/dropbear/initramfs/dropbear.conf %s/etc/dropbear/dropbear.conf] \n\e[0m" "${DESTDIR}" printf "\e[92mSuccessfully executed: [install -m 0444 /etc/dropbear/initramfs/dropbear.conf %s/etc/dropbear/dropbear.conf] \n\e[0m" "${DESTDIR}"
@@ -146,6 +145,13 @@ printf "\e[92mSuccessfully executed: [install -m 0444 /etc/dropbear/initramfs/ba
install -m 0444 /etc/banner "${DESTDIR}/etc/dropbear/banner" install -m 0444 /etc/banner "${DESTDIR}/etc/dropbear/banner"
printf "\e[92mSuccessfully executed: [install -m 0444 /etc/dropbear/initramfs/banner %s/etc/dropbear/banner] \n\e[0m" "${DESTDIR}" printf "\e[92mSuccessfully executed: [install -m 0444 /etc/dropbear/initramfs/banner %s/etc/dropbear/banner] \n\e[0m" "${DESTDIR}"
### Ensure live-boot runtime scripts in the initramfs are executable -----------------------------------------------------------
if [ -d "${DESTDIR}/usr/lib/live/boot" ]; then
find "${DESTDIR}/usr/lib/live/boot" -type f -exec chmod +x -- {} +
printf "\e[92mSuccessfully executed: [find %s/usr/lib/live/boot -type f -exec chmod +x -- {} +] \n\e[0m" "${DESTDIR}"
fi
### EOS ### EOS
printf "\e[92mSuccessfully executed: [/etc/initramfs-tools/hooks/9999_ciss_debian_live_builder.sh] \n\e[0m" printf "\e[92mSuccessfully executed: [/etc/initramfs-tools/hooks/9999_ciss_debian_live_builder.sh] \n\e[0m"
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
[git.coresecret.dev]:42842 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGQA107AVmg1D/jnyXiqbPf38zQRl8s3c+PM1zbfpeQl [git.coresecret.dev]:42842 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGQA107AVmg1D/jnyXiqbPf38zQRl8s3c+PM1zbfpeQl
[git.coresecret.dev]:42842 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDYD9ysmMWZlejUnxu0qOzeWcIYezoFLbYdo6ffGUL5kqOBAYb+5CF4bJLUpA93XFYVF+TbrcMV1yJh6JaHFL0VU5CvgAzruCeedx0c4qUV6lWcJUGNk5K0yb9n2Wosdy6F/zTOxL9KXBt/TV+cscsen2Dahvx0ctMKgNbu+vvUcWxHf9lOkbYoF/uA/nW5CVXy5XUPVUDFUhEeKXL85+6gid5AEMfYT8aRl5YDGvo1iMBmBYOljN4S7MnRe14qbAZG0GDGvF22eHbSU2pILcFIjc2Lo/S5Ox/MJpbLAqpFlLPTKgr6F7yVwfNMSNwl05ysUOZfrQKSXzCU6+lfqKYCwemLALyG/n1ernpp7/8W/2RYoz3fd+TQyfhW++rx3yUHpYCkTv9A4LRYZYGSAWKMHSBEYq3EcATQUxQi0xpwmcR+u0uC9F9eta5Bim+sBZD6F2hgPJ5xgYT8LFm880g1YadAwBoD4TAkqSvl+jYW0VA2GH9CknKHJ36gc/X4eeUHDC1Hf/E8M5RBj4D6NuHfeVRik/ahHmoCqKQUW7VU/EBsWFsngDiLEHcV71iMtWiUddWOHwoAPHIzn6p9HTeLCxTwsPMG5UDGK/S9HUozqDXxexRtqbcFa7DWuzRvZ1bcZ2VQsaafuzKCkkc4NjC7h1wssel7q9aeYPFg+1vS6Q== [git.coresecret.dev]:42842 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDYD9ysmMWZlejUnxu0qOzeWcIYezoFLbYdo6ffGUL5kqOBAYb+5CF4bJLUpA93XFYVF+TbrcMV1yJh6JaHFL0VU5CvgAzruCeedx0c4qUV6lWcJUGNk5K0yb9n2Wosdy6F/zTOxL9KXBt/TV+cscsen2Dahvx0ctMKgNbu+vvUcWxHf9lOkbYoF/uA/nW5CVXy5XUPVUDFUhEeKXL85+6gid5AEMfYT8aRl5YDGvo1iMBmBYOljN4S7MnRe14qbAZG0GDGvF22eHbSU2pILcFIjc2Lo/S5Ox/MJpbLAqpFlLPTKgr6F7yVwfNMSNwl05ysUOZfrQKSXzCU6+lfqKYCwemLALyG/n1ernpp7/8W/2RYoz3fd+TQyfhW++rx3yUHpYCkTv9A4LRYZYGSAWKMHSBEYq3EcATQUxQi0xpwmcR+u0uC9F9eta5Bim+sBZD6F2hgPJ5xgYT8LFm880g1YadAwBoD4TAkqSvl+jYW0VA2GH9CknKHJ36gc/X4eeUHDC1Hf/E8M5RBj4D6NuHfeVRik/ahHmoCqKQUW7VU/EBsWFsngDiLEHcV71iMtWiUddWOHwoAPHIzn6p9HTeLCxTwsPMG5UDGK/S9HUozqDXxexRtqbcFa7DWuzRvZ1bcZ2VQsaafuzKCkkc4NjC7h1wssel7q9aeYPFg+1vS6Q==
+1 -1
View File
@@ -9,7 +9,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
### https://www.ssh-audit.com/ ### https://www.ssh-audit.com/
### ssh -Q cipher | cipher-auth | compression | kex | kex-gss | key | key-cert | key-plain | key-sig | mac | protocol-version | sig ### ssh -Q cipher | cipher-auth | compression | kex | kex-gss | key | key-cert | key-plain | key-sig | mac | protocol-version | sig
@@ -11,7 +11,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Version Master V9.14.022.2026.06.10 # Version Master V9.14.028.2026.06.18
### https://docs.kernel.org/ ### https://docs.kernel.org/
### https://github.com/a13xp0p0v/kernel-hardening-checker/ ### https://github.com/a13xp0p0v/kernel-hardening-checker/
@@ -10,7 +10,7 @@
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
declare -gr VERSION="Master V9.14.022.2026.06.10" declare -gr VERSION="Master V9.14.028.2026.06.18"
### VERY EARLY CHECK FOR DEBUGGING ### VERY EARLY CHECK FOR DEBUGGING
if [[ $* == *" --debug "* ]]; then if [[ $* == *" --debug "* ]]; then
+1 -1
View File
@@ -112,4 +112,4 @@ d-i preseed/late_command string sh /preseed/.ash/3_di_preseed_late_command.sh
# Please consider donating to my work at: https://coresecret.eu/spenden/ # Please consider donating to my work at: https://coresecret.eu/spenden/
########################################################################################### ###########################################################################################
# Written by: ./preseed_hash_generator.sh Version: Master V9.14.022.2026.06.10 at: 10:18:37.9542 # Written by: ./preseed_hash_generator.sh Version: Master V9.14.028.2026.06.18 at: 10:18:37.9542
@@ -295,6 +295,10 @@ export CDLB_MAPPER_NAME="crypt_liveiso"
export CDLB_MAPPER_DEV="/dev/mapper/${CDLB_MAPPER_NAME}" export CDLB_MAPPER_DEV="/dev/mapper/${CDLB_MAPPER_NAME}"
export CDLB_MNT_MEDIUM="/run/live/medium" export CDLB_MNT_MEDIUM="/run/live/medium"
export CDLB_MNT_ROOTFS="/run/live/rootfs" export CDLB_MNT_ROOTFS="/run/live/rootfs"
export CDLB_ROOTFS_ATTEST_NAME="filesystem.squashfs.sha512sum.txt"
export CDLB_ROOTFS_ATTEST_CACHE_DIR="/run/ciss-rootfs-attestation"
export CDLB_ROOTFS_ATTEST_MANIFEST="${CDLB_ROOTFS_ATTEST_CACHE_DIR}/${CDLB_ROOTFS_ATTEST_NAME}"
export CDLB_ROOTFS_ATTEST_SIGNATURE="${CDLB_ROOTFS_ATTEST_MANIFEST}.sig"
export CDLB_REMOTE_WAIT_SECS="${CDLB_REMOTE_WAIT_SECS:-3600}" export CDLB_REMOTE_WAIT_SECS="${CDLB_REMOTE_WAIT_SECS:-3600}"
_PARAMETER="" _PARAMETER=""
_dev="" _dev=""
@@ -377,6 +381,66 @@ fi
printf "\e[92m[INFO] CISS LUKS FS : [%s%s] \n\e[0m" "${CDLB_MNT_MEDIUM}" "${CDLB_LUKS_FS}" printf "\e[92m[INFO] CISS LUKS FS : [%s%s] \n\e[0m" "${CDLB_MNT_MEDIUM}" "${CDLB_LUKS_FS}"
### Preserve rootfs attestation evidence before live-boot may replace or unmount the medium view. -----------------------------
CDLB_ROOTFS_ATTEST_SOURCE="${CDLB_MNT_MEDIUM}/live/${CDLB_ROOTFS_ATTEST_NAME}"
CDLB_ROOTFS_ATTEST_SOURCE_SIG="${CDLB_ROOTFS_ATTEST_SOURCE}.sig"
if [ ! -f "${CDLB_ROOTFS_ATTEST_SOURCE}" ] || [ ! -f "${CDLB_ROOTFS_ATTEST_SOURCE_SIG}" ]; then
printf "\e[91m[FATAL] Boot failure : Rootfs attestation artifacts not found on live medium: [%s] [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_SOURCE}" "${CDLB_ROOTFS_ATTEST_SOURCE_SIG}"
sleep 8
log "[FATAL] Boot failure : Rootfs attestation artifacts not found on live medium: [${CDLB_ROOTFS_ATTEST_SOURCE}] [${CDLB_ROOTFS_ATTEST_SOURCE_SIG}]"
panic "[FATAL] Boot failure : Rootfs attestation artifacts not found on live medium: [${CDLB_ROOTFS_ATTEST_SOURCE}] [${CDLB_ROOTFS_ATTEST_SOURCE_SIG}]"
fi
if ! mkdir -p "${CDLB_ROOTFS_ATTEST_CACHE_DIR}"; then
printf "\e[91m[FATAL] Boot failure : Failed to create rootfs attestation cache directory: [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_CACHE_DIR}"
sleep 8
log "[FATAL] Boot failure : Failed to create rootfs attestation cache directory: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
panic "[FATAL] Boot failure : Failed to create rootfs attestation cache directory: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
fi
if ! chmod 0755 "${CDLB_ROOTFS_ATTEST_CACHE_DIR}"; then
printf "\e[91m[FATAL] Boot failure : Failed to permission rootfs attestation cache directory: [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_CACHE_DIR}"
sleep 8
log "[FATAL] Boot failure : Failed to permission rootfs attestation cache directory: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
panic "[FATAL] Boot failure : Failed to permission rootfs attestation cache directory: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
fi
if ! cp "${CDLB_ROOTFS_ATTEST_SOURCE}" "${CDLB_ROOTFS_ATTEST_MANIFEST}" || \
! cp "${CDLB_ROOTFS_ATTEST_SOURCE_SIG}" "${CDLB_ROOTFS_ATTEST_SIGNATURE}"; then
printf "\e[91m[FATAL] Boot failure : Failed to preserve rootfs attestation artifacts in: [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_CACHE_DIR}"
sleep 8
log "[FATAL] Boot failure : Failed to preserve rootfs attestation artifacts in: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
panic "[FATAL] Boot failure : Failed to preserve rootfs attestation artifacts in: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
fi
if ! chmod 0444 "${CDLB_ROOTFS_ATTEST_MANIFEST}" "${CDLB_ROOTFS_ATTEST_SIGNATURE}"; then
printf "\e[91m[FATAL] Boot failure : Failed to make rootfs attestation cache read-only: [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_CACHE_DIR}"
sleep 8
log "[FATAL] Boot failure : Failed to make rootfs attestation cache read-only: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
panic "[FATAL] Boot failure : Failed to make rootfs attestation cache read-only: [${CDLB_ROOTFS_ATTEST_CACHE_DIR}]"
fi
chmod 0555 "${CDLB_ROOTFS_ATTEST_CACHE_DIR}" 2>&- || true
printf "\e[92m[INFO] Rootfs attestation : Preserved [%s] and [%s] \n\e[0m" \
"${CDLB_ROOTFS_ATTEST_MANIFEST}" "${CDLB_ROOTFS_ATTEST_SIGNATURE}"
### Attach a loop device read-only to the encrypted file. ---------------------------------------------------------------------- ### Attach a loop device read-only to the encrypted file. ----------------------------------------------------------------------
if ! LOOP="$(losetup -f --show -r "${CDLB_MNT_MEDIUM}${CDLB_LUKS_FS}")"; then if ! LOOP="$(losetup -f --show -r "${CDLB_MNT_MEDIUM}${CDLB_LUKS_FS}")"; then
@@ -587,6 +651,10 @@ export CDLB_MAPPER_NAME=${CDLB_MAPPER_NAME}
export CDLB_MAPPER_DEV=${CDLB_MAPPER_DEV} export CDLB_MAPPER_DEV=${CDLB_MAPPER_DEV}
export CDLB_MNT_MEDIUM=${CDLB_MNT_MEDIUM} export CDLB_MNT_MEDIUM=${CDLB_MNT_MEDIUM}
export CDLB_MNT_ROOTFS=${CDLB_MNT_ROOTFS} export CDLB_MNT_ROOTFS=${CDLB_MNT_ROOTFS}
export CDLB_ROOTFS_ATTEST_NAME=${CDLB_ROOTFS_ATTEST_NAME}
export CDLB_ROOTFS_ATTEST_CACHE_DIR=${CDLB_ROOTFS_ATTEST_CACHE_DIR}
export CDLB_ROOTFS_ATTEST_MANIFEST=${CDLB_ROOTFS_ATTEST_MANIFEST}
export CDLB_ROOTFS_ATTEST_SIGNATURE=${CDLB_ROOTFS_ATTEST_SIGNATURE}
export CDLB_REMOTE_WAIT_SECS=${CDLB_REMOTE_WAIT_SECS} export CDLB_REMOTE_WAIT_SECS=${CDLB_REMOTE_WAIT_SECS}
EOF EOF
chmod 0444 /run/ciss-rootdev 2>&- || true chmod 0444 /run/ciss-rootdev 2>&- || true
@@ -15,12 +15,14 @@
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Module summary: # Module summary:
# This live-boot component implements the verify-checksums mode for the mounted live medium. # This live-boot component implements verify-checksums mode for the mounted live medium.
# It reads the live-boot command line to decide whether checksum verification is enabled and which digests to accept. # It reads the live-boot command line to decide whether checksum verification is enabled, which digests to accept, and
# It locates the pinned CISS GPG key material on the live medium, optionally verifies this script's signed hash, # whether checksum signature verification is required. When signature verification is enabled, it requires to be pinned CISS GPG
# optionally verifies signed checksum files, and checks the first matching checksum manifest with the matching digest tool. It # key material from the live medium, verifies this script's signed SHA-512 hash, and verifies the selected checksum manifest
# writes detailed checksum output to the verification TTY. It panics instead of continuing boot when integrity or # signature before accepting checksum results. It checks the first supported checksum manifest with an available matching digest
# authenticity verification fails. # tool and writes detailed checksum command output to the verification TTY when checksum execution runs. It fails closed by
# panicking on missing manifests, missing digest tools, empty manifests, failed signatures, failed checksums, or unknown
# verification states.
### Modified Version of the original file: ### Modified Version of the original file:
### https://salsa.debian.org/live-team/live-boot 'components/0030-ciss-verify-checksums' ### https://salsa.debian.org/live-team/live-boot 'components/0030-ciss-verify-checksums'
@@ -87,6 +89,8 @@ Verify_checksums() {
_CHECKSUM_LOG="" _CHECKSUM_LOG=""
_CHECKSUM_LOG_DIR="${LIVE_VERIFY_CHECKSUMS_LOG_DIR:-/run}"
_KEYFILE="" _KEYFILE=""
_MANIFEST_FOUND="false" _MANIFEST_FOUND="false"
@@ -97,6 +101,8 @@ Verify_checksums() {
_RETURN_SHA="" _RETURN_SHA=""
_TOOL_FOUND="false"
_VERIFICATION_EXECUTED="false" _VERIFICATION_EXECUTED="false"
_VERIFICATION_SUCCEEDED="false" _VERIFICATION_SUCCEEDED="false"
@@ -159,6 +165,14 @@ Verify_checksums() {
done done
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ] && [ -z "${_KEYFILE}" ]; then
log_er "No pinned GPG key file found while checksum signature verification is enabled."
sleep 8
panic "[FATAL] No pinned GPG key file found while checksum signature verification is enabled."
fi
# shellcheck disable=SC2164 # shellcheck disable=SC2164
cd "${_MOUNTPOINT}" cd "${_MOUNTPOINT}"
@@ -256,11 +270,13 @@ Verify_checksums() {
if [ -e "${_CHECKSUM}" ]; then if [ -e "${_CHECKSUM}" ]; then
_MANIFEST_FOUND="true" _MANIFEST_FOUND="true"
log_in "Found: [${_CHECKSUM}] ..." log_in "Found: [${_CHECKSUM}] ..."
if [ -e "/usr/bin/${_DIGEST}sum" ]; then if [ -e "/usr/bin/${_DIGEST}sum" ]; then
_VERIFICATION_EXECUTED="true" _TOOL_FOUND="true"
log_in "Found: [/usr/bin/${_DIGEST}sum] ..." log_in "Found: [/usr/bin/${_DIGEST}sum] ..."
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
@@ -288,11 +304,17 @@ Verify_checksums() {
fi fi
# shellcheck disable=SC2312 # shellcheck disable=SC2312
_CHECKSUM_LOG="/run/ciss-${_DIGEST}sum-check.log" _CHECKSUM_LOG="${_CHECKSUM_LOG_DIR}/ciss-${_DIGEST}sum-check.log"
if grep -v '^#' "${_CHECKSUM}" | LC_ALL=C /usr/bin/"${_DIGEST}"sum -c > "${_CHECKSUM_LOG}" 2>&1; then _VERIFICATION_EXECUTED="true"
if ! grep -v '^#' "${_CHECKSUM}" | grep -q '[^[:space:]]'; then
_RETURN_SHA="254"
: > "${_CHECKSUM_LOG}"
log_er "Checksum manifest has no checksum entries: [${_CHECKSUM}]"
elif grep -v '^#' "${_CHECKSUM}" | LC_ALL=C /usr/bin/"${_DIGEST}"sum -c > "${_CHECKSUM_LOG}" 2>&1; then
_RETURN_SHA="${?}" _RETURN_SHA="${?}"
_VERIFICATION_SUCCEEDED="true"
cat "${_CHECKSUM_LOG}" > "${_TTY}" cat "${_CHECKSUM_LOG}" > "${_TTY}"
log_ok "Found: [/usr/bin/${_DIGEST}sum] successful verified: [${_CHECKSUM}]" log_ok "Found: [/usr/bin/${_DIGEST}sum] successful verified: [${_CHECKSUM}]"
@@ -308,6 +330,12 @@ Verify_checksums() {
fi fi
if { [ "${_RETURN_PGP}" = "0" ] || [ "${_RETURN_PGP}" = "na" ]; } && [ "${_RETURN_SHA}" = "0" ]; then
_VERIFICATION_SUCCEEDED="true"
fi
# Stop after the first verification. # Stop after the first verification.
break 2 break 2
@@ -329,28 +357,31 @@ Verify_checksums() {
if [ "${_MANIFEST_FOUND}" != "true" ]; then if [ "${_MANIFEST_FOUND}" != "true" ]; then
log_er "No supported checksum manifest found." log_er "No supported checksum manifest found. Checksum verification is fail-closed."
sleep 8 sleep 8
panic "No supported checksum manifest found." panic "[FATAL] No supported checksum manifest found. Checksum verification is fail-closed."
return 1
fi
if [ "${_TOOL_FOUND}" != "true" ]; then
log_er "Checksum manifest found, but no supported checksum tool is available. Checksum verification is fail-closed."
sleep 8
panic "[FATAL] Checksum manifest found, but no supported checksum tool is available. Checksum verification is fail-closed."
fi fi
if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then
log_er "No supported checksum verification tool was available." log_er "Checksum verification was not executed. Checksum verification is fail-closed."
sleep 8 sleep 8
panic "No supported checksum verification tool was available." panic "[FATAL] Checksum verification was not executed. Checksum verification is fail-closed."
return 1
fi fi
if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then
log_er "No supported checksum manifest was verified successfully." log_er "[FATAL] Checksum verification did not complete successfully. Evaluating fail-closed failure state."
sleep 8
panic "No supported checksum manifest was verified successfully."
return 1
fi fi
@@ -372,28 +403,24 @@ Verify_checksums() {
log_er "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed." log_er "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
sleep 8 sleep 8
panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed." panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
return 1
;; ;;
*",0") *",0")
log_er "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful." log_er "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
sleep 8 sleep 8
panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful." panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
return 1
;; ;;
"na,"*) "na,"*)
log_er "Verification of [sha checksum] file failed." log_er "Verification of [sha checksum] file failed."
sleep 8 sleep 8
panic "Verification of [sha checksum] file failed." panic "Verification of [sha checksum] file failed."
return 1
;; ;;
*) *)
log_er "Checksum verification ended in an unsupported state." log_er "Unknown checksum verification state: [${_RETURN_PGP:-unset},${_RETURN_SHA:-unset}]."
sleep 8 sleep 8
panic "Checksum verification ended in an unsupported state." panic "[FATAL] Unknown checksum verification state. Checksum verification is fail-closed."
return 1
;; ;;
esac esac
@@ -15,11 +15,13 @@
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# Module summary: # Module summary:
# - Runs after the encrypted live root filesystem has been decrypted and selected for the SquashFS root mount. # - Runs after the encrypted live root filesystem has been decrypted.
# - Requires the pinned public key and the signed decrypted-mapper SHA-512 manifest from the mounted live medium. # - Requires the pinned public key, external rootfs attestation manifest, and detached signature to exist as readable,
# - Verifies the manifest signature and pinned signer fingerprint, then verifies the complete selected decrypted mapper against # non-empty regular files.
# the manifest. # - Verifies the attestation signature with gpgv against the pinned key material and expected signer fingerprint.
# - Panics on missing, malformed, mismatched, or unverifiable evidence. # - Verifies the exact final SquashFS byte stream copied into the decrypted LUKS mapper. The signed manifest provides both the
# SHA-512 digest and the exact byte length; allocation slack after that SquashFS payload is intentionally out of scope.
# - Panics on missing, malformed, unauthentic, or mismatched evidence.
set -eu set -eu
@@ -33,13 +35,15 @@ export CDLB_EXP_CA_FPR="@EXP_CA_FPR@"
### Name of the top-level dm-crypt mapping (e.g., cryptsetup --label): zzzz_ciss_crypt_squash.hook.binary ---------------------- ### Name of the top-level dm-crypt mapping (e.g., cryptsetup --label): zzzz_ciss_crypt_squash.hook.binary ----------------------
export CDLB_MAPPER_NAME="${CDLB_MAPPER_NAME:-crypt_liveiso}" export CDLB_MAPPER_NAME="${CDLB_MAPPER_NAME:-crypt_liveiso}"
export CDLB_MAPPER_DEV="${CDLB_MAPPER_DEV:-/dev/mapper/${CDLB_MAPPER_NAME}}"
export CDLB_MNT_MEDIUM="${CDLB_MNT_MEDIUM:-/run/live/medium}"
### Rootfs selection and attestation file locations. --------------------------------------------------------------------------- ### Locations of the attestation file of filesystem.squashfs on the verified live medium. --------------------------------------
CDLB_LUKS_FS="${CDLB_LUKS_FS:-/live/ciss_rootfs.crypt}" CDLB_ROOTFS_ATTEST_NAME="${CDLB_ROOTFS_ATTEST_NAME:-filesystem.squashfs.sha512sum.txt}"
CDLB_MAPPER_DEV="${CDLB_MAPPER_DEV:-/dev/mapper/${CDLB_MAPPER_NAME}}" CDLB_ROOTFS_ATTEST_MANIFEST="${CDLB_ROOTFS_ATTEST_MANIFEST:-${CDLB_MNT_MEDIUM}/live/${CDLB_ROOTFS_ATTEST_NAME}}"
CDLB_MNT_MEDIUM="${CDLB_MNT_MEDIUM:-/run/live/medium}" CDLB_ROOTFS_ATTEST_SIGNATURE="${CDLB_ROOTFS_ATTEST_SIGNATURE:-${CDLB_ROOTFS_ATTEST_MANIFEST}.sig}"
CDLB_ATTEST_ROOTFS_SHA="${CDLB_ATTEST_ROOTFS_SHA:-${CDLB_MNT_MEDIUM}${CDLB_LUKS_FS}.decrypted.sha512sum.txt}" CDLB_ROOTFS_ATTEST_CACHE_DIR="${CDLB_ROOTFS_ATTEST_CACHE_DIR:-/run/ciss-rootfs-attestation}"
CDLB_ATTEST_ROOTFS_SIG="${CDLB_ATTEST_ROOTFS_SIG:-${CDLB_ATTEST_ROOTFS_SHA}.sig}" CDLB_ROOTFS_ATTEST_CHECK="${CDLB_ROOTFS_ATTEST_CHECK:-/run/ciss-rootfs-attestation.sha512sum}"
CDLB_KEY_DIR="${CDLB_KEY_DIR:-/etc/ciss/keys}" CDLB_KEY_DIR="${CDLB_KEY_DIR:-/etc/ciss/keys}"
### Declare functions ---------------------------------------------------------------------------------------------------------- ### Declare functions ----------------------------------------------------------------------------------------------------------
@@ -71,6 +75,17 @@ log_ok() { printf '\e[92m[INFO] %s \n\e[0m' "$*"; }
####################################### #######################################
log_er() { printf '\e[91m[FATAL] %s \n\e[0m' "$*"; } log_er() { printf '\e[91m[FATAL] %s \n\e[0m' "$*"; }
### Provide a local fail-closed fallback when this file is executed as a subprocess outside the live-boot shell context. --------
if ! command -v panic >/dev/null 2>&1; then
panic() {
log_er "${*}"
printf '%s\n' "0042 FATAL: ${*}" >/dev/console 2>/dev/null || :
exit 1
}
fi
####################################### #######################################
# Validate a boot-time attestation input file. # Validate a boot-time attestation input file.
# Globals: # Globals:
@@ -91,13 +106,11 @@ require_attestation_file() {
log_er "0042() : ${artifact_label} is a broken symlink, not a regular file: [${artifact_path}]" log_er "0042() : ${artifact_label} is a broken symlink, not a regular file: [${artifact_path}]"
panic "0042() : ${artifact_label} is a broken symlink, not a regular file: [${artifact_path}]" panic "0042() : ${artifact_label} is a broken symlink, not a regular file: [${artifact_path}]"
return 1
fi fi
log_er "0042() : ${artifact_label} missing: [${artifact_path}]" log_er "0042() : ${artifact_label} missing: [${artifact_path}]"
panic "0042() : ${artifact_label} missing: [${artifact_path}]" panic "0042() : ${artifact_label} missing: [${artifact_path}]"
return 1
fi fi
@@ -105,7 +118,6 @@ require_attestation_file() {
log_er "0042() : ${artifact_label} is not a regular file: [${artifact_path}]" log_er "0042() : ${artifact_label} is not a regular file: [${artifact_path}]"
panic "0042() : ${artifact_label} is not a regular file: [${artifact_path}]" panic "0042() : ${artifact_label} is not a regular file: [${artifact_path}]"
return 1
fi fi
@@ -113,7 +125,6 @@ require_attestation_file() {
log_er "0042() : ${artifact_label} is empty: [${artifact_path}]" log_er "0042() : ${artifact_label} is empty: [${artifact_path}]"
panic "0042() : ${artifact_label} is empty: [${artifact_path}]" panic "0042() : ${artifact_label} is empty: [${artifact_path}]"
return 1
fi fi
@@ -121,7 +132,6 @@ require_attestation_file() {
log_er "0042() : ${artifact_label} is not readable: [${artifact_path}]" log_er "0042() : ${artifact_label} is not readable: [${artifact_path}]"
panic "0042() : ${artifact_label} is not readable: [${artifact_path}]" panic "0042() : ${artifact_label} is not readable: [${artifact_path}]"
return 1
fi fi
@@ -129,48 +139,231 @@ require_attestation_file() {
} }
####################################### #######################################
# Validate the selected decrypted rootfs payload. # Resolve rootfs attestation paths on known live medium mountpoints.
# Globals: # Globals:
# None # CDLB_MNT_MEDIUM
# CDLB_ROOTFS_ATTEST_MANIFEST
# CDLB_ROOTFS_ATTEST_NAME
# CDLB_ROOTFS_ATTEST_SIGNATURE
# Arguments: # Arguments:
# 1: Absolute payload path # None
# Returns: # Returns:
# 0: on success # 0: on success
####################################### #######################################
require_rootfs_payload() { resolve_rootfs_attestation_artifacts() {
payload_path="${1}" medium_path=""
manifest_path=""
signature_path=""
if [ ! -b "${payload_path}" ]; then if [ -f "${CDLB_ROOTFS_ATTEST_MANIFEST}" ] && [ -f "${CDLB_ROOTFS_ATTEST_SIGNATURE}" ]; then
log_er "0042() : Selected rootfs payload is not a block device: [${payload_path}]" return 0
panic "0042() : Selected rootfs payload is not a block device: [${payload_path}]"
return 1
fi fi
if [ ! -r "${payload_path}" ]; then manifest_path="${CDLB_ROOTFS_ATTEST_CACHE_DIR}/${CDLB_ROOTFS_ATTEST_NAME}"
signature_path="${manifest_path}.sig"
log_er "0042() : Selected rootfs payload is not readable: [${payload_path}]" if [ -f "${manifest_path}" ] && [ -f "${signature_path}" ]; then
panic "0042() : Selected rootfs payload is not readable: [${payload_path}]"
return 1 CDLB_ROOTFS_ATTEST_MANIFEST="${manifest_path}"
CDLB_ROOTFS_ATTEST_SIGNATURE="${signature_path}"
return 0
fi
for medium_path in "${CDLB_MNT_MEDIUM}" /run/live/medium /lib/live/mount/medium /cdrom; do
[ -n "${medium_path}" ] || continue
manifest_path="${medium_path}/live/${CDLB_ROOTFS_ATTEST_NAME}"
signature_path="${manifest_path}.sig"
if [ -f "${manifest_path}" ] && [ -f "${signature_path}" ]; then
CDLB_ROOTFS_ATTEST_MANIFEST="${manifest_path}"
CDLB_ROOTFS_ATTEST_SIGNATURE="${signature_path}"
return 0
fi
done
log_er "0042() : Rootfs attestation artifacts not found. Expected manifest/signature: [${CDLB_ROOTFS_ATTEST_MANIFEST}] [${CDLB_ROOTFS_ATTEST_SIGNATURE}]"
panic "0042() : Rootfs attestation artifacts not found. Expected manifest/signature: [${CDLB_ROOTFS_ATTEST_MANIFEST}] [${CDLB_ROOTFS_ATTEST_SIGNATURE}]"
return 1
}
#######################################
# Validate the decrypted rootfs payload device.
# Globals:
# None
# Arguments:
# 1: Absolute payload device path
# Returns:
# 0: on success
#######################################
require_rootfs_payload_device() {
artifact_path="${1}"
if [ ! -e "${artifact_path}" ]; then
log_er "0042() : Rootfs payload device missing: [${artifact_path}]"
panic "0042() : Rootfs payload device missing: [${artifact_path}]"
fi
if [ -b "${artifact_path}" ]; then
:
elif [ -L "${artifact_path}" ] || [ ! -f "${artifact_path}" ]; then
log_er "0042() : Rootfs payload must be a block device or regular test fixture: [${artifact_path}]"
panic "0042() : Rootfs payload must be a block device or regular test fixture: [${artifact_path}]"
fi
if [ ! -r "${artifact_path}" ]; then
log_er "0042() : Rootfs payload is not readable: [${artifact_path}]"
panic "0042() : Rootfs payload is not readable: [${artifact_path}]"
fi fi
return 0 return 0
} }
HASH_FILE="${CDLB_ATTEST_ROOTFS_SHA}" #######################################
SIGN_FILE="${CDLB_ATTEST_ROOTFS_SIG}" # Stream exactly the attested SquashFS payload bytes from the decrypted mapper.
# Globals:
# None
# Arguments:
# 1: Payload device or regular test fixture
# 2: Exact payload byte count
# Returns:
# 0: on success
#######################################
stream_rootfs_payload() {
payload_device="${1}"
payload_size="${2}"
block_size=1048576
full_blocks=$((payload_size / block_size))
remainder=$((payload_size % block_size))
if [ "${full_blocks}" -gt 0 ]; then
dd if="${payload_device}" bs="${block_size}" count="${full_blocks}" 2>/dev/null || return 1
fi
if [ "${remainder}" -gt 0 ]; then
dd if="${payload_device}" bs="${block_size}" skip="${full_blocks}" count=1 2>/dev/null | dd bs=1 count="${remainder}" 2>/dev/null || return 1
fi
return 0
}
#######################################
# Verify the attested SquashFS payload hash against the decrypted mapper bytes.
# Globals:
# CDLB_ROOTFS_ATTEST_CHECK
# Arguments:
# 1: Manifest path
# 2: Payload device path
# Returns:
# 0: on success
#######################################
verify_rootfs_payload() {
manifest_path="${1}"
payload_device="${2}"
payload_size=""
payload_hash=""
payload_size="$(awk '/^# Bytes[[:space:]]*:[[:space:]]Final filesystem[.]squashfs[[:space:]]+[0-9]+[[:space:]]*$/ {print $NF; exit}' "${manifest_path}")"
payload_hash="$(awk '($0 !~ /^#/ && NF >= 2){print $1; exit}' "${manifest_path}")"
case "${payload_size}" in
""|*[!0-9]*)
log_er "0042() : Rootfs attestation manifest has invalid payload size."
panic "0042() : Rootfs attestation manifest has invalid payload size."
;;
esac
if [ "${payload_size}" -le 0 ]; then
log_er "0042() : Rootfs attestation manifest has empty payload size."
panic "0042() : Rootfs attestation manifest has empty payload size."
fi
case "${payload_hash}" in
""|*[!0123456789abcdefABCDEF]*)
log_er "0042() : Rootfs attestation manifest has invalid SHA-512 payload hash."
panic "0042() : Rootfs attestation manifest has invalid SHA-512 payload hash."
;;
esac
if [ "${#payload_hash}" -ne 128 ]; then
log_er "0042() : Rootfs attestation manifest SHA-512 payload hash has invalid length."
panic "0042() : Rootfs attestation manifest SHA-512 payload hash has invalid length."
fi
if ! printf '%s -\n' "${payload_hash}" > "${CDLB_ROOTFS_ATTEST_CHECK}"; then
log_er "0042() : Failed to prepare transient rootfs payload checksum file."
panic "0042() : Failed to prepare transient rootfs payload checksum file."
fi
chmod 0600 "${CDLB_ROOTFS_ATTEST_CHECK}" 2>/dev/null || :
log_in "0042() : Verifying exact SquashFS payload bytes from: [${payload_device}]"
# stream_rootfs_payload may be evaluated in a pipeline here; sha512sum -c is the fail-closed authority for truncated or
# tampered payload bytes.
# shellcheck disable=SC2310
if ! stream_rootfs_payload "${payload_device}" "${payload_size}" | /usr/bin/sha512sum -c "${CDLB_ROOTFS_ATTEST_CHECK}"; then
log_er "0042() : Rootfs payload SHA-512 verification failed."
panic "0042() : Rootfs payload SHA-512 verification failed."
fi
log_ok "0042() : Rootfs payload SHA-512 verification successful."
return 0
}
resolve_rootfs_attestation_artifacts
HASH_FILE="${CDLB_ROOTFS_ATTEST_MANIFEST}"
SIGN_FILE="${CDLB_ROOTFS_ATTEST_SIGNATURE}"
KEYFILE="${CDLB_KEY_DIR}/${CDLB_EXP_FPR}.gpg" KEYFILE="${CDLB_KEY_DIR}/${CDLB_EXP_FPR}.gpg"
require_attestation_file "Public key" "${KEYFILE}" log_in "0042() : Validating [${KEYFILE}]"
require_attestation_file "Public key" "${KEYFILE}"
log_in "0042() : Validating [${HASH_FILE}]"
require_attestation_file "Rootfs attestation manifest" "${HASH_FILE}" require_attestation_file "Rootfs attestation manifest" "${HASH_FILE}"
log_in "0042() : Validating [${SIGN_FILE}]"
require_attestation_file "Rootfs attestation signature" "${SIGN_FILE}" require_attestation_file "Rootfs attestation signature" "${SIGN_FILE}"
require_rootfs_payload "${CDLB_MAPPER_DEV}" log_in "0042() : Validating [${CDLB_MAPPER_DEV}]"
require_rootfs_payload_device "${CDLB_MAPPER_DEV}"
log_in "0042() : Verifying signed rootfs attestation manifest with pinned GPG FPR." log_ok "0042() : Rootfs attestation inputs are present and readable."
if ! _STATUS="$(/usr/bin/gpgv --no-default-keyring --keyring "${KEYFILE}" --status-fd 1 "${SIGN_FILE}" "${HASH_FILE}" 2>&1)"; then log_in "0042() : Verifying rootfs attestation manifest with 'gpgv' and pinned GPG FPR."
if ! _STATUS="$(/usr/bin/gpgv --keyring "${KEYFILE}" --status-fd 1 "${SIGN_FILE}" "${HASH_FILE}" 2>&1)"; then
log_er "0042() : gpgv verification failed for signature: [${SIGN_FILE}]" log_er "0042() : gpgv verification failed for signature: [${SIGN_FILE}]"
@@ -182,7 +375,6 @@ if ! _STATUS="$(/usr/bin/gpgv --no-default-keyring --keyring "${KEYFILE}" --stat
sleep 8 sleep 8
panic "0042() : gpgv verification failed for signature: [${SIGN_FILE}]" panic "0042() : gpgv verification failed for signature: [${SIGN_FILE}]"
exit 1
fi fi
@@ -198,51 +390,10 @@ else
log_er "0042() : Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]" log_er "0042() : Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]"
sleep 8 sleep 8
panic "[FATAL] Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]." panic "[FATAL] Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]."
exit 1
fi fi
_ATTEST_RECORD_COUNT="$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' "${HASH_FILE}")" verify_rootfs_payload "${HASH_FILE}" "${CDLB_MAPPER_DEV}"
if [ "${_ATTEST_RECORD_COUNT}" -ne 1 ]; then
log_er "0042() : Rootfs attestation manifest must contain exactly one checksum record: [${HASH_FILE}]"
sleep 8
panic "0042() : Rootfs attestation manifest must contain exactly one checksum record: [${HASH_FILE}]"
exit 1
fi
_ATTESTED_PAYLOAD="$(awk 'NF && $1 !~ /^#/ { print $2; exit }' "${HASH_FILE}")"
if [ "${_ATTESTED_PAYLOAD}" != "${CDLB_MAPPER_DEV}" ]; then
log_er "0042() : Rootfs attestation manifest targets [${_ATTESTED_PAYLOAD}], expected selected payload [${CDLB_MAPPER_DEV}]"
sleep 8
panic "0042() : Rootfs attestation manifest does not target the selected rootfs payload."
exit 1
fi
log_in "0042() : Verifying selected decrypted rootfs mapper content: [${CDLB_MAPPER_DEV}]"
if ! _CHECKSUM_STATUS="$(cd / && LC_ALL=C /usr/bin/sha512sum -c --strict --quiet "${HASH_FILE}" 2>&1)"; then
log_er "0042() : Rootfs payload checksum verification failed: [${CDLB_MAPPER_DEV}]"
if [ -n "${_CHECKSUM_STATUS}" ]; then
printf '%s\n' "${_CHECKSUM_STATUS}" >&2
fi
sleep 8
panic "0042() : Rootfs payload checksum verification failed: [${CDLB_MAPPER_DEV}]"
exit 1
fi
log_ok "0042() : Rootfs payload checksum verification successful: [${CDLB_MAPPER_DEV}]"
printf "\e[92m[INFO] Successfully applied : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] \n\e[0m" printf "\e[92m[INFO] Successfully applied : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] \n\e[0m"
@@ -497,7 +497,23 @@ setup_unionfs ()
### CISS override for /usr/lib/live/boot/0042_ciss_post_decrypt_attest ------------------------------------------------------- ### CISS override for /usr/lib/live/boot/0042_ciss_post_decrypt_attest -------------------------------------------------------
printf "\e[95m[INFO] Calling : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] ... \n\e[0m" printf "\e[95m[INFO] Calling : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] ... \n\e[0m"
[ -x /usr/lib/live/boot/0042_ciss_post_decrypt_attest ] && /usr/lib/live/boot/0042_ciss_post_decrypt_attest
chmod +x /usr/lib/live/boot/0042_ciss_post_decrypt_attest
if [ -x /usr/lib/live/boot/0042_ciss_post_decrypt_attest ]; then
if ! /usr/lib/live/boot/0042_ciss_post_decrypt_attest; then
panic "[FATAL] [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] failed."
fi
else
panic "[FATAL] [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] missing or not executable."
fi
printf "\e[92m[INFO] Calling : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] done. \n\e[0m" printf "\e[92m[INFO] Calling : [/usr/lib/live/boot/0042_ciss_post_decrypt_attest] done. \n\e[0m"
### CISS override for /usr/lib/live/boot/0042_ciss_post_decrypt_attest ------------------------------------------------------- ### CISS override for /usr/lib/live/boot/0042_ciss_post_decrypt_attest -------------------------------------------------------
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. DNSSEC Status # 2. DNSSEC Status
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Haveged Audit on Netcup RS 2000 G11 # 2. Haveged Audit on Netcup RS 2000 G11
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Lynis Audit: # 2. Lynis Audit:
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. SSH Audit by ssh-audit.com # 2. SSH Audit by ssh-audit.com
+51 -53
View File
@@ -8,15 +8,14 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. TLS Audit: # 2. TLS Audit:
````text ````text
./testssl.sh --show-each --wide --phone-out --full https://git.coresecret.dev/ ./testssl.sh --show-each --wide --phone-out --full https://git.coresecret.dev/
##################################################################### #####################################################################
testssl.sh version 3.2.2 from https://testssl.sh/ testssl.sh version 3.2.3 from https://testssl.sh/
(2e77f5e 2025-09-22 19:35:27) (0ff7a34 2026-06-01 09:45:44)
This program is free software. Distribution and modification under This program is free software. Distribution and modification under
GPLv2 permitted. USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK! GPLv2 permitted. USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!
@@ -27,7 +26,7 @@ include_toc: true
Using OpenSSL 1.0.2-bad (Mar 28 2025) [~179 ciphers] Using OpenSSL 1.0.2-bad (Mar 28 2025) [~179 ciphers]
on kali:./bin/openssl.Linux.x86_64 on kali:./bin/openssl.Linux.x86_64
Start 2025-09-28 16:12:17 -->> 152.53.110.40:443 (git.coresecret.dev) <<-- Start 2026-06-17 14:44:50 -->> 152.53.110.40:443 (git.coresecret.dev) <<--
Further IP addresses: 2a0a:4cc0:80:330f:152:53:110:40 Further IP addresses: 2a0a:4cc0:80:330f:152:53:110:40
rDNS (152.53.110.40): git.coresecret.dev. rDNS (152.53.110.40): git.coresecret.dev.
@@ -73,11 +72,11 @@ TLSv1
TLSv1.1 TLSv1.1
- -
TLSv1.2 (server order) TLSv1.2 (server order)
xc030 ECDHE-RSA-AES256-GCM-SHA384 ECDH 448 AESGCM 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 xc02c ECDHE-ECDSA-AES256-GCM-SHA384 ECDH 448 AESGCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
xcca8 ECDHE-RSA-CHACHA20-POLY1305 ECDH 448 ChaCha20 256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 xcca9 ECDHE-ECDSA-CHACHA20-POLY1305 ECDH 448 ChaCha20 256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLSv1.3 (server order) TLSv1.3 (server order)
x1302 TLS_AES_256_GCM_SHA384 ECDH 448 AESGCM 256 TLS_AES_256_GCM_SHA384 x1302 TLS_AES_256_GCM_SHA384 MLKEM1024 AESGCM 256 TLS_AES_256_GCM_SHA384
x1303 TLS_CHACHA20_POLY1305_SHA256 ECDH 448 ChaCha20 256 TLS_CHACHA20_POLY1305_SHA256 x1303 TLS_CHACHA20_POLY1305_SHA256 MLKEM1024 ChaCha20 256 TLS_CHACHA20_POLY1305_SHA256
Has server cipher order? yes (OK) -- TLS 1.3 and below Has server cipher order? yes (OK) -- TLS 1.3 and below
@@ -88,21 +87,21 @@ TLSv1.3 (server order)
Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (IANA/RFC) Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (IANA/RFC)
----------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------
x1302 TLS_AES_256_GCM_SHA384 ECDH 448 AESGCM 256 TLS_AES_256_GCM_SHA384 available x1302 TLS_AES_256_GCM_SHA384 MLKEM1024 AESGCM 256 TLS_AES_256_GCM_SHA384 available
x1303 TLS_CHACHA20_POLY1305_SHA256 ECDH 448 ChaCha20 256 TLS_CHACHA20_POLY1305_SHA256 available x1303 TLS_CHACHA20_POLY1305_SHA256 MLKEM1024 ChaCha20 256 TLS_CHACHA20_POLY1305_SHA256 available
xcc14 ECDHE-ECDSA-CHACHA20-POLY1305-OLD ECDH ChaCha20 256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v xcc14 ECDHE-ECDSA-CHACHA20-POLY1305-OLD ECDH ChaCha20 256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v
xcc13 ECDHE-RSA-CHACHA20-POLY1305-OLD ECDH ChaCha20 256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v xcc13 ECDHE-RSA-CHACHA20-POLY1305-OLD ECDH ChaCha20 256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v
xcc15 DHE-RSA-CHACHA20-POLY1305-OLD DH ChaCha20 256 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v xcc15 DHE-RSA-CHACHA20-POLY1305-OLD DH ChaCha20 256 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD not a/v
xc030 ECDHE-RSA-AES256-GCM-SHA384 ECDH 521 AESGCM 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 available xc030 ECDHE-RSA-AES256-GCM-SHA384 ECDH AESGCM 256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 not a/v
xc02c ECDHE-ECDSA-AES256-GCM-SHA384 ECDH AESGCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 not a/v xc02c ECDHE-ECDSA-AES256-GCM-SHA384 ECDH 521 AESGCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 available
xc028 ECDHE-RSA-AES256-SHA384 ECDH AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 not a/v xc028 ECDHE-RSA-AES256-SHA384 ECDH AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 not a/v
xc024 ECDHE-ECDSA-AES256-SHA384 ECDH AES 256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 not a/v xc024 ECDHE-ECDSA-AES256-SHA384 ECDH AES 256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 not a/v
xc014 ECDHE-RSA-AES256-SHA ECDH AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA not a/v xc014 ECDHE-RSA-AES256-SHA ECDH AES 256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA not a/v
xc00a ECDHE-ECDSA-AES256-SHA ECDH AES 256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA not a/v xc00a ECDHE-ECDSA-AES256-SHA ECDH AES 256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA not a/v
xa3 DHE-DSS-AES256-GCM-SHA384 DH AESGCM 256 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 not a/v xa3 DHE-DSS-AES256-GCM-SHA384 DH AESGCM 256 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 not a/v
x9f DHE-RSA-AES256-GCM-SHA384 DH AESGCM 256 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 not a/v x9f DHE-RSA-AES256-GCM-SHA384 DH AESGCM 256 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 not a/v
xcca9 ECDHE-ECDSA-CHACHA20-POLY1305 ECDH ChaCha20 256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 not a/v xcca9 ECDHE-ECDSA-CHACHA20-POLY1305 ECDH 448 ChaCha20 256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 available
xcca8 ECDHE-RSA-CHACHA20-POLY1305 ECDH 448 ChaCha20 256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 available xcca8 ECDHE-RSA-CHACHA20-POLY1305 ECDH ChaCha20 256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 not a/v
xccaa DHE-RSA-CHACHA20-POLY1305 DH ChaCha20 256 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 not a/v xccaa DHE-RSA-CHACHA20-POLY1305 DH ChaCha20 256 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 not a/v
xc0af ECDHE-ECDSA-AES256-CCM8 ECDH AESCCM8 256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 not a/v xc0af ECDHE-ECDSA-AES256-CCM8 ECDH AESCCM8 256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 not a/v
xc0ad ECDHE-ECDSA-AES256-CCM ECDH AESCCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM not a/v xc0ad ECDHE-ECDSA-AES256-CCM ECDH AESCCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM not a/v
@@ -170,9 +169,10 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
xc086 - ECDH CamelliaGCM 128 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 not a/v xc086 - ECDH CamelliaGCM 128 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 not a/v
xc08a - ECDH CamelliaGCM 128 TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 not a/v xc08a - ECDH CamelliaGCM 128 TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 not a/v
KEMs offered MLKEM1024 X25519MLKEM768 SecP384r1MLKEM1024
Elliptic curves offered: secp384r1 secp521r1 X448 Elliptic curves offered: secp384r1 secp521r1 X448
TLS 1.2 sig_algs offered: RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512 RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA+SHA224 TLS 1.2 sig_algs offered: ECDSA+SHA256 ECDSA+SHA384 ECDSA+SHA512 ECDSA+SHA224
TLS 1.3 sig_algs offered: RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512 TLS 1.3 sig_algs offered: ECDSA+SHA384
Testing server defaults (Server Hello) Testing server defaults (Server Hello)
@@ -185,33 +185,33 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
TLS clock skew Random values, no fingerprinting possible TLS clock skew Random values, no fingerprinting possible
Certificate Compression none Certificate Compression none
Client Authentication none Client Authentication none
Signature Algorithm SHA256 with RSA Signature Algorithm ECDSA with SHA256
Server key size RSA 4096 bits (exponent is 65537) Server key size EC 384 bits (curve P-384)
Server key usage Digital Signature, Key Encipherment Server key usage Digital Signature
Server extended key usage TLS Web Server Authentication, TLS Web Client Authentication Server extended key usage TLS Web Server Authentication
Serial 13292523EB168BD226CE46 (OK: length 11) Serial 85135AE9A772A9778768548CDED9F483 (OK: length 16)
Fingerprints SHA1 1CCF67686A5FFF33D163EFC9E67AB5C70D1122B8 Fingerprints SHA1 7745E895B49A44DA786509D124F7BAEF5BCDE21A
SHA256 565271C2C74AF9EF5F0DCA16453A643C13E43CBD5B87AB82A622E929C48C8B7B SHA256 EBAC1DAD82CFAF97644D2F9A03082DE9ABC2B44AD4C86FE6FA202D3EF7243FE4
Common Name (CN) coresecret.dev Common Name (CN) coresecret.dev
subjectAltName (SAN) coresecret.dev git.coresecret.dev lab.coresecret.dev run.coresecret.dev www.coresecret.dev subjectAltName (SAN) coresecret.dev badges.coresecret.dev cendev.eu git.coresecret.dev lab.coresecret.dev phpmyadmin.git.coresecret.dev
run.coresecret.dev uml.coresecret.dev www.coresecret.dev
Trust (hostname) Ok via SAN (same w/o SNI) Trust (hostname) Ok via SAN (same w/o SNI)
Chain of trust Ok Chain of trust Ok
EV cert (experimental) no EV cert (experimental) no
Certificate Validity (UTC) 178 >= 60 days (2025-09-27 18:27 --> 2026-03-25 22:59) Certificate Validity (UTC) 89 >= 60 days (2026-06-16 00:00 --> 2026-09-14 23:59)
ETS/"eTLS", visibility info not present ETS/"eTLS", visibility info not present
In pwnedkeys.com DB not in database Certificate Revocation List http://crl.buypass.no/crl/BPClass2CA5.crl, not revoked In pwnedkeys.com DB not in database
OCSP URI http://ocsp.buypass.com, not revoked Certificate Revocation List --
OCSP URI http://ocsp.sectigo.com, not revoked
OCSP stapling offered, not revoked OCSP stapling offered, not revoked
OCSP must staple extension -- OCSP must staple extension supported
DNS CAA RR (experimental) available - please check for match with "Issuer" below DNS CAA RR (experimental) available - please check for match with "Issuer" below
communications=error, iodef=mailto:dns@coresecret.eu, issue=;, issue=buypass.no, issue=certum.pl, contactemail=caa@coresecret.eu, iodef=mailto:caa@coresecret.eu, issue=;, issue=certum.pl, issue=letsencrypt.org;,
issue=letsencrypt.org;, issue=quantumsign.eu;, issue=sectigo.com, issuect=quantumsign.eu;, issuect=quantumsign.eu;, issue=quantumsign.eu;, issue=sectigo.com, issuemail=certum.pl, issuevmc=sectigo.com, issuewild=;
issuect=quantumsign.eu;, issuect=quantumsign.eu;, issuect=quantumsign.eu;, issuect=quantumsign.eu;,
issuect=quantumsign.eu;, issuect=quantumsign.eu;, issuemail=buypass.no, issuemail=certum.pl, issuewild=;
Certificate Transparency yes (certificate extension) Certificate Transparency yes (certificate extension)
Certificates provided 2 Certificates provided 2
Issuer Buypass Class 2 CA 5 (Buypass AS-983163327 from NO) Issuer ZeroSSL ECC DV SSL CA 2 (ZeroSSL GmbH from AT)
Intermediate cert validity #1: ok > 40 days (2027-05-23 12:57). Buypass Class 2 CA 5 <-- Buypass Class 2 Root CA Intermediate cert validity #1: ok > 40 days (2035-09-23 23:59). ZeroSSL ECC DV SSL CA 2 <-- Sectigo Public Server Authentication Root E46
Intermediate Bad OCSP (exp.) Ok Intermediate Bad OCSP (exp.) Ok
@@ -223,7 +223,7 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
Public Key Pinning -- Public Key Pinning --
Server banner nginx Server banner nginx
Application banner -- Application banner --
Cookie(s) 2 issued: 2/2 secure, 2/2 HttpOnly Cookie(s) 1 issued: 1/1 secure, 1/1 HttpOnly
Security headers X-Frame-Options: SAMEORIGIN Security headers X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'; connect-src 'self'; font-src 'self' data:; form-action 'self' Content-Security-Policy: default-src 'self'; connect-src 'self'; font-src 'self' data:; form-action 'self'
@@ -236,7 +236,6 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
Cross-Origin-Resource-Policy: cross-origin Cross-Origin-Resource-Policy: cross-origin
Cross-Origin-Embedder-Policy: unsafe-none Cross-Origin-Embedder-Policy: unsafe-none
X-XSS-Protection: 1; mode=block X-XSS-Protection: 1; mode=block
Permissions-Policy: interest-cohort=()
Referrer-Policy: no-referrer Referrer-Policy: no-referrer
Cache-Control: no-cache Cache-Control: no-cache
Reverse Proxy banner -- Reverse Proxy banner --
@@ -257,8 +256,7 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
SWEET32 (CVE-2016-2183, CVE-2016-6329) not vulnerable (OK) SWEET32 (CVE-2016-2183, CVE-2016-6329) not vulnerable (OK)
FREAK (CVE-2015-0204) not vulnerable (OK) FREAK (CVE-2015-0204) not vulnerable (OK)
DROWN (CVE-2016-0800, CVE-2016-0703) not vulnerable on this host and port (OK) DROWN (CVE-2016-0800, CVE-2016-0703) not vulnerable on this host and port (OK)
make sure you don't use this certificate elsewhere with SSLv2 enabled services, see no RSA certificate, thus certificate can't be used with SSLv2 elsewhere
https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=565271C2C74AF9EF5F0DCA16453A643C13E43CBD5B87AB82A622E929C48C8B7B
LOGJAM (CVE-2015-4000), experimental not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2 LOGJAM (CVE-2015-4000), experimental not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2
BEAST (CVE-2011-3389) not vulnerable (OK), no SSL3 or TLS1 BEAST (CVE-2011-3389) not vulnerable (OK), no SSL3 or TLS1
LUCKY13 (CVE-2013-0169), experimental not vulnerable (OK) LUCKY13 (CVE-2013-0169), experimental not vulnerable (OK)
@@ -271,24 +269,24 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
Browser Protocol Cipher Suite Name (OpenSSL) Forward Secrecy Browser Protocol Cipher Suite Name (OpenSSL) Forward Secrecy
------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------
Android 7.0 (native) No connection Android 7.0 (native) No connection
Android 8.1 (native) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 384 bit ECDH (P-384) Android 8.1 (native) TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
Android 9.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Android 9.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Android 10.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Android 10.0 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Android 11/12 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Android 11/12 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Android 13/14 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Android 13/14 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Android 15 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Android 15 (native) TLSv1.3 TLS_AES_256_GCM_SHA384 X25519MLKEM768
Chrome 101 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Chrome 101 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Chromium 137 (Win 11) TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Chromium 137 (Win 11) TLSv1.3 TLS_AES_256_GCM_SHA384 X25519MLKEM768
Firefox 100 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Firefox 100 (Win 10) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
Firefox 137 (Win 11) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Firefox 137 (Win 11) TLSv1.3 TLS_AES_256_GCM_SHA384 X25519MLKEM768
IE 8 Win 7 No connection IE 8 Win 7 No connection
IE 11 Win 7 No connection IE 11 Win 7 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
IE 11 Win 8.1 No connection IE 11 Win 8.1 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
IE 11 Win Phone 8.1 No connection IE 11 Win Phone 8.1 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
IE 11 Win 10 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 384 bit ECDH (P-384) IE 11 Win 10 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
Edge 15 Win 10 TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 384 bit ECDH (P-384) Edge 15 Win 10 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 384 bit ECDH (P-384)
Edge 101 Win 10 21H2 TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Edge 101 Win 10 21H2 TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384)
Edge 133 Win 11 23H2 TLSv1.3 TLS_AES_256_GCM_SHA384 384 bit ECDH (P-384) Edge 133 Win 11 23H2 TLSv1.3 TLS_AES_256_GCM_SHA384 X25519MLKEM768
Safari 18.4 (iOS 18.4) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Safari 18.4 (iOS 18.4) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
Safari 15.4 (macOS 12.3.1) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Safari 15.4 (macOS 12.3.1) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
Safari 18.4 (macOS 15.4) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Safari 18.4 (macOS 15.4) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
@@ -299,11 +297,11 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
Java 21.0.6 (OpenJDK) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448) Java 21.0.6 (OpenJDK) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448)
go 1.17.8 TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) go 1.17.8 TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
LibreSSL 3.3.6 (macOS) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) LibreSSL 3.3.6 (macOS) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
OpenSSL 1.0.2e TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 521 bit ECDH (P-521) OpenSSL 1.0.2e TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 521 bit ECDH (P-521)
OpenSSL 1.1.1d (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448) OpenSSL 1.1.1d (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448)
OpenSSL 3.0.15 (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448) OpenSSL 3.0.15 (Debian) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448)
OpenSSL 3.5.0 (git) TLSv1.3 TLS_AES_256_GCM_SHA384 448 bit ECDH (X448) OpenSSL 3.5.0 (git) TLSv1.3 TLS_AES_256_GCM_SHA384 X25519MLKEM768
Apple Mail (16.0) TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 521 bit ECDH (P-521) Apple Mail (16.0) TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384 521 bit ECDH (P-521)
Thunderbird (91.9) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521) Thunderbird (91.9) TLSv1.3 TLS_AES_256_GCM_SHA384 521 bit ECDH (P-521)
@@ -317,7 +315,7 @@ Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Ciphe
Final Score 100 Final Score 100
Overall Grade A+ Overall Grade A+
Done 2025-09-28 16:13:50 [ 95s] -->> 152.53.110.40:443 (git.coresecret.dev) <<-- Done 2026-06-17 14:46:05 [ 78s] -->> 152.53.110.40:443 (git.coresecret.dev) <<--
```` ````
--- ---
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Hardened Kernel Boot Parameters # 2. Hardened Kernel Boot Parameters
+25 -2
View File
@@ -8,10 +8,33 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Changelog # 2. Changelog
## V9.14.028.2026.06.18
* **Changed**: [0024-ciss-crypt-squash](../config/includes.chroot/usr/lib/live/boot/0024-ciss-crypt-squash) Explicitly permissions the runtime rootfs attestation cache and fails closed on cache creation or chmod errors.
* **Changed**: [MAN_CISS_ISO_BOOT_CHAIN.md](MAN_CISS_ISO_BOOT_CHAIN.md) Documents the rootfs attestation artifact custody path from build-time `binary/live` creation through the `0024` runtime cache and `0042` verification.
* **Changed**: [README.md](../README.md) Documents the runtime rootfs attestation cache handoff.
## V9.14.026.2026.06.17
* **Updated**: git.coresecret.dev nginx Mainline 1.31.1 custom build with OpenSSL 4.0.1 to support PQC KEX algorithms:
* * ``MLKEM1024`` ``SecP384r1MLKEM1024`` ``X25519MLKEM768``
* * ECDH: ``X448`` ``secp521r1`` ``secp384r1``
* **Updated**: [AUDIT_TLS.md](AUDIT_TLS.md)
## V9.14.024.2026.06.11
* **Added**: [lib_build_dir_safety.sh](../lib/lib_build_dir_safety.sh) Integrated Security Audit Finding A12
* **Added**: [lib_debug_sanitize.sh](../lib/lib_debug_sanitize.sh) Integrated Security Audit Finding A11
* **Added**: [lib_secret_validation.sh](../lib/lib_secret_validation.sh) Integrated Security Audit Finding A10
* **Changed**: [zzzz_ciss_crypt_squash.hook.binary](../config/hooks/live/zzzz_ciss_crypt_squash.hook.binary) Integrated Security Audit Finding A01 + A10
* **Changed**: [0030-ciss-verify-checksums](../config/includes.chroot/usr/lib/live/boot/0030-ciss-verify-checksums) Integrated Security Audit Finding A02
* **Changed**: [0042_ciss_post_decrypt_attest](../config/includes.chroot/usr/lib/live/boot/0042_ciss_post_decrypt_attest) Integrated Security Audit Finding A01
* **Changed**: [lib_ciss_upgrades_boot.sh](../lib/lib_ciss_upgrades_boot.sh) Integrated Security Audit Finding A01
* **Changed**: [lib_lb_config_start.sh](../lib/lib_lb_config_start.sh) Integrated Security Audit Finding A12
* **Changed**: [README.md](../README.md) Integrated Security Audit Finding A01 + A02
* **Changed**: [lib_usage.sh](../lib/lib_usage.sh) Integrated Security Audit Finding A10
## V9.14.022.2026.06.10 ## V9.14.022.2026.06.10
* **Added**: [lib_logo.sh](../lib/lib_logo.sh) * **Added**: [lib_logo.sh](../lib/lib_logo.sh)
* **Added**: [9999_cdi_starter.sh](../scripts/usr/local/sbin/9999_cdi_starter.sh) Retrieve rdns for Primordial-Workflow™ * **Added**: [9999_cdi_starter.sh](../scripts/usr/local/sbin/9999_cdi_starter.sh) Retrieve rdns for Primordial-Workflow™
@@ -196,7 +219,7 @@ include_toc: true
* **Added**: [lib_ciss_upgrades_build.sh](../lib/lib_ciss_upgrades_build.sh) Updates for CISS and PhysNet Primordial-Workflow™. * **Added**: [lib_ciss_upgrades_build.sh](../lib/lib_ciss_upgrades_build.sh) Updates for CISS and PhysNet Primordial-Workflow™.
* **Added**: [lib_gnupg.sh](../lib/lib_gnupg.sh) Updates for CISS and PhysNet Primordial-Workflow™. * **Added**: [lib_gnupg.sh](../lib/lib_gnupg.sh) Updates for CISS and PhysNet Primordial-Workflow™.
* **Added**: [lib_primordial.sh](../lib/lib_primordial.sh) Updates for CISS and PhysNet Primordial-Workflow™. * **Added**: [lib_primordial.sh](../lib/lib_primordial.sh) Updates for CISS and PhysNet Primordial-Workflow™.
* **Added**: [0030-ciss-verify-checksums](../scripts/usr/lib/live/boot/0030-ciss-verify-checksums) Unified handling via includes.chroot. * **Added**: [0030-ciss-verify-checksums](../.archive/0030-ciss-verify-checksums) Unified handling via includes.chroot.
* **Bugfixes**: [linter_char_scripts.yaml](../.gitea/workflows/linter_char_scripts.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-linter_char_scripts.yaml}" * **Bugfixes**: [linter_char_scripts.yaml](../.gitea/workflows/linter_char_scripts.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-linter_char_scripts.yaml}"
* **Bugfixes**: [render-dnssec-status.yaml](../.gitea/workflows/render-dnssec-status.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-render-dnssec-status.yaml}" * **Bugfixes**: [render-dnssec-status.yaml](../.gitea/workflows/render-dnssec-status.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-render-dnssec-status.yaml}"
* **Bugfixes**: [render-dot-to-png.yaml](../.gitea/workflows/render-dot-to-png.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-render-dot-to-png.yaml}" * **Bugfixes**: [render-dot-to-png.yaml](../.gitea/workflows/render-dot-to-png.yaml) - WORKFLOW_ID="${GITHUB_WORKFLOW:-render-dot-to-png.yaml}"
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Centurion Net - Developer Branch Overview # 2. Centurion Net - Developer Branch Overview
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Purpose # 2. Purpose
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Contributing / participating # 2. Contributing / participating
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Credits # 2. Credits
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Download the latest PUBLIC CISS.debian.live.ISO # 2. Download the latest PUBLIC CISS.debian.live.ISO
+11 -7
View File
@@ -8,14 +8,14 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2.1. Usage # 2.1. Usage
````text ````text
CDLB(1) CISS.debian.live.builder CDLB(1) CDLB(1) CISS.debian.live.builder CDLB(1)
CISS.debian.live.builder from https://git.coresecret.dev/msw CISS.debian.live.builder from https://git.coresecret.dev/msw
Master V9.14.022.2026.06.10 Master V9.14.028.2026.06.18
A lightweight Shell Wrapper for building a hardened Debian Live ISO Image. A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
(c) Marc S. Weidner, 2018 - 2026 (c) Marc S. Weidner, 2018 - 2026
@@ -37,6 +37,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
--build-directory </path/to/build_directory> --build-directory </path/to/build_directory>
Where the Debian Live Build Image should be generated. RECOMMENDED path: </opt/cdlb> Where the Debian Live Build Image should be generated. RECOMMENDED path: </opt/cdlb>
Cleanup is destructive inside the exact builder-owned path and requires '.ciss-live-builder-owned'.
MUST be provided. MUST be provided.
--change-splash <STRING> one of <club | hexagon> --change-splash <STRING> one of <club | hexagon>
@@ -57,6 +58,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
--debug, -d --debug, -d
Enables debug logging for the main program routine. Detailed logging information are written to: Enables debug logging for the main program routine. Detailed logging information are written to:
</tmp/ciss_live_builder_1801049.log> </tmp/ciss_live_builder_1801049.log>
After xtrace is stopped and its debug FD is closed, a final exact-value redaction pass sanitizes logs.
--dhcp-centurion --dhcp-centurion
If a DHCP lease is provided, the provider's name server will be overridden and the hardened, privacy-focused If a DHCP lease is provided, the provider's name server will be overridden and the hardened, privacy-focused
@@ -86,12 +88,12 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
--key_age=* --key_age=*
The SOPS AGE private keyring for decryption operations. Change '*' to your desired SOPS AGE key file. The SOPS AGE private keyring for decryption operations. Change '*' to your desired SOPS AGE key file.
File MUST be placed in: This MUST be a filename only and MUST be placed in the root-owned tmpfs secret root:
</dev/shm/cdlb_secrets> </dev/shm/cdlb_secrets>
--key_luks=* --key_luks=*
The LUKS encryption / decryption passphrase for '/'-fs-encryption. Change '*' to your desired passphrase file. The LUKS encryption / decryption passphrase for '/'-fs-encryption. Change '*' to your desired passphrase file.
File MUST be placed in: This MUST be a filename only and MUST be placed in the root-owned tmpfs secret root:
</dev/shm/cdlb_secrets> </dev/shm/cdlb_secrets>
--log-statistics-only --log-statistics-only
@@ -140,7 +142,8 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
--root-password-file </dev/shm/cdlb_secrets/password.txt>> --root-password-file </dev/shm/cdlb_secrets/password.txt>>
Password file for 'root', if given, MUST be a string of 42 to 64 characters. Password file for 'root', if given, MUST be a string of 42 to 64 characters.
If the argument is omitted, no further login authentication is required for the local console. If the argument is omitted, no further login authentication is required for the local console.
MUST be placed in: The path MUST be absolute, regular, non-symlink, root-owned, and mode 0400 after normalization.
RECOMMENDED path:
</dev/shm/cdlb_secrets/password.txt> </dev/shm/cdlb_secrets/password.txt>
--secure-boot-profile <STRING> one of <debian-shim | ciss-uki> --secure-boot-profile <STRING> one of <debian-shim | ciss-uki>
@@ -156,7 +159,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
specified via '--signing_key=*'. If the keyring is protected, then provide the passphrase in its own file. specified via '--signing_key=*'. If the keyring is protected, then provide the passphrase in its own file.
Specify the fingerprint of the key to use via '--signing_key_fpr=*'. Specify the fingerprint of the key to use via '--signing_key_fpr=*'.
Optionally import an offline GPG CA signing public key via: '--signing_ca=*'. Optionally import an offline GPG CA signing public key via: '--signing_ca=*'.
Change '*' to your desired files / fingerprint. Files MUST be placed in: Change '*' to your desired filename-only files / fingerprint. Files MUST be placed in:
</dev/shm/cdlb_secrets> </dev/shm/cdlb_secrets>
--sshfp --sshfp
@@ -171,6 +174,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
--ssh-pubkey </dev/shm/cdlb_secrets/> --ssh-pubkey </dev/shm/cdlb_secrets/>
Imports the SSH Public Key from the file 'authorized_keys' into the Live ISO. Imports the SSH Public Key from the file 'authorized_keys' into the Live ISO.
Directory MUST be absolute, regular, non-symlink, root-owned, and not group/world-writable.
Key file MUST be placed in: Key file MUST be placed in:
</dev/shm/cdlb_secrets/authorized_keys> </dev/shm/cdlb_secrets/authorized_keys>
@@ -186,7 +190,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
💷 Please consider donating to my work at: 💷 Please consider donating to my work at:
🌐 https://coresecret.eu/spenden/ 🌐 https://coresecret.eu/spenden/
V9.14.022.2026.06.10 2026-05-17 CDLB(1) V9.14.028.2026.06.18 2026-05-17 CDLB(1)
```` ````
# 3. Booting # 3. Booting
+171 -93
View File
@@ -8,28 +8,23 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. CISS.debian.live.builder Boot & Trust Chain (Technical Documentation) # 2. CISS.debian.live.builder Boot & Trust Chain (Technical Documentation)
**Status:** 2026-06-10<br> **Status:** 2026-06-18<br>
**Audience:** CICA CISO, CISS staff, technically proficient administrators<br> **Audience:** CICA CISO, CISS staff, technically proficient administrators<br>
**Summary:** The **CISS.debian.live.builder** Live-ISO establishes a two-stage verification chain around the live root: an **Summary:** The **CISS.debian.live.builder** Live-ISO establishes a two-stage verification chain around the live root: after the CISS LUKS/dm-integrity container has been opened, and the live medium context has been exposed, `0030-ciss-verify-checksums` verifies the mounted live-medium checksum manifest, detached signature, and signer fingerprint; `0024-ciss-crypt-squash` preserves the rootfs attestation artifacts from the real ISO medium into a stable initramfs runtime cache; later, `0042_ciss_post_decrypt_attest` verifies the signed rootfs attestation manifest, and the exact final SquashFS payload bytes copied into the decrypted LUKS mapper. UEFI Secure Boot can use either the default Microsoft/Debian shim chain, or a CISS-signed UKI chain for systems that trust the CISS Secure Boot key material.<br>
ISO-edge checksum-manifest check and a late attestation of the complete selected decrypted rootfs mapper. The late check verifies
both the signed SHA-512 manifest and the mapper bytes before boot continues. `dm-integrity` separately provides sector-integrity
protection and is not a substitute for origin-bound signature and checksum attestation. UEFI Secure Boot can use either the
default Microsoft/Debian shim chain, or a CISS-signed UKI chain for systems that trust the CISS Secure Boot key material.<br>
# 3. Overview # 3. Overview
* **Trust anchor:** Pinned fingerprint (FPR) of the signing key embedded at build time in initramfs hooks. * **Trust anchor:** Pinned fingerprint (FPR) of the signing key embedded at build time in initramfs hooks.
* **Integrity & authenticity verification:** * **Integrity and authenticity verification:**
1. **ISO edge:** Verify one supported checksum manifest using `gpgv`, FPR pinning, and the matching checksum tool. 1. **Mounted live medium:** After `0024-ciss-crypt-squash` has opened the encrypted container and exposed `/run/live/medium`, verify `sha512sum.txt` using `gpgv`, FPR pinning, and checksum execution.
2. **Late rootfs attestation:** Verify the signed mapper manifest and the complete selected decrypted mapper 2. **Decrypted rootfs payload:** Preserve the external rootfs attestation manifest and detached signature before live-boot may replace or unmount the medium view, verify the cached manifest using `gpgv` and FPR pinning, then verify the exact SquashFS payload bytes from the decrypted mapper with `sha512sum -c`.
`/dev/mapper/crypt_liveiso` with `sha512sum -c`.
* **Storage-level protection:** `dm-crypt` (AES-XTS-512) and, outside runner builds, `dm-integrity` (HMAC-SHA-512, 4 KiB). * **Storage-level confidentiality and keyed sector integrity:** `dm-crypt` (AES-XTS-512) and `dm-integrity` (HMAC-SHA-512, 4 KiB).
* **Remotely unlock:** CISS hardened and build dropbear, modern primitives only, no passwords, no agent/forwarding. * **Remotely unlock:** CISS hardened and build dropbear, modern primitives only, no passwords, no agent/forwarding.
# 3.1. Secure Boot Profiles # 3.1. Secure Boot Profiles
@@ -54,15 +49,15 @@ private Secure Boot key names are detected in those paths before live-build chec
# 4. Primitives & Parameters # 4. Primitives & Parameters
| Component | Primitive / Parameter | Purpose | | Component | Primitive / Parameter | Purpose |
|--------------|-----------------------------------------------------------|--------------------------------------------------------| |--------------|----------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| LUKS2 | `aes-xts-plain64`, `--key-size 512`, `--sector-size 4096` | Confidentiality (2×256-bit XTS) | | LUKS2 | `aes-xts-plain64`, `--key-size 512`, `--sector-size 4096` | Confidentiality (2×256-bit XTS) |
| dm-integrity | `hmac-sha512` (keyed), journal | Per-sector integrity inside the LUKS mapping; not origin attestation | | dm-integrity | `hmac-sha512` (keyed), journal | Keyed per-sector integrity for the opened mapping; not origin authenticity |
| PBKDF | `argon2id`, `--iter-time 1000` ms | Key derivation, hardware-agnostic | | PBKDF | `argon2id`, `--iter-time 1000` ms, `--pbkdf-memory 262144`, `--pbkdf-parallel 1` | Bounded key derivation cost for initramfs unlock |
| Signatures | Ed25519 or RSA-4096 (FPR pinned) | Public verifiability, non-repudiation | | Signatures | Ed25519 or RSA-4096 (FPR pinned) | Public verifiability, non-repudiation |
| Verification | `gpgv --no-default-keyring` | No agent dependency in initramfs | | Verification | `gpgv --keyring <pinned-keyring>` | Explicit keyring selection and no agent dependency in initramfs |
| Hash lists | `sha512sum` format | Deterministic ISO-edge and decrypted-mapper verification | | Hash lists | `sha512sum` format | Deterministic content verification |
| Dropbear | Modern KEX/AEAD (per `localoptions.h`) | Minimal attack surface, remote unlock | | Dropbear | Modern KEX/AEAD (per `localoptions.h`) | Minimal attack surface, remote unlock |
# 5. Diagram: CISS Live ISO Boot Flow # 5. Diagram: CISS Live ISO Boot Flow
```mermaid ```mermaid
@@ -97,12 +92,14 @@ flowchart TD
0090 e09@--> 0100["Starting CISS.hardened dropbear"]; 0090 e09@--> 0100["Starting CISS.hardened dropbear"];
0100 e10@--> 0110["Executing live-boot, mounting ISO FS"]; 0100 e10@--> 0110["Executing live-boot, mounting ISO FS"];
0110 e11@--> 0122["Executing 0022-ciss: Hardening tmpfs for OverlayFS upper/work"]; 0110 e11@--> 0122["Executing 0022-ciss: Hardening tmpfs for OverlayFS upper/work"];
0122 e12@--> 0124["Executing 0024-ciss: LUKS open (dm-crypt & integrity)"]; 0122 e12@--> 0124["Executing 0024-ciss: Mount ISO medium and locate /live/ciss_rootfs.crypt"];
0124 e13@--> |SUCCESSFUL| LUKS["Unlocking LUKS2 Argon2id PBKDF → XTS + HMAC-SHA512"]; 0124 e13@--> CACHE["0024-ciss: Preserve rootfs attestation artifacts in /run/ciss-rootfs-attestation"];
LUKS e14@--> ROOT["Assemble RootFS OverlayFS"]; CACHE e13b@--> LUKSOPEN["0024-ciss: LUKS open (dm-crypt & integrity)"];
ROOT e15@--> 0126["Executing 0026-ciss: Hardening early sysctls"]; LUKSOPEN e13c@--> |SUCCESSFUL| LUKS["Decrypted mapper exposed; livefs_root=/run/live/medium set"];
0126 e16@--> 0130["Executing 0030-ciss: Verification of authenticity and integrity via embedded and pinned GPG of ISO edge"]; LUKS e14@--> 0126["Executing 0026-ciss: Hardening early sysctls"];
0130 e17@--> |SUCCESSFUL| 0142["Executing 0042-ciss: Attestation of RootFS"]; 0126 e15@--> 0130["Executing 0030-ciss: Mounted live-medium checksum and signature verification"];
0130 e16@--> |SUCCESSFUL| ROOT["9990-overlay: Mount SquashFS / OverlayFS"];
ROOT e17@--> 0142["Executing 0042-ciss: Attestation of RootFS SquashFS payload"];
0142 e18@--> 0145["init-bottom: stop CISS.hardened dropbear, tear down initramfs net"]; 0142 e18@--> 0145["init-bottom: stop CISS.hardened dropbear, tear down initramfs net"];
0145 e19@--> 9050["Switching root (run-init / pivot_root)"]; 0145 e19@--> 9050["Switching root (run-init / pivot_root)"];
9050 e20@--> 9010["Starting /sbin/init -> systemd"]; 9050 e20@--> 9010["Starting /sbin/init -> systemd"];
@@ -116,6 +113,8 @@ flowchart TD
e11@{ animation: fast } e11@{ animation: fast }
e12@{ animation: fast } e12@{ animation: fast }
e13@{ animation: fast } e13@{ animation: fast }
e13b@{ animation: fast }
e13c@{ animation: fast }
e14@{ animation: fast } e14@{ animation: fast }
e15@{ animation: fast } e15@{ animation: fast }
e16@{ animation: fast } e16@{ animation: fast }
@@ -135,28 +134,52 @@ flowchart TD
0030 -- FAIL --> X; 0030 -- FAIL --> X;
0040 -- FAIL --> X; 0040 -- FAIL --> X;
0124 -- FAIL --> X; 0124 -- FAIL --> X;
CACHE -- FAIL --> X;
LUKSOPEN -- FAIL --> X;
0130 -- FAIL --> X; 0130 -- FAIL --> X;
0142 -- FAIL --> X; 0142 -- FAIL --> X;
``` ```
# 6. Diagram: CISS Live ISO LUKS and dm-integrity layering # 6. Diagram: CISS Live ISO LUKS and dm-integrity layering
```text
ISO medium
└── /live/ciss_rootfs.crypt
└── LUKS2 / dm-crypt / dm-integrity
└── /dev/mapper/crypt_liveiso
└── SquashFS rootfs [SHA-512 over exact SquashFS byte stream]
└── OverlayFS / running root filesystem
```
Rootfs attestation evidence follows a separate side path:
```text
ISO medium
├── /live/filesystem.squashfs.sha512sum.txt
└── /live/filesystem.squashfs.sha512sum.txt.sig
└── copied by 0024-ciss-crypt-squash to:
├── /run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt
└── /run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt.sig
```
The `/run/ciss-rootfs-attestation/` cache is only a stable initramfs runtime location. It is not a trust anchor. `0042_ciss_post_decrypt_attest` still requires the cached manifest to verify against the detached signature, the pinned GPG fingerprint, and the actual decrypted mapper bytes.
```mermaid ```mermaid
--- ---
config: config:
theme: forest theme: forest
--- ---
flowchart TD flowchart TD
0{{"Plain device: CD-ROM / USB"}} --> 1["ISO image (ISO9660 + ESP)"]; 0{{"Plain device: CD-ROM / USB"}} --> 1["ISO medium (ISO9660 + ESP)"];
1 --> 2["Mount ISO9660 FS → /run/live/medium"]; 1 --> 2["/live/ciss_rootfs.crypt"];
2 --> 3["Container file /run/live/medium/live/ciss_rootfs.crypt"]; 2 --> 3["LUKS2 / dm-crypt / dm-integrity"];
3 --> 4["dm-integrity layer (HMAC-SHA-512, 4 KiB)"]; 3 --> 4["/dev/mapper/crypt_liveiso"];
4 --> 5["dm-crypt LUKS2 (AES-XTS-512) → /dev/mapper/crypt_liveiso"]; 4 --> 5["SquashFS rootfs byte stream"];
5 --> 6["Mount SquashFS from /dev/mapper/crypt_liveiso → /run/live/rootfs"]; 5 --> 6["OverlayFS / running root filesystem"];
``` ```
**Note:** `dm-integrity` detects sector corruption within its keyed mapping. The signed SHA-512 mapper manifest independently **Note:** `dm-integrity` provides keyed sector integrity for the opened LUKS mapping. It is not treated as origin authenticity; origin authenticity is provided by the signed checksum and rootfs attestation manifests plus pinned signer fingerprints.
binds the selected decrypted rootfs payload to the signing key. Neither property substitutes for the other.
# 7. CISS Live ISO LUKS Build-Time Core Steps # 7. CISS Live ISO LUKS Build-Time Core Steps
```sh ```sh
@@ -171,6 +194,8 @@ cryptsetup luksFormat \
--luks2-keyslots-size 16777216 \ --luks2-keyslots-size 16777216 \
--luks2-metadata-size 4194304 \ --luks2-metadata-size 4194304 \
--pbkdf argon2id \ --pbkdf argon2id \
--pbkdf-memory 262144 \
--pbkdf-parallel 1 \
--sector-size 4096 \ --sector-size 4096 \
--type luks2 \ --type luks2 \
--use-random \ --use-random \
@@ -178,62 +203,101 @@ cryptsetup luksFormat \
"${LUKSFS}" "${LUKSFS}"
``` ```
After `filesystem.squashfs` is copied to `/dev/mapper/crypt_liveiso`, the binary hook hashes the complete decrypted mapper,
including the mapper padding after the SquashFS image. It writes
`binary/live/ciss_rootfs.crypt.decrypted.sha512sum.txt`, signs that manifest with the existing artifact-signing key, verifies the
signature and checksum locally, and only then closes the mapping and removes the plaintext `filesystem.squashfs`.
**Signing keys:** Ed25519 and RSA-4096; **FPR pinned at build time** in hooks. Signing keys are **additionally** signed by an offline GPG Root-CA (out-of-band trust chain). **Signing keys:** Ed25519 and RSA-4096; **FPR pinned at build time** in hooks. Signing keys are **additionally** signed by an offline GPG Root-CA (out-of-band trust chain).
# 8. Early ISO-Edge Verification (CISS modified hook 0030-ciss-verify-checksums, live-bottom) ## 7.1. Rootfs Attestation Artifacts Created at Build Time
**Goal:** During live-boot, require one supported ISO-edge checksum manifest to be successfully verified: `config/hooks/live/zzzz_ciss_crypt_squash.hook.binary` runs in the live-build binary phase after `binary/live/filesystem.squashfs` exists and before the final ISO image is emitted.
The hook expects:
| Artifact | Build-time path | Purpose |
|-----------------------------|------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| Final plaintext SquashFS | `${VAR_HANDLER_BUILD_DIR}/binary/live/filesystem.squashfs` | Source byte stream that will be attested and copied into the encrypted mapper. |
| Signing key passphrase file | `${VAR_SIGNING_KEY_PASSFILE}` | Unlocks the configured signing key without exposing the passphrase on the command line. |
| Verification keyring | `${VAR_VERIFY_KEYRING}` | Build-time self-check for the detached signature before the ISO is accepted. |
The hook creates:
| Artifact | Build-time path | ISO path |
|---------------------------------------|------------------------------------------------------------------------------|-----------------------------------------------|
| Encrypted live root container | `${VAR_HANDLER_BUILD_DIR}/binary/live/ciss_rootfs.crypt` | `/live/ciss_rootfs.crypt` |
| Rootfs attestation manifest | `${VAR_HANDLER_BUILD_DIR}/binary/live/filesystem.squashfs.sha512sum.txt` | `/live/filesystem.squashfs.sha512sum.txt` |
| Rootfs attestation detached signature | `${VAR_HANDLER_BUILD_DIR}/binary/live/filesystem.squashfs.sha512sum.txt.sig` | `/live/filesystem.squashfs.sha512sum.txt.sig` |
The manifest format is intentionally small and deterministic:
```text
# CISS.debian.live.builder Master <version>
# Attestation file for filesystem.squashfs Version 1.0.0
# Boundary : Final filesystem.squashfs byte stream copied into /dev/mapper/crypt_liveiso
# Bytes : Final filesystem.squashfs <exact-byte-count>
<sha512-of-final-filesystem.squashfs> filesystem.squashfs
```
The signed boundary is the final SquashFS byte stream before LUKS wrapping. The hook writes that byte stream into `/dev/mapper/crypt_liveiso`, closes the mapper, shreds the transient LUKS key file, removes `binary/live/filesystem.squashfs`, and keeps only `/live/ciss_rootfs.crypt` plus the manifest/signature pair in the final ISO payload tree.
# 8. Mounted Live-Medium Checksum Verification (CISS modified hook 0030-ciss-verify-checksums, live-bottom)
**Goal:** After `0024-ciss-crypt-squash` has opened the encrypted container and exposed the live medium context, but before the final live root is accepted, verify:
1. **Detached signature of `sha512sum.txt`** using `gpgv` against the embedded public key. 1. **Detached signature of `sha512sum.txt`** using `gpgv` against the embedded public key.
2. **FPR pinning:** Parse `VALIDSIG` and require exact match with the build-time pinned FPR. 2. **FPR pinning:** Parse `VALIDSIG` and require exact match with the build-time pinned FPR.
3. **Optional:** *Script self-IA* hash the executed hook and compare against the signed list (drift/bitrot detector). 3. **Optional:** *Script self-IA* hash the executed hook and compare against the signed list (drift/bitrot detector).
Verification is fail-closed. Boot panics if no supported manifest is present, no matching checksum tool is available, checksum
verification does not succeed, signature verification fails when requested, or verification ends in an unknown state.
**Core call (initramfs):** **Core call (initramfs):**
```sh ```sh
/usr/bin/gpgv --no-default-keyring --keyring "$KEYFILE" --status-fd 1 --verify sha512sum.txt.sig sha512sum.txt /usr/bin/gpgv --keyring "$KEYFILE" --status-fd 1 sha512sum.txt.sig sha512sum.txt
# parse [GNUPG:] VALIDSIG ... <FPR> ... # parse [GNUPG:] VALIDSIG ... <FPR> ...
``` ```
# 9. Late Root-FS Payload Attestation (CISS hook 0042_ciss_post_decrypt_attest, called by 9990-overlay.sh) # 9. Late Root-FS Attestation and dmsetup Health (CISS hook 0042_ciss_post_decrypt_attest, called by 9990-overlay.sh)
**Goal:** After LUKS unlock and rootfs selection, verify the authenticity of the manifest and the content of the actual selected **Goal:** After LUKS unlocked, and the live root has been mounted by `9990-overlay.sh`, validate the **decrypted** rootfs payload selected at build time and the **actual** mapping topology.
decrypted rootfs payload.
* **Exact attested boundary:** the complete `/dev/mapper/crypt_liveiso` block payload selected by `9990-overlay.sh` and mounted * **Attested boundary:** the final `binary/live/filesystem.squashfs` byte stream, immediately before it is copied into `/dev/mapper/crypt_liveiso` by `zzzz_ciss_crypt_squash.hook.binary`.
read-only as SquashFS, including mapper padding after the SquashFS image. * **Runtime verification boundary:** the first byte count declared by `# Bytes : Final filesystem.squashfs <bytes>` in the signed manifest, read from the decrypted mapper. Any LUKS allocation slack after the SquashFS payload is intentionally excluded.
* **Attestation files:** `/run/live/medium/live/ciss_rootfs.crypt.decrypted.sha512sum.txt[.sig]` * **ISO attestation files:** `/run/live/medium/live/filesystem.squashfs.sha512sum.txt[.sig]` while the original ISO medium is mounted by `0024-ciss-crypt-squash`.
* **Key source:** `/etc/ciss/keys/<FPR>.gpg` in the initramfs; the valid signature FPR must equal the build-time pin. * **Runtime attestation cache:** `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt[.sig]`, copied by `0024-ciss-crypt-squash` before live-boot may replace or unmount the medium view during `toram` handling.
* **Manifest constraint:** exactly one checksum record is accepted, and it must target the selected mapper path. * **Key source:** `/etc/ciss/keys/*.gpg` (accepted only if FPR == build-pin)
## 9.1. Runtime Artifact Custody and Expectations
| Step | Actor | Requires | Copies / writes | Later consumer |
|------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| 1 | `0024-ciss-crypt-squash` | Mounted ISO medium at `/run/live/medium`; `/run/live/medium/live/ciss_rootfs.crypt`; `/run/live/medium/live/filesystem.squashfs.sha512sum.txt`; `/run/live/medium/live/filesystem.squashfs.sha512sum.txt.sig` | Copies the manifest to `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt` and the detached signature to `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt.sig`; sets the cache directory to `0755` before copy, cached files to `0444`, and best-effort final directory mode to `0555` | `0042_ciss_post_decrypt_attest` |
| 2 | `0024-ciss-crypt-squash` | `/run/live/medium/live/ciss_rootfs.crypt`; unlock passphrase from console or Dropbear path | Opens the encrypted container as `/dev/mapper/crypt_liveiso`; writes `/run/ciss-rootdev` with mapper, medium, and attestation-cache paths | `9990-overlay.sh` |
| 3 | `9990-main.sh` | `/conf/param.conf` with `PLAIN_ROOT=1` and `livefs_root=/run/live/medium`; optional `toram` boot parameter | May copy live media to RAM and may leave `/run/live/medium` busy, replaced, or otherwise unsuitable as the only attestation source | `9990-overlay.sh` and `0042_ciss_post_decrypt_attest` |
| 4 | `9990-overlay.sh` | `/run/ciss-rootdev`; `/dev/mapper/crypt_liveiso` | Sources `/run/ciss-rootdev`, overrides the image directory to `/dev/mapper/crypt_liveiso`, mounts the decrypted SquashFS read-only, and invokes `/usr/lib/live/boot/0042_ciss_post_decrypt_attest` | `0042_ciss_post_decrypt_attest` |
| 5 | `0042_ciss_post_decrypt_attest` | `/etc/ciss/keys/<pinned-FPR>.gpg`; `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt`; `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt.sig`; `/dev/mapper/crypt_liveiso` | Creates transient `/run/ciss-rootfs-attestation.sha512sum` for `sha512sum -c`; does not create trusted evidence | Boot continues only after signature, FPR, and exact payload bytes all verify |
`0042_ciss_post_decrypt_attest` resolves artifacts in this order:
1. The explicit manifest/signature paths exported through `/run/ciss-rootdev`.
2. The default runtime cache under `/run/ciss-rootfs-attestation/`.
3. Compatibility fallback mountpoints: `${CDLB_MNT_MEDIUM}`, `/run/live/medium`, `/lib/live/mount/medium`, and `/cdrom`.
The fallback mountpoints are diagnostic and compatibility paths. The intended normal path for current CISS ISOs is the runtime cache copied by `0024-ciss-crypt-squash`.
**Core calls (initramfs):** **Core calls (initramfs):**
```sh ```sh
# 1) Signature and FPR pin (no agent) # 1) Signature and FPR pin (no agent)
/usr/bin/gpgv --no-default-keyring --keyring "$KEYFILE" --status-fd 1 --verify "$SIG" "$DATA" DATA="/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt"
SIG="${DATA}.sig"
KEYFILE="/etc/ciss/keys/<pinned-FPR>.gpg"
/usr/bin/gpgv --keyring "${KEYFILE}" --status-fd 1 "${SIG}" "${DATA}"
# 2) Required selected-payload verification # 2) Mandatory content hash verification
( cd / && /usr/bin/sha512sum -c --strict --quiet "$DATA" ) dd if="${CDLB_MAPPER_DEV}" ... | /usr/bin/sha512sum -c /run/ciss-rootfs-attestation.sha512sum
``` ```
The signed manifest alone is not sufficient: boot continues only after the selected decrypted mapper content matches it.
This boundary does not individually attest the mounted file tree, OverlayFS upper layer, runtime mutations, or secrets after
unlock.
# 10. Failure Policy (fail-closed, deterministic) # 10. Failure Policy (fail-closed, deterministic)
* **ISO-edge abort:** no supported manifest, no supported verification tool, failed checksum, failed requested signature, or * **Abort** on: missing checksum manifest, unsupported checksum manifest/tool state, failed checksum, empty checksum manifest, missing rootfs attestation artifacts on the real ISO medium during `0024`, failed preservation of the runtime attestation cache, missing cached rootfs manifest/signature during `0042`, missing `VALIDSIG`, FPR mismatch, missing key/signature, malformed rootfs attestation manifest, or rootfs payload hash mismatch.
unknown verification state. * A signed rootfs manifest alone is not sufficient. Boot continues only after the manifest signature/FPR, and the decrypted SquashFS payload bytes both verify successfully.
* **Rootfs-attestation abort:** missing or malformed manifest/signature/key, missing `VALIDSIG`, FPR mismatch, manifest target * `dm-integrity` protects the opened LUKS mapping against sector corruption or tampering under the LUKS key, but it is not treated as origin authenticity. Origin authenticity is provided by the signed rootfs attestation manifest and pinned signer fingerprint.
mismatch, unreadable or non-block selected mapper, or mapper checksum mismatch.
# 11. CISS hardened and built dropbear # 11. CISS hardened and built dropbear
@@ -258,63 +322,77 @@ unlock.
* [9990-main.sh](../config/includes.chroot/usr/lib/live/boot/9990-main.sh), * [9990-main.sh](../config/includes.chroot/usr/lib/live/boot/9990-main.sh),
* [9990-networking.sh](../config/includes.chroot/usr/lib/live/boot/9990-networking.sh), * [9990-networking.sh](../config/includes.chroot/usr/lib/live/boot/9990-networking.sh),
* [9990-overlay.sh](../config/includes.chroot/usr/lib/live/boot/9990-overlay.sh). * [9990-overlay.sh](../config/includes.chroot/usr/lib/live/boot/9990-overlay.sh).
* **Hooks (boot view):** * **Hooks (initramfs boot view):**
* `/scripts/live-premount/0022-ciss-overlay-tmpfs`, * `/usr/lib/live/boot/0022-ciss-overlay-tmpfs`,
* `/scripts/live-premount/0024-ciss-crypt-squash`, * `/usr/lib/live/boot/0024-ciss-crypt-squash`,
* `/scripts/live-premount/0026-ciss-early-sysctl`, * `/usr/lib/live/boot/0026-ciss-early-sysctl`,
* `/scripts/live-bottom/0030-ciss-verify-checksums`, * `/usr/lib/live/boot/0030-ciss-verify-checksums`,
* `/scripts/live-bottom/0042-ciss-post-decrypt-attest` * `/usr/lib/live/boot/0042_ciss_post_decrypt_attest`,
* `/usr/lib/live/boot/9990-main.sh`,
* `/usr/lib/live/boot/9990-overlay.sh`
* **Key files:** * **Key files:**
* ISO edge (for 0030): embedded public key blob (project-specific FPR) * Mounted live medium (for 0030): embedded public key blob (project-specific FPR)
* Root FS (for 0042): `/etc/ciss/keys/<FPR>.gpg` * Root FS (for 0042): `/etc/ciss/keys/<FPR>.gpg`
* **Mounts (typical):** `/run/live/rootfs`, `/run/live/overlay` * **Rootfs attestation artifacts:**
* ISO payload paths: `/live/filesystem.squashfs.sha512sum.txt`, `/live/filesystem.squashfs.sha512sum.txt.sig`
* Runtime cache paths: `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt`, `/run/ciss-rootfs-attestation/filesystem.squashfs.sha512sum.txt.sig`
* Transient checksum file for exact mapper-byte verification: `/run/ciss-rootfs-attestation.sha512sum`
* **Runtime handoff state:** `/run/ciss-rootdev`
* **Mounts (typical):** `/run/live/medium`, `/run/live/rootfs`, `/run/live/overlay`
# 13. Diagram: CISS Live ISO Build, Boot, and Run Time Trust Chain & Verification Paths # 13. Diagram: CISS Live ISO Build, Boot, and Run Time Trust Chain & Verification Paths
```mermaid ```mermaid
flowchart TD flowchart TD
subgraph ISO Build Time subgraph ISO Build Time
A["Embed and pin GPG FPR (into ISO & RootFS as needed)"] e00@--> B["Generate ISO-edge sha512sum.txt and .sig"]; A["Embed and pin GPG FPR (into ISO & RootFS as needed)"] e00@--> B["Generate mounted-medium sha512sum.txt and .sig"];
B e01@--> C["Build filesystem.squashfs and wrap it into ciss_rootfs.crypt"]; B e01@--> C["Build filesystem.squashfs"];
C e01a@--> C2["Hash complete decrypted mapper and sign rootfs manifest"]; C e01b@--> C2["Generate rootfs attestation manifest and detached signature in binary/live"];
C2 e01c@--> C3["Copy filesystem.squashfs into ciss_rootfs.crypt and remove plaintext filesystem.squashfs"];
e00@{ animation: fast } e00@{ animation: fast }
e01@{ animation: fast } e01@{ animation: fast }
e01a@{ animation: fast } e01b@{ animation: fast }
e01c@{ animation: fast }
end end
subgraph ISO Boot Time subgraph ISO Boot Time
C2 e02@--> D["0024 LUKS2, dm-integrity HMAC-SHA512"]; C3 e02@--> D["0024 mounts real ISO medium and expects ciss_rootfs.crypt plus rootfs attestation files under /live"];
D e03@-->|SUCCESSFUL| E["ciss_rootfs.crypt opened"]; D e02b@--> DCACHE["0024 copies rootfs attestation files to /run/ciss-rootfs-attestation"];
E e04@--> F["Mounting RootFS"]; DCACHE e03@--> E["0024 opens ciss_rootfs.crypt with LUKS2/dm-integrity and exposes /dev/mapper/crypt_liveiso"];
F e05@--> G["0030 verification of authenticity and integrity via embedded and pinned GPG of ISO edge"]; E e04@--> F["0030 verifies mounted live-medium manifest, signature, FPR, and checksums"];
G e06@-->|SUCCESSFUL| H["ISO edge verified"]; F e05@-->|SUCCESSFUL| G["Mounted live medium verified"];
H e07@--> I["0042 verifies signed manifest and selected decrypted mapper"]; G e06@--> H["9990-overlay mounts SquashFS / OverlayFS"];
I e08@-->|SUCCESSFUL| J["RootFS attestation successful"]; H e07@--> I["0042 verifies cached rootfs attestation manifest and FPR"];
I e08@--> J["0042 verifies exact SquashFS bytes from /dev/mapper/crypt_liveiso"];
J e09@-->|SUCCESSFUL| K["RootFS SquashFS payload attestation successful"];
e02@{ animation: fast } e02@{ animation: fast }
e02b@{ animation: fast }
e03@{ animation: fast } e03@{ animation: fast }
e04@{ animation: fast } e04@{ animation: fast }
e05@{ animation: fast } e05@{ animation: fast }
e06@{ animation: fast } e06@{ animation: fast }
e07@{ animation: fast } e07@{ animation: fast }
e08@{ animation: fast } e08@{ animation: fast }
end
subgraph ISO Run Time
J e09@--> K{{"CISS.debian.live.builder ISO running"}};
X{{"CISS.debian.live.builder Boot process halted"}};
e09@{ animation: fast } e09@{ animation: fast }
end end
subgraph ISO Run Time
K e10@--> L{{"CISS.debian.live.builder ISO running"}};
X{{"CISS.debian.live.builder Boot process halted"}};
e10@{ animation: fast }
end
D -- FAIL --> X; D -- FAIL --> X;
G -- FAIL --> X; DCACHE -- FAIL --> X;
E -- FAIL --> X;
F -- FAIL --> X;
I -- FAIL --> X; I -- FAIL --> X;
J -- FAIL --> X;
``` ```
# 14. Closing Remarks # 14. Closing Remarks
The verification path is fail-closed and binds the selected decrypted rootfs mapper to the pinned signing key. `dm-integrity` This achieves a portable, self-contained trust chain without a Microsoft-db, providing strong protection at the mounted-medium and decrypted-rootfs-payload boundaries. The dual-verification phases make the state transparent and deterministic without treating `dm-integrity`, LUKS, or private infrastructure as substitutes for origin authenticity.
adds a separate sector-integrity property where enabled. The implemented attestation does not cover runtime OverlayFS changes,
post-unlock secrets, or an individually enumerated mounted file tree.
--- ---
**[no tracking | no logging | no advertising | no profiling | no bullshit](https://coresecret.eu/)** **[no tracking | no logging | no advertising | no profiling | no bullshit](https://coresecret.eu/)**
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. SSH Host Key Policy CISS.debian.live.builder / CISS.debian.installer # 2. SSH Host Key Policy CISS.debian.live.builder / CISS.debian.installer
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. Resources # 2. Resources
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. ``30-ciss-hardening.conf`` # 2. ``30-ciss-hardening.conf``
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. ``90-ciss-local.hardened`` # 2. ``90-ciss-local.hardened``
+1 -1
View File
@@ -8,7 +8,7 @@ include_toc: true
**Centurion Intelligence Consulting Agency Information Security Standard**<br> **Centurion Intelligence Consulting Agency Information Security Standard**<br>
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br> *Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
**Master Version**: 9.14<br> **Master Version**: 9.14<br>
**Build**: V9.14.022.2026.06.10<br> **Build**: V9.14.028.2026.06.18<br>
# 2. ``ciss_live_builder.sh`` # 2. ``ciss_live_builder.sh``
+60 -17
View File
@@ -57,7 +57,6 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
# None # None
# Returns: # Returns:
# ERR_ARG_MSMTCH: on failure # ERR_ARG_MSMTCH: on failure
# ERR_ARG_MSMTCH: on failure
# ERR_CONTROL_CT: on failure # ERR_CONTROL_CT: on failure
# ERR_DROPBEAR_V: on failure # ERR_DROPBEAR_V: on failure
# ERR_MISS_PWD_F: on failure # ERR_MISS_PWD_F: on failure
@@ -76,7 +75,6 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
# ERR__SSH__PORT: on failure # ERR__SSH__PORT: on failure
####################################### #######################################
arg_parser() { arg_parser() {
declare primordial_key_regex='^[A-Za-z0-9._@%+=:,~-]+$'
declare primordial_url_regex='^https://[A-Za-z0-9.-]+/[A-Za-z0-9._~/%+=:@,-]+\.git$' declare primordial_url_regex='^https://[A-Za-z0-9.-]+/[A-Za-z0-9._~/%+=:@,-]+\.git$'
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
@@ -109,6 +107,16 @@ arg_parser() {
shift 1 shift 1
;; ;;
-l | --logo)
if [[ -n "${2-}" && "${2}" != -* ]]; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
printf "\e[91m❌ Error: --logo MUST NOT be followed by an argument.\e[0m\n" >&2
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_ARG_MSMTCH}"
fi
shift 1
;;
-v | --version) -v | --version)
if [[ -n "${2-}" && "${2}" != -* ]]; then if [[ -n "${2-}" && "${2}" != -* ]]; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
@@ -134,10 +142,9 @@ arg_parser() {
;; ;;
--build-directory) --build-directory)
declare -gx VAR_HANDLER_BUILD_DIR="${2}" declare -gx VAR_HANDLER_BUILD_DIR="${2-}"
if [[ ! "${VAR_HANDLER_BUILD_DIR}" =~ ^/ ]]; then if ! validate_build_dir_argument "${VAR_HANDLER_BUILD_DIR}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
printf "\e[91m❌ Error: --build-directory MUST be an absolute path. Got: '%s'\n" "${VAR_HANDLER_BUILD_DIR}" >&2
exit "${ERR_NOTABSPATH}" exit "${ERR_NOTABSPATH}"
fi fi
declare -gx VAR_BUILD_LOG="${VAR_HANDLER_BUILD_DIR}/cdlb_${VAR_ISO8601}_build.log" declare -gx VAR_BUILD_LOG="${VAR_HANDLER_BUILD_DIR}/cdlb_${VAR_ISO8601}_build.log"
@@ -156,7 +163,7 @@ arg_parser() {
shift 1 shift 1
;; ;;
--change-splash ) --change-splash)
if [[ "${2}" == "club" || "${2}" == "hexagon" ]]; then if [[ "${2}" == "club" || "${2}" == "hexagon" ]]; then
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -g VAR_HANDLER_SPLASH="${2}" declare -g VAR_HANDLER_SPLASH="${2}"
@@ -266,18 +273,28 @@ arg_parser() {
;; ;;
--key_age=*) --key_age=*)
declare key_age="${1#*=}"
if ! validate_secret_filename "--key_age" "${key_age}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_AGE="true" declare -gx VAR_AGE="true"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_AGE_KEY="${1#*=}" declare -gx VAR_AGE_KEY="${key_age}"
shift 1 shift 1
;; ;;
--key_luks=*) --key_luks=*)
declare key_luks="${1#*=}"
if ! validate_secret_filename "--key_luks" "${key_luks}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_LUKS="true" declare -gx VAR_LUKS="true"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_LUKS_KEY="${1#*=}" declare -gx VAR_LUKS_KEY="${key_luks}"
shift 1 shift 1
;; ;;
@@ -296,7 +313,7 @@ arg_parser() {
--primordial-key) --primordial-key)
declare primordial_key="${2-}" declare primordial_key="${2-}"
if [[ -n "${primordial_key}" && "${primordial_key}" != -* && "${primordial_key}" != "." && "${primordial_key}" != ".." && "${primordial_key}" != */* && "${primordial_key}" =~ ${primordial_key_regex} ]]; then if validate_secret_filename "--primordial-key" "${primordial_key}"; then
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}" declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}"
@@ -315,7 +332,7 @@ arg_parser() {
--primordial-key=*) --primordial-key=*)
declare primordial_key="${1#*=}" declare primordial_key="${1#*=}"
if [[ -n "${primordial_key}" && "${primordial_key}" != "." && "${primordial_key}" != ".." && "${primordial_key}" != */* && "${primordial_key}" =~ ${primordial_key_regex} ]]; then if validate_secret_filename "--primordial-key" "${primordial_key}"; then
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}" declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}"
@@ -461,7 +478,7 @@ arg_parser() {
;; ;;
--root-password-file) --root-password-file)
declare pw_file="${2}" declare pw_file="${2-}"
if [[ -z "${pw_file}" ]]; then if [[ -z "${pw_file}" ]]; then
@@ -473,10 +490,9 @@ arg_parser() {
fi fi
if [[ ! -f "${pw_file}" ]]; then if ! validate_secret_absolute_file_basics "--root-password-file" "${pw_file}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
printf "\e[91m❌ Error: --root-password-file password file '%s' does not exist.\e[0m\n" "${pw_file}" >&2
# shellcheck disable=SC2162 # shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m' read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_MISS_PWD_F}" exit "${ERR_MISS_PWD_F}"
@@ -507,6 +523,13 @@ arg_parser() {
} }
fi fi
validate_secret_file_path "--root-password-file" "${pw_file}" || {
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
# shellcheck disable=SC2162
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
exit "${ERR_RGHT_PWD_F}"
}
declare plaintext_pw declare plaintext_pw
### No tracing for security reasons ---------------------------------------------------------------------------------- ### No tracing for security reasons ----------------------------------------------------------------------------------
[[ "${VAR_EARLY_DEBUG}" == "true" ]] && set +x [[ "${VAR_EARLY_DEBUG}" == "true" ]] && set +x
@@ -606,16 +629,26 @@ arg_parser() {
;; ;;
--signing_ca=*) --signing_ca=*)
declare signing_ca="${1#*=}"
if ! validate_secret_filename "--signing_ca" "${signing_ca}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_SIGNING_CA="${1#*=}" declare -gx VAR_SIGNING_CA="${signing_ca}"
shift 1 shift 1
;; ;;
--signing_key=*) --signing_key=*)
declare signing_key="${1#*=}"
if ! validate_secret_filename "--signing_key" "${signing_key}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_SIGNER="true" declare -gx VAR_SIGNER="true"
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_SIGNING_KEY="${1#*=}" declare -gx VAR_SIGNING_KEY="${signing_key}"
shift 1 shift 1
;; ;;
@@ -626,8 +659,13 @@ arg_parser() {
;; ;;
--signing_key_pass=*) --signing_key_pass=*)
declare signing_key_pass="${1#*=}"
if ! validate_secret_filename "--signing_key_pass" "${signing_key_pass}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_SIGNING_KEY_PASS="${1#*=}" declare -gx VAR_SIGNING_KEY_PASS="${signing_key_pass}"
shift 1 shift 1
;; ;;
@@ -694,8 +732,13 @@ arg_parser() {
;; ;;
--ssh-pubkey) --ssh-pubkey)
declare ssh_pubkey="${2-}"
if ! validate_ssh_pubkey_directory "${ssh_pubkey}"; then
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
exit "${ERR_ARG_MSMTCH}"
fi
# shellcheck disable=SC2034 # shellcheck disable=SC2034
declare -gx VAR_SSHPUBKEY="${2}" declare -gx VAR_SSHPUBKEY="${ssh_pubkey}"
shift 2 shift 2
;; ;;
+318
View File
@@ -0,0 +1,318 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-11; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2154
# Module overview:
# This module centralizes build-directory safety checks for path validation, builder-ownership markers, and destructive cleanup
# helpers. It keeps cleanup operations limited to canonical, explicitly validated build-directory paths.
#
# Function behavior:
# build_dir_safety_error(): writes a scoped build-directory safety error message to stderr.
# reject_broad_build_dir_path(): rejects the filesystem root and common top-level system directories as build targets.
# validate_build_dir_argument(): validates a non-empty absolute build-directory argument before the path is created.
# validate_existing_build_dir(): validates the argument and confirms that it resolves to an existing directory.
# require_builder_owned_build_dir(): requires a validated directory with a safe root-owned builder marker.
# ensure_builder_owned_build_dir(): creates the marker for a safe empty build directory or verifies an existing marker.
# require_builder_owned_subpath(): confirms that a target exists strictly below a verified builder-owned directory.
# safe_clean_build_dir_contents(): removes direct build-directory contents while preserving the builder marker.
# safe_remove_builder_subpath(): removes one verified subpath below a builder-owned build directory.
guard_sourcing || return "${ERR_GUARD_SRCE}"
#######################################
# Print a cleanup/path safety error.
# Globals:
# None
# Arguments:
# 1: Error detail.
# Returns:
# 0: on success
#######################################
build_dir_safety_error() {
declare detail="${1}"
printf "\e[91m❌ build directory safety: %s \e[0m\n" "${detail}" >&2
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f build_dir_safety_error
#######################################
# Reject broad parent directories as build-directory targets.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Canonical path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
reject_broad_build_dir_path() {
declare canonical_path="${1}"
case "${canonical_path}" in
"" | "/" | "/bin" | "/boot" | "/dev" | "/etc" | "/home" | "/lib" | "/lib64" | "/opt" | "/proc" | "/root" | "/run" | "/sbin" | "/sys" | "/tmp" | "/usr" | "/var")
build_dir_safety_error "refusing broad path."
return "${ERR_INVLD_CHAR}"
;;
*)
;;
esac
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f reject_broad_build_dir_path
#######################################
# Validate a build-directory argument before it is created.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Build directory path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_build_dir_argument() {
declare build_dir="${1}" canonical_path=""
if [[ -z "${build_dir}" ]]; then
build_dir_safety_error "path MUST NOT be empty."
return "${ERR_INVLD_CHAR}"
fi
if [[ "${build_dir}" != /* ]]; then
build_dir_safety_error "path MUST be absolute."
return "${ERR_INVLD_CHAR}"
fi
if [[ -L "${build_dir}" ]]; then
build_dir_safety_error "path MUST NOT be a symlink."
return "${ERR_INVLD_CHAR}"
fi
canonical_path="$(realpath -m -- "${build_dir}")"
reject_broad_build_dir_path "${canonical_path}" || return "${?}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_build_dir_argument
#######################################
# Canonicalize and validate an existing build directory.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Build directory path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_existing_build_dir() {
declare build_dir="${1}" canonical_path=""
validate_build_dir_argument "${build_dir}" || return "${?}"
if [[ ! -d "${build_dir}" ]]; then
build_dir_safety_error "path MUST be an existing directory."
return "${ERR_INVLD_CHAR}"
fi
canonical_path="$(realpath -e -- "${build_dir}")"
reject_broad_build_dir_path "${canonical_path}" || return "$?"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_existing_build_dir
#######################################
# Validate the builder-owned marker in a build directory.
# Globals:
# CISS_BUILD_DIR_MARKER
# ERR_INVLD_CHAR
# Arguments:
# 1: Build directory path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
require_builder_owned_build_dir() {
declare build_dir="${1}" canonical_path="" marker_path="" marker_owner="" marker_mode="" marker_mode_octal=""
validate_existing_build_dir "${build_dir}" || return "$?"
canonical_path="$(realpath -e -- "${build_dir}")"
marker_path="${canonical_path}/${CISS_BUILD_DIR_MARKER}"
if [[ -L "${marker_path}" || ! -f "${marker_path}" ]]; then
build_dir_safety_error "builder-owned marker is missing or unsafe."
return "${ERR_INVLD_CHAR}"
fi
marker_owner="$(stat -c '%u:%g' -- "${marker_path}")"
if [[ "${marker_owner}" != "0:0" ]]; then
build_dir_safety_error "builder-owned marker MUST be owned by root:root."
return "${ERR_INVLD_CHAR}"
fi
marker_mode="$(stat -c '%a' -- "${marker_path}")"
marker_mode_octal=$((8#${marker_mode}))
if (( (marker_mode_octal & 022) != 0 )); then
build_dir_safety_error "builder-owned marker MUST NOT be group- or world-writable."
return "${ERR_INVLD_CHAR}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f require_builder_owned_build_dir
#######################################
# Create or preserve the builder-owned marker.
# Globals:
# CISS_BUILD_DIR_MARKER
# ERR_INVLD_CHAR
# Arguments:
# 1: Build directory path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
ensure_builder_owned_build_dir() {
declare build_dir="${1}" canonical_path="" marker_path=""
validate_existing_build_dir "${build_dir}" || return "${?}"
canonical_path="$(realpath -e -- "${build_dir}")"
marker_path="${canonical_path}/${CISS_BUILD_DIR_MARKER}"
if [[ -e "${marker_path}" || -L "${marker_path}" ]]; then
require_builder_owned_build_dir "${canonical_path}" || return "${?}"
return 0
fi
if [[ -d "${canonical_path}/.build" ]]; then
build_dir_safety_error "existing live-build state lacks the builder-owned marker."
return "${ERR_INVLD_CHAR}"
fi
install -m 0600 -o root -g root /dev/null "${marker_path}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f ensure_builder_owned_build_dir
#######################################
# Validate that a target path is strictly below a builder-owned build directory.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Build directory path.
# 2: Target-path below the build directory.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
require_builder_owned_subpath() {
declare build_dir="${1}" target_path="${2}" build_real="" target_real=""
require_builder_owned_build_dir "${build_dir}" || return "$?"
if [[ -z "${target_path}" || -L "${target_path}" || ! -e "${target_path}" ]]; then
build_dir_safety_error "target subpath is empty, missing, or a symlink."
return "${ERR_INVLD_CHAR}"
fi
build_real="$(realpath -e -- "${build_dir}")"
target_real="$(realpath -e -- "${target_path}")"
if [[ "${target_real}" == "${build_real}" ]]; then
build_dir_safety_error "target subpath MUST NOT be the build directory itself."
return "${ERR_INVLD_CHAR}"
fi
case "${target_real}" in
"${build_real}"/*)
;;
*)
build_dir_safety_error "target subpath MUST stay below the build directory."
return "${ERR_INVLD_CHAR}"
;;
esac
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f require_builder_owned_subpath
#######################################
# Remove all contents of the exact builder-owned build directory.
# Globals:
# CISS_BUILD_DIR_MARKER
# Arguments:
# 1: Build directory path.
# Returns:
# 0: on success
# Non-zero: on failure
#######################################
safe_clean_build_dir_contents() {
declare build_dir="${1}" build_real=""
require_builder_owned_build_dir "${build_dir}" || return "${?}"
build_real="$(realpath -e -- "${build_dir}")"
find "${build_real}" -mindepth 1 -maxdepth 1 -xdev ! -name "${CISS_BUILD_DIR_MARKER}" -exec rm -rf --one-file-system -- {} +
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f safe_clean_build_dir_contents
#######################################
# Remove one exact builder-owned subpath.
# Globals:
# None
# Arguments:
# 1: Build-directory-path.
# 2: Target-path below build-directory.
# Returns:
# 0: on success
# Non-zero: on failure
#######################################
safe_remove_builder_subpath() {
declare build_dir="${1}" target_path="${2}" target_real=""
require_builder_owned_subpath "${build_dir}" "${target_path}" || return "${?}"
target_real="$(realpath -e -- "${target_path}")"
rm -rf --one-file-system -- "${target_real}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f safe_remove_builder_subpath
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
+6 -2
View File
@@ -33,12 +33,16 @@ x_remove() {
shopt -s nullglob dotglob shopt -s nullglob dotglob
### Collect exact currently available secret values before removing their source files.
### Log rewriting is intentionally deferred to the final trap after xtrace has been stopped.
collect_debug_secret_values || true
if [[ "${VAR_SIGNER}" == "true" ]]; then if [[ "${VAR_SIGNER}" == "true" ]]; then
# shellcheck disable=SC2312 # shellcheck disable=SC2312
find "${VAR_TMP_SECRET}" -xdev -type f \ find "${VAR_TMP_SECRET}" -xdev -type f \
! -path "${VAR_TMP_SECRET}/signing_key_pass.txt" \ ! -path "${VAR_TMP_SECRET}/${VAR_SIGNING_KEY_PASS:-signing_key_pass.txt}" \
! -path "${VAR_TMP_SECRET}/luks.txt" \ ! -path "${VAR_TMP_SECRET}/${VAR_LUKS_KEY:-luks.txt}" \
-print0 \ -print0 \
| xargs -0 --no-run-if-empty shred -fzu -n 5 -- | xargs -0 --no-run-if-empty shred -fzu -n 5 --
+6 -1
View File
@@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# shellcheck disable=SC2154
# SPDX-Version: 3.0 # SPDX-Version: 3.0
# SPDX-CreationInfo: 2025-11-12; WEIDNER, Marc S.; <msw@coresecret.dev> # SPDX-CreationInfo: 2025-11-12; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
@@ -9,14 +10,15 @@
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework. # SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder # SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu # SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2154
guard_sourcing || return "${ERR_GUARD_SRCE}" guard_sourcing || return "${ERR_GUARD_SRCE}"
####################################### #######################################
# Integrates and generates sha512sum and GPG signatures on CISS specific LIVE boot artifacts: # Integrates and generates sha512sum and GPG signatures on CISS specific LIVE boot artifacts:
# - /root/.ciss/attestation/VAR_SIGNING_KEY_FPR.* legacy-signed public-key copy, not rootfs content attestation
# - /etc/initramfs-tools/files/unlock_wrapper.sh # - /etc/initramfs-tools/files/unlock_wrapper.sh
# - /usr/lib/live/boot/0030-ciss-verify-checksums # - /usr/lib/live/boot/0030-ciss-verify-checksums
# Rootfs content attestation for the final SquashFS payload is generated by zzzz_ciss_crypt_squash.hook.binary.
# Globals: # Globals:
# BASH_SOURCE # BASH_SOURCE
# VAR_HANDLER_BUILD_DIR # VAR_HANDLER_BUILD_DIR
@@ -31,7 +33,10 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
ciss_upgrades_boot() { ciss_upgrades_boot() {
printf "\e[95m🧪 %s starting ... \e[0m\n" "${BASH_SOURCE[0]}" printf "\e[95m🧪 %s starting ... \e[0m\n" "${BASH_SOURCE[0]}"
gpg --batch --yes --export "${VAR_SIGNING_KEY_FPR}" >| "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ciss/attestation/${VAR_SIGNING_KEY_FPR}.gpg"
declare -ar _ary_target=( declare -ar _ary_target=(
"/root/.ciss/attestation/${VAR_SIGNING_KEY_FPR}.gpg"
"/etc/initramfs-tools/files/unlock_wrapper.sh" "/etc/initramfs-tools/files/unlock_wrapper.sh"
"/usr/lib/live/boot/0030-ciss-verify-checksums" "/usr/lib/live/boot/0030-ciss-verify-checksums"
) )
+30 -15
View File
@@ -33,6 +33,7 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
####################################### #######################################
clean_up() { clean_up() {
declare clean_exit_code="$1" fs_type="" _old_nullglob="" _old_dotglob="" _old_failglob="" declare clean_exit_code="$1" fs_type="" _old_nullglob="" _old_dotglob="" _old_failglob=""
declare build_dir_valid="false" includes_chroot=""
### Enable nullglob/dotglob, disable failglob for safe globbing. ### Enable nullglob/dotglob, disable failglob for safe globbing.
_old_nullglob="$(shopt -p nullglob || true)" _old_nullglob="$(shopt -p nullglob || true)"
@@ -52,10 +53,10 @@ clean_up() {
rm -f -- "${VAR_NOTES}" rm -f -- "${VAR_NOTES}"
### Release advisory lock on FD 127. ### Release advisory lock on FD 127.
flock -u 127 flock -u 127 2>/dev/null || true
### Close file descriptor 127. ### Close file descriptor 127.
exec 127>&- exec 127>&- 2>/dev/null || true
### Remove the lockfile artifact. ### Remove the lockfile artifact.
rm -f /run/lock/ciss_live_builder.lock rm -f /run/lock/ciss_live_builder.lock
@@ -100,32 +101,46 @@ clean_up() {
### No tracing for security reasons ------------------------------------------------------------------------------------------ ### No tracing for security reasons ------------------------------------------------------------------------------------------
[[ "${VAR_EARLY_DEBUG}" == "true" ]] && set +x [[ "${VAR_EARLY_DEBUG}" == "true" ]] && set +x
### Removes secrets securely. ### Stop xtrace before destructive cleanup and collect still-available exact secret values.
# shellcheck disable=SC2312 ### The final log rewrite runs later from the trap after no further debug/error log writes are expected.
find "${VAR_TMP_SECRET}" -xdev -type f -print0 | xargs -0 --no-run-if-empty shred -fzu -n 5 -- finalize_debug_xtrace_logging || true
find "${VAR_TMP_SECRET}" -xdev -depth -type d -empty -delete collect_debug_secret_values || true
### Securely shred all regular files below ./includes.chroot, then remove empty dirs. ### Removes secrets securely.
if [[ -d "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot" ]]; then if [[ -n "${VAR_TMP_SECRET:-}" && -d "${VAR_TMP_SECRET}" && ! -L "${VAR_TMP_SECRET}" ]]; then
# shellcheck disable=SC2312 # shellcheck disable=SC2312
find "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot" -xdev -type f -print0 | xargs -0 --no-run-if-empty shred -fzu -n 5 -- find "${VAR_TMP_SECRET}" -xdev -type f -print0 | xargs -0 --no-run-if-empty shred -fzu -n 5 -- || true
find "${VAR_TMP_SECRET}" -xdev -depth -type d -empty -delete || true
fi
if [[ -n "${VAR_HANDLER_BUILD_DIR:-}" && -d "${VAR_HANDLER_BUILD_DIR}" ]]; then
if require_builder_owned_build_dir "${VAR_HANDLER_BUILD_DIR}"; then
build_dir_valid="true"
fi
fi
### Securely shred all regular files below ./includes.chroot, then remove empty dirs.
includes_chroot="${VAR_HANDLER_BUILD_DIR:-}/config/includes.chroot"
if [[ "${build_dir_valid}" == "true" && -d "${includes_chroot}" ]] \
&& require_builder_owned_subpath "${VAR_HANDLER_BUILD_DIR}" "${includes_chroot}"; then
# shellcheck disable=SC2312
find "${includes_chroot}" -xdev -type f -print0 | xargs -0 --no-run-if-empty shred -fzu -n 5 -- || true
### Remove empty directories (bottom-up). ### Remove empty directories (bottom-up).
find "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot" -depth -xdev -type d -empty -delete find "${includes_chroot}" -depth -xdev -type d -empty -delete || true
fi fi
### Delete all files and directories below ./chroot. ### Delete all files and directories below ./chroot.
if [[ -d "${VAR_HANDLER_BUILD_DIR}/chroot" ]]; then if [[ "${build_dir_valid}" == "true" && -d "${VAR_HANDLER_BUILD_DIR}/chroot" ]]; then
rm -rf "${VAR_HANDLER_BUILD_DIR}/chroot" safe_remove_builder_subpath "${VAR_HANDLER_BUILD_DIR}" "${VAR_HANDLER_BUILD_DIR}/chroot" || true
fi fi
### Turn on tracing again ----------------------------------------------------------------------------------------------------
[[ "${VAR_EARLY_DEBUG}" == "true" ]] && set -x
eval "${_old_nullglob}" 2>/dev/null || true eval "${_old_nullglob}" 2>/dev/null || true
eval "${_old_dotglob}" 2>/dev/null || true eval "${_old_dotglob}" 2>/dev/null || true
eval "${_old_failglob}" 2>/dev/null || true eval "${_old_failglob}" 2>/dev/null || true
+297
View File
@@ -0,0 +1,297 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-11; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2154
# Function behavior:
# debug_sanitize_escape_glob(): Escape Bash glob metacharacters so exact values can be used safely in parameter-substitution matches.
# debug_sanitize_read_file(): Read a text file into a named variable while preserving trailing newline bytes.
# debug_sanitize_add_secret(): Add one non-empty exact secret value to the in-memory redaction list, avoiding duplicates.
# debug_sanitize_add_secret_file(): Add the exact content of a regular, non-symlink secret file to the redaction list.
# debug_sanitize_collect_secrets(): Add controlled secret variables and secret-file contents to the redaction list.
# collect_debug_secret_values(): Collect exact secret values while xtrace is temporarily disabled.
# finalize_debug_xtrace_logging(): Permanently disable xtrace and close the xtrace log FD before rewriting logs.
# debug_sanitize_log_file(): Redact collected exact secret values from one log file and restrict its permissions.
# sanitize_debug_logs(): Run the final exact-value sanitization pass across closed debug, variable, and error logs.
guard_sourcing || return "${ERR_GUARD_SRCE}"
declare -ga _ARY_DEBUG_SECRET_VALUES=()
declare -g _VAR_DEBUG_XTRACE_FINALIZED="false"
#######################################
# Escape Bash glob metacharacters for exact parameter-substitution matching.
# Globals:
# None
# Arguments:
# 1: Raw value.
# Returns:
# 0: on success
#######################################
debug_sanitize_escape_glob() {
declare value="${1}"
value="${value//\\/\\\\}"
value="${value//\*/\\*}"
value="${value//\?/\\?}"
value="${value//\[/\\[}"
value="${value//\]/\\]}"
printf '%s' "${value}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_escape_glob
#######################################
# Read a text file into a variable, preserving trailing newlines.
# Globals:
# None
# Arguments:
# 1: File path.
# 2: Output variable name.
# Returns:
# 0: on success
#######################################
debug_sanitize_read_file() {
declare file_path="${1}" output_var="${2}" content=""
IFS= read -r -d '' content < "${file_path}" || true
printf -v "${output_var}" '%s' "${content}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_read_file
#######################################
# Add one exact secret value to the redaction list.
# Globals:
# _ARY_DEBUG_SECRET_VALUES
# Arguments:
# 1: Secret value.
# Returns:
# 0: on success
#######################################
debug_sanitize_add_secret() {
declare secret_value="${1}" known_value=""
[[ -n "${secret_value}" ]] || return 0
for known_value in "${_ARY_DEBUG_SECRET_VALUES[@]:-}"; do
[[ "${known_value}" == "${secret_value}" ]] && return 0
done
_ARY_DEBUG_SECRET_VALUES+=("${secret_value}")
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_add_secret
#######################################
# Add a secret file's exact content to the redaction list.
# Globals:
# _ARY_DEBUG_SECRET_VALUES
# Arguments:
# 1: File path.
# Returns:
# 0: on success
#######################################
debug_sanitize_add_secret_file() {
declare file_path="${1}" secret_value=""
[[ -n "${file_path}" && -f "${file_path}" && ! -L "${file_path}" ]] || return 0
[[ -s "${file_path}" ]] || return 0
debug_sanitize_read_file "${file_path}" secret_value
debug_sanitize_add_secret "${secret_value}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_add_secret_file
#######################################
# Gather exact values from controlled secret variables and files.
# Globals:
# _ARY_DEBUG_SECRET_VALUES
# VAR_HASHED_PWD
# VAR_SIGNING_KEY_PASSFILE
# VAR_TMP_SECRET
# Arguments:
# None
# Returns:
# 0: on success
#######################################
debug_sanitize_collect_secrets() {
declare secret_file=""
if [[ -n "${VAR_HASHED_PWD:-}" ]]; then
debug_sanitize_add_secret "${VAR_HASHED_PWD}"
fi
if [[ -n "${VAR_SIGNING_KEY_PASSFILE:-}" ]]; then
debug_sanitize_add_secret_file "${VAR_SIGNING_KEY_PASSFILE}"
fi
if [[ -n "${VAR_TMP_SECRET:-}" && -d "${VAR_TMP_SECRET}" && ! -L "${VAR_TMP_SECRET}" ]]; then
while IFS= read -r -d '' secret_file; do
debug_sanitize_add_secret_file "${secret_file}"
done < <(find "${VAR_TMP_SECRET}" -xdev -type f -print0 2>/dev/null || true)
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_collect_secrets
#######################################
# Collect exact secret values without tracing secret-bearing operations.
# Globals:
# _VAR_DEBUG_XTRACE_FINALIZED
# Arguments:
# None
# Returns:
# 0: on success
#######################################
collect_debug_secret_values() {
declare tracing_was_enabled="false"
case "$-" in
*x*)
tracing_was_enabled="true"
set +x
;;
*)
;;
esac
debug_sanitize_collect_secrets || true
if [[ "${tracing_was_enabled}" == "true" && "${_VAR_DEBUG_XTRACE_FINALIZED}" != "true" ]]; then
set -x
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f collect_debug_secret_values
#######################################
# Permanently stop xtrace logging before the final log rewrite.
# Globals:
# BASH_XTRACEFD
# _VAR_DEBUG_XTRACE_FINALIZED
# Arguments:
# None
# Returns:
# 0: on success
#######################################
finalize_debug_xtrace_logging() {
declare xtrace_fd=""
set +x
if [[ "${BASH_XTRACEFD:-}" =~ ^[0-9]+$ ]]; then
xtrace_fd="${BASH_XTRACEFD}"
unset BASH_XTRACEFD
if (( xtrace_fd > 2 )); then
exec {xtrace_fd}>&- 2>/dev/null || true
fi
fi
_VAR_DEBUG_XTRACE_FINALIZED="true"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f finalize_debug_xtrace_logging
#######################################
# Redact exact secret values from one log file.
# Globals:
# _ARY_DEBUG_SECRET_VALUES
# Arguments:
# 1: Log file path.
# Returns:
# 0: on success
#######################################
debug_sanitize_log_file() {
declare log_file="${1}" log_content="" secret_value="" secret_pattern="" redaction=""
declare -i secret_len=0
[[ -n "${log_file}" && -f "${log_file}" && ! -L "${log_file}" ]] || return 0
debug_sanitize_read_file "${log_file}" log_content
for secret_value in "${_ARY_DEBUG_SECRET_VALUES[@]:-}"; do
[[ -n "${secret_value}" ]] || continue
secret_pattern="$(debug_sanitize_escape_glob "${secret_value}")"
secret_len="${#secret_value}"
printf -v redaction '%*s' "${secret_len}" ''
redaction="${redaction// /*}"
log_content="${log_content//${secret_pattern}/${redaction}}"
done
printf '%s' "${log_content}" >| "${log_file}"
chmod 0600 "${log_file}" 2>/dev/null || true
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f debug_sanitize_log_file
#######################################
# Final exact-value debug log sanitization pass.
# Globals:
# LOG_DEBUG
# LOG_ERROR
# LOG_VAR
# Arguments:
# None
# Returns:
# 0: on success
#######################################
sanitize_debug_logs() {
declare old_lc_all="${LC_ALL:-}" log_file=""
finalize_debug_xtrace_logging || true
LC_ALL=C
debug_sanitize_collect_secrets || true
for log_file in "${LOG_DEBUG:-}" "${LOG_VAR:-}" "${LOG_ERROR:-}"; do
debug_sanitize_log_file "${log_file}" || true
done
LC_ALL="${old_lc_all}"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f sanitize_debug_logs
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
+7 -1
View File
@@ -72,9 +72,15 @@ EOF
fi fi
### Use pubring as verification keyring reference. ### Use pubring as a verification keyring reference.
declare -grx VAR_VERIFY_KEYRING="${GNUPGHOME}/pubring.kbx" declare -grx VAR_VERIFY_KEYRING="${GNUPGHOME}/pubring.kbx"
validate_secret_file_in_root "--signing_key" "${VAR_SIGNING_KEY}" || return "${?}"
validate_secret_file_in_root "--signing_key_pass" "${VAR_SIGNING_KEY_PASS}" || return "${?}"
if [[ -n "${VAR_SIGNING_CA}" ]]; then
validate_secret_file_in_root "--signing_ca" "${VAR_SIGNING_CA}" || return "${?}"
fi
declare -grx VAR_SIGNING_KEY_PASSFILE="${VAR_TMP_SECRET}/${VAR_SIGNING_KEY_PASS}" declare -grx VAR_SIGNING_KEY_PASSFILE="${VAR_TMP_SECRET}/${VAR_SIGNING_KEY_PASS}"
### No tracing for security reasons ------------------------------------------------------------------------------------------ ### No tracing for security reasons ------------------------------------------------------------------------------------------
+1
View File
@@ -182,6 +182,7 @@ hardening_ultra() {
printf "\e[95m🧪 Updating SSH Keys, Ports ... \e[0m\n" printf "\e[95m🧪 Updating SSH Keys, Ports ... \e[0m\n"
### ./config/includes.chroot/root/.ssh --------------------------------------------------------------------------------------- ### ./config/includes.chroot/root/.ssh ---------------------------------------------------------------------------------------
validate_ssh_pubkey_directory "${VAR_SSHPUBKEY}" || return "${?}"
install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
install -m 0600 -o root -g root "${VAR_SSHPUBKEY}/authorized_keys" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/" install -m 0600 -o root -g root "${VAR_SSHPUBKEY}/authorized_keys" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/"
+3 -5
View File
@@ -30,12 +30,14 @@ lb_config_start() {
mkdir -p "${VAR_HANDLER_BUILD_DIR}" mkdir -p "${VAR_HANDLER_BUILD_DIR}"
# shellcheck disable=SC2164 # shellcheck disable=SC2164
cd "${VAR_HANDLER_BUILD_DIR}" cd "${VAR_HANDLER_BUILD_DIR}"
ensure_builder_owned_build_dir "${VAR_HANDLER_BUILD_DIR}"
printf "\e[92m✅ '%s' created. \e[0m\n" "${VAR_HANDLER_BUILD_DIR}" printf "\e[92m✅ '%s' created. \e[0m\n" "${VAR_HANDLER_BUILD_DIR}"
else else
# shellcheck disable=SC2164 # shellcheck disable=SC2164
cd "${VAR_HANDLER_BUILD_DIR}" cd "${VAR_HANDLER_BUILD_DIR}"
ensure_builder_owned_build_dir "${VAR_HANDLER_BUILD_DIR}"
fi fi
@@ -48,11 +50,7 @@ lb_config_start() {
lb clean --binary --cache --purge --source lb clean --binary --cache --purge --source
if [[ "${PWD}" == "${VAR_HANDLER_BUILD_DIR}" && "${PWD}" != "/" && -n "${PWD}" ]]; then safe_clean_build_dir_contents "${VAR_HANDLER_BUILD_DIR}"
rm -rf -- ./* ./.??*
fi
printf "\e[92m✅ Deleting former config, binary and cache done.\e[0m\n" printf "\e[92m✅ Deleting former config, binary and cache done.\e[0m\n"
+14
View File
@@ -84,6 +84,8 @@ init_primordial() {
### Check for SOPS AGE key integration --------------------------------------------------------------------------------------- ### Check for SOPS AGE key integration ---------------------------------------------------------------------------------------
if [[ "${VAR_AGE,,}" == "true" ]]; then if [[ "${VAR_AGE,,}" == "true" ]]; then
validate_secret_file_in_root "--key_age" "${VAR_AGE_KEY}" || return "$?"
install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.config/sops/age" install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.config/sops/age"
install -m 0400 "${VAR_TMP_SECRET}/${VAR_AGE_KEY}" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.config/sops/age/keys.txt" install -m 0400 "${VAR_TMP_SECRET}/${VAR_AGE_KEY}" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.config/sops/age/keys.txt"
shred -fzu -n 5 -- "${VAR_TMP_SECRET}/${VAR_AGE_KEY}" 2>/dev/null || rm -f "${VAR_TMP_SECRET}/${VAR_AGE_KEY}" shred -fzu -n 5 -- "${VAR_TMP_SECRET}/${VAR_AGE_KEY}" 2>/dev/null || rm -f "${VAR_TMP_SECRET}/${VAR_AGE_KEY}"
@@ -93,6 +95,18 @@ init_primordial() {
### Check for SSH CISS and PhysNet Primordial-Workflow™ integration ------------------------------------------------------- ### Check for SSH CISS and PhysNet Primordial-Workflow™ integration -------------------------------------------------------
if [[ "${VAR_SSHFP,,}" == "true" ]]; then if [[ "${VAR_SSHFP,,}" == "true" ]]; then
# shellcheck disable=SC2312
if find "${VAR_TMP_SECRET}" -xdev \( -name 'id*' -o -name 'ssh_host_*' \) -type l -print -quit | grep -q .; then
printf "\e[91m❌ ERROR: SSH identity and host key inputs MUST NOT be symlinks. \e[0m\n" >&2
return "${ERR_INVLD_CHAR}"
fi
# shellcheck disable=SC2312
if find "${VAR_TMP_SECRET}" -xdev \( -name 'id*' -o -name 'ssh_host_*' \) ! -type f -print -quit | grep -q .; then
printf "\e[91m❌ ERROR: SSH identity and host key inputs MUST be regular files. \e[0m\n" >&2
return "${ERR_INVLD_CHAR}"
fi
install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
install -m 0600 "${VAR_TMP_SECRET}/id"* "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/" install -m 0600 "${VAR_TMP_SECRET}/id"* "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh/"
normalize_ssh_keys_in_dir "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh" normalize_ssh_keys_in_dir "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
+406
View File
@@ -0,0 +1,406 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-CreationInfo: 2026-06-11; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git
# SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency
# SPDX-FileCopyrightText: 2024-2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework.
# SPDX-PackageName: CISS.debian.live.builder
# SPDX-Security-Contact: security@coresecret.eu
# shellcheck disable=SC2154
guard_sourcing || return "${ERR_GUARD_SRCE}"
#######################################
# Print a validation error without echoing secret values.
# Globals:
# None
# Arguments:
# 1: Validation label.
# 2: Error detail.
# Returns:
# 0: on success
#######################################
secret_validation_error() {
declare label="$1" detail="$2"
printf "\e[91mERROR: %s: %s\e[0m\n" "${label}" "${detail}" >&2
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f secret_validation_error
#######################################
# Validate a filename-only secret argument.
# Globals:
# ERR_ARG_MSMTCH
# Arguments:
# 1: Validation label.
# 2: Filename.
# Returns:
# 0: on success
# ERR_ARG_MSMTCH: on failure
#######################################
validate_secret_filename() {
declare label="$1" filename="$2"
declare filename_regex='^[A-Za-z0-9._@%+=:,~-]+$'
if [[ -z "${filename}" ]]; then
secret_validation_error "${label}" "filename MUST NOT be empty."
return "${ERR_ARG_MSMTCH}"
fi
if [[ "${filename}" == "." || "${filename}" == ".." ]]; then
secret_validation_error "${label}" "filename MUST NOT be '.' or '..'."
return "${ERR_ARG_MSMTCH}"
fi
if [[ "${filename}" == -* ]]; then
secret_validation_error "${label}" "filename MUST NOT start with '-'."
return "${ERR_ARG_MSMTCH}"
fi
if [[ "${filename}" == */* || "${filename}" == *\\* ]]; then
secret_validation_error "${label}" "filename MUST NOT contain path separators."
return "${ERR_ARG_MSMTCH}"
fi
if [[ ! "${filename}" =~ ${filename_regex} ]]; then
secret_validation_error "${label}" "filename contains unsupported characters."
return "${ERR_ARG_MSMTCH}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_secret_filename
#######################################
# Validate the fixed tmpfs secret root.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Secret root path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_secret_root() {
declare secret_root="$1" root_owner="" root_mode="" root_mode_octal="" root_fs=""
if [[ -z "${secret_root}" ]]; then
secret_validation_error "secret root" "path MUST NOT be empty."
return "${ERR_INVLD_CHAR}"
fi
if [[ -L "${secret_root}" ]]; then
secret_validation_error "secret root" "path MUST NOT be a symlink."
return "${ERR_INVLD_CHAR}"
fi
if [[ ! -d "${secret_root}" ]]; then
secret_validation_error "secret root" "path MUST be an existing directory."
return "${ERR_INVLD_CHAR}"
fi
root_owner="$(stat -c '%u:%g' -- "${secret_root}")"
if [[ "${root_owner}" != "0:0" ]]; then
secret_validation_error "secret root" "directory MUST be owned by root:root."
return "${ERR_INVLD_CHAR}"
fi
root_mode="$(stat -c '%a' -- "${secret_root}")"
root_mode_octal=$((8#${root_mode}))
if (( (root_mode_octal & 077) != 0 || (root_mode_octal & 0700) != 0700 )); then
secret_validation_error "secret root" "directory mode MUST be 0700 or stricter."
return "${ERR_INVLD_CHAR}"
fi
root_fs="$(stat -f -c '%T' -- "${secret_root}")"
if [[ "${root_fs}" != "tmpfs" && "${root_fs}" != "ramfs" ]]; then
secret_validation_error "secret root" "directory MUST be backed by tmpfs or ramfs."
return "${ERR_INVLD_CHAR}"
fi
# shellcheck disable=SC2312
if find "${secret_root}" -xdev -type l -print -quit | grep -q .; then
secret_validation_error "secret root" "secret tree MUST NOT contain symlinks."
return "${ERR_INVLD_CHAR}"
fi
# shellcheck disable=SC2312
if find "${secret_root}" -xdev \( -type b -o -type c -o -type p -o -type s \) -print -quit | grep -q .; then
secret_validation_error "secret root" "secret tree MUST NOT contain special files."
return "${ERR_INVLD_CHAR}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_secret_root
#######################################
# Normalize ownership and mode of regular files in the secret root.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Secret root path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
harden_secret_root_files() {
declare secret_root="$1"
validate_secret_root "${secret_root}" || return "$?"
find "${secret_root}" -xdev -type f -exec chown root:root -- {} +
find "${secret_root}" -xdev -type f -exec chmod 0400 -- {} +
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f harden_secret_root_files
#######################################
# Validate that an existing absolute path is a regular non-symlink file.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Validation label.
# 2: File path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_secret_absolute_file_basics() {
declare label="$1" file_path="$2"
if [[ -z "${file_path}" ]]; then
secret_validation_error "${label}" "file path MUST NOT be empty."
return "${ERR_INVLD_CHAR}"
fi
if [[ "${file_path}" != /* ]]; then
secret_validation_error "${label}" "file path MUST be absolute."
return "${ERR_INVLD_CHAR}"
fi
if [[ -L "${file_path}" ]]; then
secret_validation_error "${label}" "file MUST NOT be a symlink."
return "${ERR_INVLD_CHAR}"
fi
if [[ ! -f "${file_path}" ]]; then
secret_validation_error "${label}" "file MUST be an existing regular file."
return "${ERR_INVLD_CHAR}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_secret_absolute_file_basics
#######################################
# Validate a strict secret file.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Validation label.
# 2: File path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_secret_file_path() {
declare label="$1" file_path="$2" file_owner="" file_mode="" file_mode_octal=""
validate_secret_absolute_file_basics "${label}" "${file_path}" || return "$?"
file_owner="$(stat -c '%u:%g' -- "${file_path}")"
if [[ "${file_owner}" != "0:0" ]]; then
secret_validation_error "${label}" "file MUST be owned by root:root."
return "${ERR_INVLD_CHAR}"
fi
file_mode="$(stat -c '%a' -- "${file_path}")"
file_mode_octal=$((8#${file_mode}))
if (( (file_mode_octal & 077) != 0 || (file_mode_octal & 0400) != 0400 )); then
secret_validation_error "${label}" "file mode MUST allow root read and no group/other access."
return "${ERR_INVLD_CHAR}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_secret_file_path
#######################################
# Validate a filename-only secret stored below the fixed secret root.
# Globals:
# VAR_TMP_SECRET
# Arguments:
# 1: Validation label.
# 2: Filename.
# Returns:
# 0: on success
# Non-zero: on failure
#######################################
validate_secret_file_in_root() {
declare label="$1" filename="$2"
validate_secret_filename "${label}" "${filename}" || return "$?"
validate_secret_file_path "${label}" "${VAR_TMP_SECRET}/${filename}" || return "$?"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_secret_file_in_root
#######################################
# Validate a public input file copied into the ISO.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Validation label.
# 2: File path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_public_input_file() {
declare label="$1" file_path="$2" file_owner="" file_mode="" file_mode_octal=""
validate_secret_absolute_file_basics "${label}" "${file_path}" || return "$?"
file_owner="$(stat -c '%u:%g' -- "${file_path}")"
if [[ "${file_owner}" != "0:0" ]]; then
secret_validation_error "${label}" "file MUST be owned by root:root."
return "${ERR_INVLD_CHAR}"
fi
file_mode="$(stat -c '%a' -- "${file_path}")"
file_mode_octal=$((8#${file_mode}))
if (( (file_mode_octal & 022) != 0 )); then
secret_validation_error "${label}" "file MUST NOT be group- or world-writable."
return "${ERR_INVLD_CHAR}"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_public_input_file
#######################################
# Validate the authorized_keys directory.
# Globals:
# ERR_INVLD_CHAR
# Arguments:
# 1: Directory path.
# Returns:
# 0: on success
# ERR_INVLD_CHAR: on failure
#######################################
validate_ssh_pubkey_directory() {
declare key_dir="$1" key_file="" dir_owner="" dir_mode="" dir_mode_octal=""
if [[ -z "${key_dir}" ]]; then
secret_validation_error "--ssh-pubkey" "directory path MUST NOT be empty."
return "${ERR_INVLD_CHAR}"
fi
if [[ "${key_dir}" != /* ]]; then
secret_validation_error "--ssh-pubkey" "directory path MUST be absolute."
return "${ERR_INVLD_CHAR}"
fi
if [[ -L "${key_dir}" ]]; then
secret_validation_error "--ssh-pubkey" "directory MUST NOT be a symlink."
return "${ERR_INVLD_CHAR}"
fi
if [[ ! -d "${key_dir}" ]]; then
secret_validation_error "--ssh-pubkey" "directory MUST exist."
return "${ERR_INVLD_CHAR}"
fi
dir_owner="$(stat -c '%u:%g' -- "${key_dir}")"
if [[ "${dir_owner}" != "0:0" ]]; then
secret_validation_error "--ssh-pubkey" "directory MUST be owned by root:root."
return "${ERR_INVLD_CHAR}"
fi
dir_mode="$(stat -c '%a' -- "${key_dir}")"
dir_mode_octal=$((8#${dir_mode}))
if (( (dir_mode_octal & 022) != 0 )); then
secret_validation_error "--ssh-pubkey" "directory MUST NOT be group- or world-writable."
return "${ERR_INVLD_CHAR}"
fi
key_file="${key_dir}/authorized_keys"
validate_public_input_file "--ssh-pubkey authorized_keys" "${key_file}" || return "$?"
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_ssh_pubkey_directory
#######################################
# Validate all selected secret inputs after argument parsing.
# Globals:
# VAR_AGE
# VAR_AGE_KEY
# VAR_LUKS
# VAR_LUKS_KEY
# VAR_SIGNER
# VAR_SIGNING_CA
# VAR_SIGNING_KEY
# VAR_SIGNING_KEY_PASS
# VAR_SSHPUBKEY
# VAR_TMP_SECRET
# Arguments:
# None
# Returns:
# 0: on success
# Non-zero: on failure
#######################################
validate_selected_secret_inputs() {
if [[ "${VAR_AGE,,}" == "true" ]]; then
validate_secret_file_in_root "--key_age" "${VAR_AGE_KEY}" || return "$?"
fi
if [[ "${VAR_LUKS,,}" == "true" ]]; then
validate_secret_file_in_root "--key_luks" "${VAR_LUKS_KEY}" || return "$?"
fi
if [[ "${VAR_SIGNER,,}" == "true" ]]; then
validate_secret_file_in_root "--signing_key" "${VAR_SIGNING_KEY}" || return "$?"
validate_secret_file_in_root "--signing_key_pass" "${VAR_SIGNING_KEY_PASS}" || return "$?"
fi
if [[ -n "${VAR_SIGNING_CA:-}" ]]; then
validate_secret_file_in_root "--signing_ca" "${VAR_SIGNING_CA}" || return "$?"
fi
if [[ -n "${VAR_SSHPUBKEY:-}" ]]; then
validate_ssh_pubkey_directory "${VAR_SSHPUBKEY}" || return "$?"
fi
return 0
}
### Prevents accidental 'unset -f'.
# shellcheck disable=SC2034
readonly -f validate_selected_secret_inputs
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
+4
View File
@@ -49,6 +49,8 @@ trap_on_exit() {
print_scr_exit "${errcode}" print_scr_exit "${errcode}"
sanitize_debug_logs || true
exit "${errcode}" exit "${errcode}"
else else
@@ -63,6 +65,8 @@ trap_on_exit() {
fi fi
sanitize_debug_logs || true
exit "${errcode}" exit "${errcode}"
fi fi
+16 -10
View File
@@ -39,13 +39,13 @@ usage() {
# shellcheck disable=SC2155 # shellcheck disable=SC2155
declare var_header=$(center "CDLB(1) CISS.debian.live.builder CDLB(1)" "${var_cols}") declare var_header=$(center "CDLB(1) CISS.debian.live.builder CDLB(1)" "${var_cols}")
# shellcheck disable=SC2155 # shellcheck disable=SC2155
declare var_footer=$(center "V9.14.022.2026.06.10 2026-06-10 CDLB(1)" "${var_cols}") declare var_footer=$(center "${VAR_VERSION} 2026-06-11 CDLB(1)" "${var_cols}")
{ {
echo -e "\e[1;97m${var_header}\e[0m" echo -e "\e[1;97m${var_header}\e[0m"
echo echo
echo -e "\e[92mCISS.debian.live.builder from https://git.coresecret.dev/msw \e[0m" echo -e "\e[92mCISS.debian.live.builder from https://git.coresecret.dev/msw \e[0m"
echo -e "\e[92mMaster V9.14.022.2026.06.10\e[0m" echo -e "\e[92mMaster ${VAR_VERSION}\e[0m"
echo -e "\e[92mA lightweight Shell Wrapper for building a hardened Debian Live ISO Image.\e[0m" echo -e "\e[92mA lightweight Shell Wrapper for building a hardened Debian Live ISO Image.\e[0m"
echo echo
echo -e "\e[97m(c) Marc S. Weidner, 2018 - 2026 \e[0m" echo -e "\e[97m(c) Marc S. Weidner, 2018 - 2026 \e[0m"
@@ -67,6 +67,7 @@ usage() {
echo echo
echo -e "\e[97m --build-directory </path/to/build_directory> \e[0m" echo -e "\e[97m --build-directory </path/to/build_directory> \e[0m"
echo " Where the Debian Live Build Image should be generated. RECOMMENDED path: </opt/cdlb>" echo " Where the Debian Live Build Image should be generated. RECOMMENDED path: </opt/cdlb>"
echo " Cleanup is destructive inside the exact builder-owned path and requires '.ciss-live-builder-owned'."
echo " MUST be provided." echo " MUST be provided."
echo echo
echo -e "\e[97m --change-splash <STRING> one of <club | hexagon> \e[0m" echo -e "\e[97m --change-splash <STRING> one of <club | hexagon> \e[0m"
@@ -77,6 +78,9 @@ usage() {
echo " This option creates a boot menu entry that starts the forthcoming 'CISS.debian.installer', which is executed" echo " This option creates a boot menu entry that starts the forthcoming 'CISS.debian.installer', which is executed"
echo " once the system has successfully booted up." echo " once the system has successfully booted up."
echo echo
echo -e "\e[97m --cicd \e[0m"
echo " Only for CISS internal Gitea Action Runners"
echo
echo -e "\e[97m --contact, -c \e[0m" echo -e "\e[97m --contact, -c \e[0m"
echo " Show author contact information." echo " Show author contact information."
echo echo
@@ -87,6 +91,7 @@ usage() {
echo -e "\e[97m --debug, -d \e[0m" echo -e "\e[97m --debug, -d \e[0m"
echo " Enables debug logging for the main program routine. Detailed logging information are written to:" echo " Enables debug logging for the main program routine. Detailed logging information are written to:"
echo " </tmp/ciss_live_builder_$$.log>" echo " </tmp/ciss_live_builder_$$.log>"
echo " After xtrace is stopped and its debug FD is closed, a final exact-value redaction pass sanitizes logs."
echo echo
echo -e "\e[97m --dhcp-centurion \e[0m" echo -e "\e[97m --dhcp-centurion \e[0m"
echo " If a DHCP lease is provided, the provider's name server will be overridden and the hardened, privacy-focused " echo " If a DHCP lease is provided, the provider's name server will be overridden and the hardened, privacy-focused "
@@ -108,14 +113,17 @@ usage() {
echo echo
echo -e "\e[97m --key_age=* \e[0m" echo -e "\e[97m --key_age=* \e[0m"
echo " The SOPS AGE private keyring for decryption operations. Change '*' to your desired SOPS AGE key file." echo " The SOPS AGE private keyring for decryption operations. Change '*' to your desired SOPS AGE key file."
echo " File MUST be placed in:" echo " This MUST be a filename only and MUST be placed in the root-owned tmpfs secret root:"
echo " </dev/shm/cdlb_secrets>" echo " </dev/shm/cdlb_secrets>"
echo echo
echo -e "\e[97m --key_luks=* \e[0m" echo -e "\e[97m --key_luks=* \e[0m"
echo " The LUKS encryption / decryption passphrase for '/'-fs-encryption. Change '*' to your desired passphrase file." echo " The LUKS encryption / decryption passphrase for '/'-fs-encryption. Change '*' to your desired passphrase file."
echo " File MUST be placed in:" echo " This MUST be a filename only and MUST be placed in the root-owned tmpfs secret root:"
echo " </dev/shm/cdlb_secrets>" echo " </dev/shm/cdlb_secrets>"
echo echo
echo -e "\e[97m --logo, -l \e[0m"
echo " Shows the Centurion Head."
echo
echo -e "\e[97m --log-statistics-only \e[0m" echo -e "\e[97m --log-statistics-only \e[0m"
echo " Provides statistic only after successful building a CISS.debian.live-ISO. While enabling '--log-statistics-only'" echo " Provides statistic only after successful building a CISS.debian.live-ISO. While enabling '--log-statistics-only'"
echo " the argument '--build-directory' MUST be provided." echo " the argument '--build-directory' MUST be provided."
@@ -123,10 +131,6 @@ usage() {
echo -e "\e[97m --primordial-key <ssh-identity-filename> \e[0m" echo -e "\e[97m --primordial-key <ssh-identity-filename> \e[0m"
echo " SSH identity filename for the Primordial overlay clone. This MUST be a filename only; the runtime path is" echo " SSH identity filename for the Primordial overlay clone. This MUST be a filename only; the runtime path is"
echo " derived as '/root/.ssh/<ssh-identity-filename>'." echo " derived as '/root/.ssh/<ssh-identity-filename>'."
echo " Example fragment:"
echo " ./ciss_live_builder.sh --primordial-url https://git.coresecret.dev/ahz/PhysNet.primordial.git \\"
echo " --primordial-key id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10 \\"
echo " --primordial-ssh 42842"
echo echo
echo -e "\e[97m --primordial-ssh <INTEGER> \e[0m" echo -e "\e[97m --primordial-ssh <INTEGER> \e[0m"
echo " Adds one outgoing UFW TCP exception for a bootstrap SSH port." echo " Adds one outgoing UFW TCP exception for a bootstrap SSH port."
@@ -162,7 +166,8 @@ usage() {
echo -e "\e[97m --root-password-file </dev/shm/cdlb_secrets/password.txt>> \e[0m" echo -e "\e[97m --root-password-file </dev/shm/cdlb_secrets/password.txt>> \e[0m"
echo " Password file for 'root', if given, MUST be a string of 42 to 64 characters." echo " Password file for 'root', if given, MUST be a string of 42 to 64 characters."
echo " If the argument is omitted, no further login authentication is required for the local console." echo " If the argument is omitted, no further login authentication is required for the local console."
echo " MUST be placed in:" echo " The path MUST be absolute, regular, non-symlink, root-owned, and mode 0400 after normalization."
echo " RECOMMENDED path:"
echo " </dev/shm/cdlb_secrets/password.txt>" echo " </dev/shm/cdlb_secrets/password.txt>"
echo echo
echo -e "\e[97m --secure-boot-profile <STRING> one of <debian-shim | ciss-uki> \e[0m" echo -e "\e[97m --secure-boot-profile <STRING> one of <debian-shim | ciss-uki> \e[0m"
@@ -178,7 +183,7 @@ usage() {
echo " specified via '--signing_key=*'. If the keyring is protected, then provide the passphrase in its own file." echo " specified via '--signing_key=*'. If the keyring is protected, then provide the passphrase in its own file."
echo " Specify the fingerprint of the key to use via '--signing_key_fpr=*'." echo " Specify the fingerprint of the key to use via '--signing_key_fpr=*'."
echo " Optionally import an offline GPG CA signing public key via: '--signing_ca=*'." echo " Optionally import an offline GPG CA signing public key via: '--signing_ca=*'."
echo " Change '*' to your desired files / fingerprint. Files MUST be placed in:" echo " Change '*' to your desired filename-only files / fingerprint. Files MUST be placed in:"
echo " </dev/shm/cdlb_secrets>" echo " </dev/shm/cdlb_secrets>"
echo echo
echo -e "\e[97m --sops-version <STRING> \e[0m" echo -e "\e[97m --sops-version <STRING> \e[0m"
@@ -201,6 +206,7 @@ usage() {
echo echo
echo -e "\e[97m --ssh-pubkey </dev/shm/cdlb_secrets/> \e[0m" echo -e "\e[97m --ssh-pubkey </dev/shm/cdlb_secrets/> \e[0m"
echo " Imports the SSH Public Key from the file 'authorized_keys' into the Live ISO." echo " Imports the SSH Public Key from the file 'authorized_keys' into the Live ISO."
echo " Directory MUST be absolute, regular, non-symlink, root-owned, and not group/world-writable."
echo " Key file MUST be placed in:" echo " Key file MUST be placed in:"
echo " </dev/shm/cdlb_secrets/authorized_keys>" echo " </dev/shm/cdlb_secrets/authorized_keys>"
echo echo
+2 -2
View File
@@ -601,7 +601,7 @@ main() {
var_log="/root/.ciss/cdi/log/9999-cdi-starter_$(date +"%Y-%m-%d_%H-%M-%S").log" var_log="/root/.ciss/cdi/log/9999-cdi-starter_$(date +"%Y-%m-%d_%H-%M-%S").log"
touch "${var_log}" touch "${var_log}"
printf "CISS.debian.live.builder V9.14.022.2026.06.10 calling CISS.debian.installer ... \n" >> "${var_log}" printf "CISS.debian.live.builder V9.14.028.2026.06.18 calling CISS.debian.installer ... \n" >> "${var_log}"
### Sleep a moment to settle boot artifacts. ### Sleep a moment to settle boot artifacts.
sleep 8 sleep 8
@@ -696,7 +696,7 @@ main() {
### Timeout reached without acceptable semaphore. ### Timeout reached without acceptable semaphore.
logger -t cdi-watcher "No valid semaphore ${VAR_SEMAPHORE} (mode 0600) within ${VAR_TIMEOUT}s; exiting idle." logger -t cdi-watcher "No valid semaphore ${VAR_SEMAPHORE} (mode 0600) within ${VAR_TIMEOUT}s; exiting idle."
printf "CISS.debian.live.builder V9.14.022.2026.06.10: No valid semaphore [%s] within [%s]s.\n" "${VAR_SEMAPHORE}" "${VAR_TIMEOUT}" >> "${var_log}" printf "CISS.debian.live.builder V9.14.028.2026.06.18: No valid semaphore [%s] within [%s]s.\n" "${VAR_SEMAPHORE}" "${VAR_TIMEOUT}" >> "${var_log}"
exit 0 exit 0
} }
-228
View File
@@ -1,228 +0,0 @@
#!/bin/bash
# SPDX-Version: 3.0
# SPDX-FileCopyrightText: 2026; WEIDNER, Marc S.; <msw@coresecret.dev>
# SPDX-FileType: SOURCE
# SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1
# SPDX-PackageName: CISS.debian.live.builder
set -Ceuo pipefail
declare ROOT_DIR=""
declare SHA512SUM=""
declare SHASUM=""
declare TMP_BASE=""
declare TMP_ROOT=""
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SHA512SUM="$(command -v sha512sum)"
SHASUM="$(command -v shasum || true)"
TMP_BASE="${TMPDIR:-/tmp}"
TMP_BASE="${TMP_BASE%/}"
TMP_ROOT="$(mktemp -d "${TMP_BASE}/ciss-boot-attestation.XXXXXXXX")"
cleanup() {
case "${TMP_ROOT}" in
"${TMP_BASE}/ciss-boot-attestation."*)
rm -rf -- "${TMP_ROOT}"
;;
*)
printf 'Refusing to clean unexpected test path: %s\n' "${TMP_ROOT}" >&2
return 1
;;
esac
}
trap cleanup EXIT
fail() {
printf 'FAIL: %s\n' "${1}" >&2
exit 1
}
prepare_checksum_hook() {
declare source_hook="${1}"
declare target_hook="${2}"
declare fault_mode="${3}"
declare test_bin="${4}"
declare test_tty="${5}"
declare test_runtime=""
test_runtime="$(dirname "${test_tty}")"
sed \
-e "s|/usr/bin/|${test_bin}/|g" \
-e "s|/run/ciss-|${test_runtime}/ciss-|g" \
-e "s|_TTY=\"/dev/tty8\"|_TTY=\"${test_tty}\"|" \
"${source_hook}" > "${target_hook}"
if [[ "${fault_mode}" == "unknown-state" ]]; then
sed \
-e 's/_RETURN_PGP="na"/_RETURN_PGP="unknown"/' \
-e 's/_RETURN_SHA="${?}"/_RETURN_SHA="unknown"/g' \
"${target_hook}" > "${target_hook}.new"
mv "${target_hook}.new" "${target_hook}"
fi
}
install_test_sha512sum() {
declare test_bin="${1}"
if printf '' | "${SHA512SUM}" -c >/dev/null 2>&1; then
ln -s "${SHA512SUM}" "${test_bin}/sha512sum"
elif [[ -n "${SHASUM}" ]]; then
printf '#!/bin/sh\nexec "%s" -a 512 "$@"\n' "${SHASUM}" > "${test_bin}/sha512sum"
chmod 0755 "${test_bin}/sha512sum"
else
fail "No SHA-512 tool with checksum verification support is available."
fi
}
run_checksum_case() {
declare source_hook="${1}"
declare case_name="${2}"
declare expected_status="${3}"
declare expected_message="${4}"
declare case_dir=""
declare hook_copy=""
declare output_file=""
declare test_bin=""
declare test_tty=""
declare source_id=""
declare fault_mode=""
declare panic_returns="false"
declare status=0
source_id="$(printf '%s' "${source_hook#"${ROOT_DIR}"/}" | tr '/' '_')"
case_dir="${TMP_ROOT}/${source_id}-${case_name}"
hook_copy="${case_dir}/0030-ciss-verify-checksums"
output_file="${case_dir}/output.log"
test_bin="${case_dir}/bin"
test_tty="${case_dir}/tty.log"
mkdir -p "${case_dir}" "${test_bin}"
: >| "${test_tty}"
case "${case_name}" in
valid)
install_test_sha512sum "${test_bin}"
printf 'trusted rootfs payload\n' > "${case_dir}/payload"
(cd "${case_dir}" && "${test_bin}/sha512sum" payload > sha512sum.txt)
;;
missing-manifest)
install_test_sha512sum "${test_bin}"
;;
unsupported-manifest)
install_test_sha512sum "${test_bin}"
printf 'unsupported\n' > "${case_dir}/md5sum.txt"
;;
failed-checksum)
install_test_sha512sum "${test_bin}"
printf 'trusted rootfs payload\n' > "${case_dir}/payload"
(cd "${case_dir}" && "${test_bin}/sha512sum" payload > sha512sum.txt)
printf 'tampered rootfs payload\n' >| "${case_dir}/payload"
;;
missing-tool)
install_test_sha512sum "${test_bin}"
printf 'trusted rootfs payload\n' > "${case_dir}/payload"
(cd "${case_dir}" && "${test_bin}/sha512sum" payload > sha512sum.txt)
rm -f "${test_bin}/sha512sum"
;;
unknown-state)
fault_mode="unknown-state"
panic_returns="true"
install_test_sha512sum "${test_bin}"
printf 'trusted rootfs payload\n' > "${case_dir}/payload"
(cd "${case_dir}" && "${test_bin}/sha512sum" payload > sha512sum.txt)
;;
*)
fail "Unknown checksum test case: ${case_name}"
;;
esac
prepare_checksum_hook "${source_hook}" "${hook_copy}" "${fault_mode}" "${test_bin}" "${test_tty}"
set +e
# shellcheck disable=SC2034,SC2329
(
set +C
CDLB_SCRIPT_FULL="${hook_copy}"
LIVE_BOOT_CMDLINE="verify-checksums=sha512"
LIVE_VERIFY_CHECKSUMS=""
log_begin_msg() { :; }
log_end_msg() { :; }
log_success_msg() { :; }
panic() {
printf 'PANIC: %s\n' "${1}" >&2
if [[ "${panic_returns}" == "true" ]]; then
return 0
fi
exit 97
}
sleep() { :; }
# shellcheck source=/dev/null
. "${hook_copy}"
Verify_checksums "${case_dir}"
) > "${output_file}" 2>&1
status="${?}"
set -e
[[ "${status}" -eq "${expected_status}" ]] || {
cat "${output_file}" >&2
fail "${source_hook} ${case_name}: expected status ${expected_status}, got ${status}"
}
grep -Fq "${expected_message}" "${output_file}" || {
cat "${output_file}" >&2
fail "${source_hook} ${case_name}: missing expected message '${expected_message}'"
}
}
test_rootfs_payload_tamper() {
declare case_dir="${TMP_ROOT}/rootfs-payload-tamper"
declare test_bin="${case_dir}/bin"
declare payload="${case_dir}/crypt_liveiso"
declare manifest="${case_dir}/ciss_rootfs.crypt.decrypted.sha512sum.txt"
declare build_hook="${ROOT_DIR}/config/hooks/live/zzzz_ciss_crypt_squash.hook.binary"
declare boot_hook="${ROOT_DIR}/config/includes.chroot/usr/lib/live/boot/0042_ciss_post_decrypt_attest"
mkdir -p "${case_dir}" "${test_bin}"
install_test_sha512sum "${test_bin}"
printf 'trusted selected rootfs mapper payload\n' > "${payload}"
"${test_bin}/sha512sum" "${payload}" > "${manifest}"
"${test_bin}/sha512sum" -c --strict --quiet "${manifest}"
printf 'tampered selected rootfs mapper payload\n' >> "${payload}"
if "${test_bin}/sha512sum" -c --strict --quiet "${manifest}" >/dev/null 2>&1; then
fail "Modified selected rootfs payload unexpectedly passed checksum verification."
fi
# shellcheck disable=SC2016
grep -Fq 'sha512sum "${MAPPER_DEV}" >| "${ROOTFS_ATTESTATION}"' "${build_hook}" || \
fail "Build hook does not generate the attestation from the decrypted mapper."
# shellcheck disable=SC2016
grep -Fq '/usr/bin/sha512sum -c --strict --quiet "${HASH_FILE}"' "${boot_hook}" || \
fail "Boot hook does not verify the selected rootfs payload with sha512sum -c."
# shellcheck disable=SC2016
grep -Fq '[ "${_ATTESTED_PAYLOAD}" != "${CDLB_MAPPER_DEV}" ]' "${boot_hook}" || \
fail "Boot hook does not require the manifest to target the selected rootfs payload."
}
declare -a CHECKSUM_HOOKS=(
"${ROOT_DIR}/config/includes.chroot/usr/lib/live/boot/0030-ciss-verify-checksums"
"${ROOT_DIR}/scripts/usr/lib/live/boot/0030-ciss-verify-checksums"
)
declare checksum_hook=""
for checksum_hook in "${CHECKSUM_HOOKS[@]}"; do
run_checksum_case "${checksum_hook}" "valid" 0 "Verification of [sha checksum] file successful"
run_checksum_case "${checksum_hook}" "missing-manifest" 97 "No supported checksum manifest found."
run_checksum_case "${checksum_hook}" "unsupported-manifest" 97 "No supported checksum manifest found."
run_checksum_case "${checksum_hook}" "failed-checksum" 97 "No supported checksum manifest was verified successfully."
run_checksum_case "${checksum_hook}" "missing-tool" 97 "No supported checksum verification tool was available."
run_checksum_case "${checksum_hook}" "unknown-state" 1 "Checksum verification ended in an unsupported state."
done
test_rootfs_payload_tamper
printf 'PASS: checksum verification fails closed and modified rootfs payloads fail attestation.\n'
+1 -1
View File
@@ -25,7 +25,7 @@ declare -grx VAR_GIT_HEAD_FULL="$(git rev-parse HEAD)"
declare -grx VAR_HOST="$(uname -n)" declare -grx VAR_HOST="$(uname -n)"
declare -grx VAR_ISO8601="$(date -u -d "@${VAR_DATE_EPOCH}" '+%Y-%m-%dT%H:%M:%SZ')" declare -grx VAR_ISO8601="$(date -u -d "@${VAR_DATE_EPOCH}" '+%Y-%m-%dT%H:%M:%SZ')"
declare -grx VAR_SYSTEM="$(uname -mnosv)" declare -grx VAR_SYSTEM="$(uname -mnosv)"
declare -grx VAR_VERSION="Master V9.14.022.2026.06.10" declare -grx VAR_VERSION="Master V9.14.028.2026.06.18"
declare -grx VAR_VER_BASH="$(bash --version | head -n1 | awk '{ declare -grx VAR_VER_BASH="$(bash --version | head -n1 | awk '{
# Print $4 and $5; include $6 only if it exists # Print $4 and $5; include $6 only if it exists
out = $4 out = $4
+3
View File
@@ -43,6 +43,7 @@ declare -g VAR_SSHFP="false"
declare -g VAR_SSHPORT="" declare -g VAR_SSHPORT=""
declare -g VAR_SSHPUBKEY="" declare -g VAR_SSHPUBKEY=""
declare -g VAR_SUITE="trixie" declare -g VAR_SUITE="trixie"
declare -ga ARY_DEBUG_SECRET_VALUES=()
declare -ga ARY_HANDLER_JUMPHOST_UNIQUE=() declare -ga ARY_HANDLER_JUMPHOST_UNIQUE=()
declare -ga ARY_HANDLER_JUMPHOST=() declare -ga ARY_HANDLER_JUMPHOST=()
declare -ga ARY_HANDLER_NETCUP_IPV6=() declare -ga ARY_HANDLER_NETCUP_IPV6=()
@@ -51,10 +52,12 @@ declare -gi VAR_HANDLER_PRIORITY=0
declare -gi VAR_HANDLER_STA=0 declare -gi VAR_HANDLER_STA=0
declare -gi VAR_REIONICE_CLASS=2 declare -gi VAR_REIONICE_CLASS=2
declare -gi VAR_REIONICE_PRIORITY=4 declare -gi VAR_REIONICE_PRIORITY=4
declare -gr CISS_BUILD_DIR_MARKER=".ciss_debian_live_builder_owned"
declare -gr VAR_CHROOT_DIR="chroot" declare -gr VAR_CHROOT_DIR="chroot"
declare -gr VAR_PACKAGES_FILE="chroot.packages.live" declare -gr VAR_PACKAGES_FILE="chroot.packages.live"
declare -gx VAR_AGE_KEY="" declare -gx VAR_AGE_KEY=""
declare -gx VAR_AGE="false" declare -gx VAR_AGE="false"
declare -gx VAR_ARG_SANITIZED=""
declare -gx VAR_CDLB_INSIDE_RUNNER="${VAR_CDLB_INSIDE_RUNNER:-false}" declare -gx VAR_CDLB_INSIDE_RUNNER="${VAR_CDLB_INSIDE_RUNNER:-false}"
declare -gx VAR_CISS_SECUREBOOT_PROFILE="debian-shim" declare -gx VAR_CISS_SECUREBOOT_PROFILE="debian-shim"
declare -gx VAR_LUKS_KEY="" declare -gx VAR_LUKS_KEY=""