Compare commits
6 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
|
6aeb9037ea
|
|||
|
eeecefc966
|
|||
|
42e2ae6b0e
|
|||
|
b78779e790
|
|||
|
9ef535554a
|
|||
|
800cd175fc
|
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔐 Generating a Private Live ISO TRIXIE.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔐 Generating a Private Live ISO TRIXIE.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 💙 Generating a PUBLIC Live ISO.
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ body:
|
||||
attributes:
|
||||
label: "Version"
|
||||
description: "Which version are you running? Use `./ciss_live_builder.sh -v`."
|
||||
placeholder: "e.g., Master V9.14.020.2026.06.08"
|
||||
placeholder: "e.g., Master V9.14.022.2026.06.10"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
FROM debian:bookworm
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔁 Render README.md to README.html.
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
|
||||
build:
|
||||
counter: 1023
|
||||
version: V9.14.020.2026.06.08
|
||||
version: V9.14.022.2026.06.10
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
|
||||
build:
|
||||
counter: 1023
|
||||
version: V9.14.020.2026.06.08
|
||||
version: V9.14.022.2026.06.10
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=yaml
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
|
||||
build:
|
||||
counter: 1023
|
||||
version: V9.14.020.2026.06.08
|
||||
version: V9.14.022.2026.06.10
|
||||
# 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-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔐 Generating a Private Live ISO TRIXIE.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔐 Generating a Private Live ISO TRIXIE.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 💙 Generating a PUBLIC Live ISO.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
# Gitea Workflow: Shell-Script Linting
|
||||
#
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🛡️ Retrieve DNSSEC status of coresecret.dev.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
name: 🔁 Render Graphviz Diagrams.
|
||||
|
||||
|
||||
+1
-1
@@ -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-PackageName="CISS.debian.live.builder"
|
||||
properties_SPDX-Security-Contact="security@coresecret.eu"
|
||||
properties_version="V9.14.020.2026.06.08"
|
||||
properties_version="V9.14.022.2026.06.10"
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=conf
|
||||
|
||||
@@ -6,7 +6,7 @@ Creator: Person: Marc S. Weidner (Centurion Intelligence Consulting Agency)
|
||||
Created: 2025-05-07T12:00:00Z
|
||||
Package: CISS.debian.live.builder
|
||||
PackageName: CISS.debian.live.builder
|
||||
PackageVersion: Master V9.14.020.2026.06.08
|
||||
PackageVersion: Master V9.14.022.2026.06.10
|
||||
PackageSupplier: Organization: Centurion Intelligence Consulting Agency
|
||||
PackageDownloadLocation: https://git.coresecret.dev/msw/CISS.debian.live.builder
|
||||
PackageHomePage: https://git.coresecret.dev/msw/CISS.debian.live.builder
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
gitea: none
|
||||
include_toc: true
|
||||
---
|
||||
[](https://git.coresecret.dev/msw/CISS.debian.live.builder)
|
||||
[](https://git.coresecret.dev/msw/CISS.debian.live.builder)
|
||||
|
||||
[](https://eupl.eu/1.2/en/)
|
||||
[](https://opensource.org/license/eupl-1-2)
|
||||
@@ -27,7 +27,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
**CISS.debian.live.builder — First of its own.**<br>
|
||||
**World-class CIA: Designed, handcrafted, and powered by Centurion Intelligence Consulting Agency.**
|
||||
@@ -175,7 +175,7 @@ installer toolchain.
|
||||
|
||||
This project adheres strictly to a structured versioning scheme following the pattern x.y.z-Date.
|
||||
|
||||
Example: `V9.14.020.2026.06.08`
|
||||
Example: `V9.14.022.2026.06.10`
|
||||
|
||||
`x.y.z` represents major (x), minor (y), and patch (z) version increments.
|
||||
|
||||
@@ -365,6 +365,11 @@ For further details see: **[90-ciss-local.hardened.md](docs/documentation/90-cis
|
||||
## 2.9. UFW Hardening
|
||||
|
||||
* **Description**: Defaults to `deny incoming` and (optionally) `deny outgoing`; automatically opens only whitelisted ports.
|
||||
* **Primordial SSH exception**: `--primordial-url <https-git-url>`, `--primordial-key <ssh-identity-filename>` and
|
||||
`--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
|
||||
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.
|
||||
* **Rationale**: Implements a default-deny firewall, reducing lateral movement and data exfiltration risks immediately after
|
||||
deployment.
|
||||
|
||||
@@ -520,6 +525,9 @@ To use **``CISS.debian.live.builder``** as intended, the following baseline is e
|
||||
--signing_key_pass=signing_key_pass.txt \
|
||||
--signing_key=signing_key.asc \
|
||||
--ssh-port 4242 \
|
||||
--primordial-url https://git.coresecret.dev/ahz/PhysNet.primordial.git \
|
||||
--primordial-key id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10 \
|
||||
--primordial-ssh 42842 \
|
||||
--ssh-pubkey /dev/shm/cdlb_secrets \
|
||||
--sshfp \
|
||||
--trixie
|
||||
@@ -569,6 +577,9 @@ preview it or run it.
|
||||
SSH_PUBKEY=/dev/shm/cdlb_secrets
|
||||
|
||||
# Optional
|
||||
PRIMORDIAL_URL=https://git.coresecret.dev/ahz/PhysNet.primordial.git
|
||||
PRIMORDIAL_KEY=id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10
|
||||
PRIMORDIAL_SSH_PORT=42842
|
||||
PROVIDER_NETCUP_IPV6=2001:cdb::1
|
||||
# comma-separated; IPv6 in [] is fine
|
||||
JUMP_HOSTS=[2001:db8::1],[2001:db8::2]
|
||||
|
||||
+2
-2
@@ -8,13 +8,13 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Repository Structure
|
||||
|
||||
**Project:** Centurion Intelligence Consulting Agency Information Security Standard (CISS) — Debian Live Builder
|
||||
**Branch:** `master`
|
||||
**Repository State:** Master Version **9.14**, Build **V9.14.020.2026.06.08** (as of 2025-10-11)
|
||||
**Repository State:** Master Version **9.14**, Build **V9.14.022.2026.06.10** (as of 2025-10-11)
|
||||
|
||||
## 3.1. Top-Level Layout
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
.:-=++***#####***+==-:.
|
||||
.-=*#%%@@@@@@@@@@@@@@@@@@@@@%%#*=-.
|
||||
.=*#@@@@@@@%%%%%%%%%%%%%%%%%%%%%@@@@@@@%*=:
|
||||
:+#@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@%*=.
|
||||
.+#@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@#=:
|
||||
:*%@@%%%%%%%%%%%%%%%%@@@@@@@@@@@@@%%%%%%%%%%%%%%%%@@@@%%%*=
|
||||
:*@@%%%%%%%%%%%%%%@@@@@%%#*******#%%@@@@%%%%%%%%%@@%#+-:.
|
||||
.+@@%%%%%%%%%%%%%%@@%#+-. .-+#%@@%%%%@@#=.
|
||||
-%@%%%%%%%%%%%%%@@%*-. :-+**####**+-: .-*%@@@*:
|
||||
+@@%%%%%%%%%%%%%@%+. :+#%@@@@@@@@@@@@@@%#+: .+#:
|
||||
*@%%%%%%%%%%%%%%@*. =#@@@@%%%%%%%%%%%%%%@@@@#-
|
||||
*@%%%%%%%%%%%%%%@- -%@@%%%%%%%%%%%%%%%%%%%%%%@@#-
|
||||
+@%%%%%%%%%%%%%%@- +@@%%%%%%%%%%%%%%%%%%%%%%%%%%@@+-*#
|
||||
-@%%%%%%%%%%%%%%@+ +@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@-
|
||||
%%%%%%%%%%%%%%%%% :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
-@%%%%%%%%%%%%%%@* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@=
|
||||
#%%%%%%%%%%%%%%%@= *@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
.%%%%%%%%%%%%%%%%@+ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@%%%%%%%=
|
||||
-@%%%%%%%%%%%%%%%@* :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@@@@@.
|
||||
=@%%%%%%%%%%%%%%%%%. #@%%%%%%%%%%%%%%%%%%%%%%%%%%%*..:--==+*-
|
||||
=@%%%%%%%%%%%%%%%%@= :@%%%%%%%%%%%%%%%%%%%%%%%%%%%@#:
|
||||
=@%%%%%%%%%%%%%%%%%%. +@%%%%%%%%%%%%%%%%%%%%%%%%%%%@@+
|
||||
:@%%%%%%%%%%%%%%%%%@# #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@#::::.
|
||||
%@%%%%%%%%%%%%%%%%%@= :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@@@%#:
|
||||
*%%%%%%%%%%%%%%%%%%- *@%%%%%%%%%%%%%%%@@@@%%%%%%%%%%%%%%%@@@.
|
||||
:@%%%%%%%%%%%%%%%@- -@%%%%%%%%%%%%@@@%%%%%@@%%%%%%%%%%%%%%%.
|
||||
*@%%%%%%%%%%%%%@+ .%%%%%%%%%%%@@*=:. .-*@%%%%%%%%%%%%@=
|
||||
.%%%%%%%%%%%%%%%. .%%%%%%%%%@@*: :%%%%%%%%%%%@+
|
||||
=@%%%%%%%%%%%@* -@%%%%%%%@#: =@%%%%%%%%@*
|
||||
+@%%%%%%%%%%@. *@%%%%%@@+ .@%%%%%%%%%.
|
||||
*@%%%%%%%%@+ -@%%%%%@%- .@%%%%%%%@=
|
||||
+@%%%%%@@* :%%%%%@@*. -@%%%%%%%%
|
||||
=@@@@@#- :%%%%@@%- #%%%%%%%@+
|
||||
:#*+: :%%%@@%+ -@@@%%%%%@:
|
||||
=@@@@#=. :+#@@@@%%.
|
||||
.*%#*=. .=*%@%
|
||||
::. .-+
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. CISS Secure Boot Private Material
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. CISS Secure Boot Public Material
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ source_guard "./var/bash.var.sh"
|
||||
### CHECK FOR CONTACT, HELP, VERSION STRING, AND XTRACE DEBUG.
|
||||
for arg in "$@"; do case "${arg,,}" in -c|--contact) . ./lib/lib_contact.sh ; contact; exit 0;; esac; done
|
||||
for arg in "$@"; do case "${arg,,}" in -h|--help) . ./lib/lib_usage.sh ; usage ; exit 0;; esac; done
|
||||
for arg in "$@"; do case "${arg,,}" in -l|--logo) . ./lib/lib_logo.sh ; logo ; exit 0;; esac; done
|
||||
for arg in "$@"; do case "${arg,,}" in -v|--version) . ./lib/lib_version.sh ; version; exit 0;; esac; done
|
||||
for arg in "$@"; do case "${arg,,}" in -d|--debug) . ./meta_sources_debug.sh; debugger "${@}";; esac; done
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@ BUILD_DIR ?=
|
||||
DROPBEAR_VERSION ?=
|
||||
### Optional SOPS release override; empty uses VAR_SOPS_VERSION from var/global.var.sh:
|
||||
SOPS_VERSION ?=
|
||||
### Optional Primordial CDI overlay settings; all three values are required for automatic overlay bootstrap:
|
||||
PRIMORDIAL_URL ?=
|
||||
PRIMORDIAL_KEY ?=
|
||||
PRIMORDIAL_SSH_PORT ?=
|
||||
PROVIDER_NETCUP_IPV6 ?=
|
||||
ROOT_PASSWORD_FILE ?=
|
||||
### Secure Boot profile; debian-shim or ciss-uki:
|
||||
|
||||
@@ -15,6 +15,7 @@ printf "\e[95m🧪 '%s' starting ... \e[0m\n" "${0}"
|
||||
|
||||
declare -r UFW_OUT_POLICY="deny"
|
||||
declare -r SSHPORT="SSHPORT_MUST_BE_SET"
|
||||
# PRIMORDIAL_SSH_PORT_DECLARATION_MUST_BE_SET
|
||||
|
||||
ufw --force reset
|
||||
|
||||
@@ -44,7 +45,8 @@ if [[ ${UFW_OUT_POLICY,,} == "deny" ]]; then
|
||||
ufw allow out 853/tcp comment 'Outgoing DoT'
|
||||
ufw allow out 993/tcp comment 'Outgoing IMAPS'
|
||||
ufw allow out 4460/tcp comment 'Outgoing NTS'
|
||||
ufw allow out "${SSHPORT}"/tcp comment 'Outgoing SSH (Custom-Port)'
|
||||
ufw allow out "${SSHPORT}"/tcp comment 'Outgoing SSH Custom-Port'
|
||||
# PRIMORDIAL_SSH_RULE_MUST_BE_SET
|
||||
ufw allow out 53/udp comment 'Outgoing DNS'
|
||||
ufw allow out 123/udp comment 'Outgoing NTP'
|
||||
ufw allow out 443/udp comment 'Outgoing QUIC'
|
||||
|
||||
@@ -9,17 +9,90 @@
|
||||
# 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
|
||||
set -Ceuo pipefail
|
||||
|
||||
# Final live-build binary hook for encrypted root filesystem packaging. Preallocate a LUKS2 container, formats it with the
|
||||
# generated build secret, copies the generated filesystem.squashfs into the opened encrypted mapping, then closes the container,
|
||||
# shreds the temporary LUKS secret, and removes the plaintext SquashFS from the ISO payload.
|
||||
# Final live-build binary hook for encrypted root filesystem packaging. Preallocate a LUKS2 container, format it with the
|
||||
# generated build secret, copy the generated filesystem.squashfs into the opened encrypted mapping, generate and sign a
|
||||
# SHA-512 attestation manifest for the complete decrypted mapper, then close the container, shred the temporary LUKS secret,
|
||||
# and remove the plaintext SquashFS from the ISO payload.
|
||||
|
||||
printf "\e[95m🧪 '%s' starting ... \e[0m\n" "${0}"
|
||||
|
||||
__umask=$(umask)
|
||||
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.
|
||||
# Globals:
|
||||
@@ -65,8 +138,25 @@ readonly -f preallocate
|
||||
|
||||
declare ROOTFS="${VAR_HANDLER_BUILD_DIR}/binary/live/filesystem.squashfs"
|
||||
declare LUKSFS="${VAR_HANDLER_BUILD_DIR}/binary/live/ciss_rootfs.crypt"
|
||||
declare MAPPER_DEV="/dev/mapper/crypt_liveiso"
|
||||
declare ROOTFS_ATTESTATION="${LUKSFS}.decrypted.sha512sum.txt"
|
||||
declare ROOTFS_ATTESTATION_SIG="${ROOTFS_ATTESTATION}.sig"
|
||||
declare KEYFD=""
|
||||
|
||||
require_command gpg
|
||||
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."
|
||||
|
||||
rm -f -- "${ROOTFS_ATTESTATION}" "${ROOTFS_ATTESTATION_SIG}"
|
||||
|
||||
# shellcheck disable=SC2155
|
||||
declare -i VAR_ROOTFS_SIZE=$(stat -c%s -- "${ROOTFS}")
|
||||
|
||||
@@ -126,7 +216,7 @@ fi
|
||||
cryptsetup open --key-file "/proc/$$/fd/${KEYFD}" "${LUKSFS}" crypt_liveiso
|
||||
|
||||
# shellcheck disable=SC2155
|
||||
declare -i LUKS_FREE=$(blockdev --getsize64 /dev/mapper/crypt_liveiso)
|
||||
declare -i LUKS_FREE=$(blockdev --getsize64 "${MAPPER_DEV}")
|
||||
declare -i SQUASH_FS="${VAR_ROOTFS_SIZE}"
|
||||
|
||||
if (( LUKS_FREE >= SQUASH_FS )); then
|
||||
@@ -140,8 +230,22 @@ else
|
||||
|
||||
fi
|
||||
|
||||
dd if="${ROOTFS}" of=/dev/mapper/crypt_liveiso bs=8M status=progress conv=fsync
|
||||
dd if="${ROOTFS}" of="${MAPPER_DEV}" bs=8M status=progress conv=fsync
|
||||
sync
|
||||
|
||||
# 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}<&-
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
[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==
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
### 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
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Version Master V9.14.020.2026.06.08
|
||||
# Version Master V9.14.022.2026.06.10
|
||||
|
||||
### https://docs.kernel.org/
|
||||
### https://github.com/a13xp0p0v/kernel-hardening-checker/
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# SPDX-PackageName: CISS.debian.live.builder
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
declare -gr VERSION="Master V9.14.020.2026.06.08"
|
||||
declare -gr VERSION="Master V9.14.022.2026.06.10"
|
||||
|
||||
### VERY EARLY CHECK FOR DEBUGGING
|
||||
if [[ $* == *" --debug "* ]]; then
|
||||
|
||||
@@ -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/
|
||||
###########################################################################################
|
||||
# Written by: ./preseed_hash_generator.sh Version: Master V9.14.020.2026.06.08 at: 10:18:37.9542
|
||||
# Written by: ./preseed_hash_generator.sh Version: Master V9.14.022.2026.06.10 at: 10:18:37.9542
|
||||
|
||||
@@ -89,9 +89,20 @@ Verify_checksums() {
|
||||
|
||||
_KEYFILE=""
|
||||
|
||||
_MANIFEST_FOUND="false"
|
||||
|
||||
_MP=""
|
||||
|
||||
_RETURN_PGP=""
|
||||
|
||||
_RETURN_SHA=""
|
||||
|
||||
_VERIFICATION_EXECUTED="false"
|
||||
|
||||
_VERIFICATION_SUCCEEDED="false"
|
||||
|
||||
### Parse commandline arguments ----------------------------------------------------------------------------------------------
|
||||
# shellcheck disable=SC2154
|
||||
for _PARAMETER in ${LIVE_BOOT_CMDLINE}; do
|
||||
|
||||
case "${_PARAMETER}" in
|
||||
@@ -244,10 +255,12 @@ Verify_checksums() {
|
||||
|
||||
if [ -e "${_CHECKSUM}" ]; then
|
||||
|
||||
_MANIFEST_FOUND="true"
|
||||
log_in "Found: [${_CHECKSUM}] ..."
|
||||
|
||||
if [ -e "/usr/bin/${_DIGEST}sum" ]; then
|
||||
|
||||
_VERIFICATION_EXECUTED="true"
|
||||
log_in "Found: [/usr/bin/${_DIGEST}sum] ..."
|
||||
|
||||
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
|
||||
@@ -279,6 +292,7 @@ Verify_checksums() {
|
||||
if grep -v '^#' "${_CHECKSUM}" | LC_ALL=C /usr/bin/"${_DIGEST}"sum -c > "${_CHECKSUM_LOG}" 2>&1; then
|
||||
|
||||
_RETURN_SHA="${?}"
|
||||
_VERIFICATION_SUCCEEDED="true"
|
||||
cat "${_CHECKSUM_LOG}" > "${_TTY}"
|
||||
log_ok "Found: [/usr/bin/${_DIGEST}sum] successful verified: [${_CHECKSUM}]"
|
||||
|
||||
@@ -313,6 +327,33 @@ Verify_checksums() {
|
||||
log_end_msg
|
||||
printf "\n"
|
||||
|
||||
if [ "${_MANIFEST_FOUND}" != "true" ]; then
|
||||
|
||||
log_er "No supported checksum manifest found."
|
||||
sleep 8
|
||||
panic "No supported checksum manifest found."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then
|
||||
|
||||
log_er "No supported checksum verification tool was available."
|
||||
sleep 8
|
||||
panic "No supported checksum verification tool was available."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then
|
||||
|
||||
log_er "No supported checksum manifest was verified successfully."
|
||||
sleep 8
|
||||
panic "No supported checksum manifest was verified successfully."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
case "${_RETURN_PGP},${_RETURN_SHA}" in
|
||||
|
||||
"0,0")
|
||||
@@ -331,18 +372,28 @@ Verify_checksums() {
|
||||
log_er "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
|
||||
sleep 8
|
||||
panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
|
||||
return 1
|
||||
;;
|
||||
|
||||
*",0")
|
||||
log_er "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
|
||||
sleep 8
|
||||
panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
|
||||
return 1
|
||||
;;
|
||||
|
||||
"na,"*)
|
||||
log_er "Verification of [sha checksum] file failed."
|
||||
sleep 8
|
||||
panic "Verification of [sha checksum] file failed."
|
||||
return 1
|
||||
;;
|
||||
|
||||
*)
|
||||
log_er "Checksum verification ended in an unsupported state."
|
||||
sleep 8
|
||||
panic "Checksum verification ended in an unsupported state."
|
||||
return 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
@@ -15,14 +15,11 @@
|
||||
# SPDX-Security-Contact: security@coresecret.eu
|
||||
|
||||
# Module summary:
|
||||
# - Runs after the encrypted live root filesystem has been decrypted.
|
||||
# - Requires the pinned public key, attestation hash file, and detached signature to exist as readable, non-empty regular files
|
||||
# inside the decrypted rootfs.
|
||||
# - Verifies the attestation signature with gpgv against the pinned key material.
|
||||
# - Confirms that the signature fingerprint matches the build-time expected rootfs fingerprint and panics on missing, malformed,
|
||||
# or mismatched evidence.
|
||||
|
||||
_SAVED_SET_OPTS="$(set +o)"
|
||||
# - Runs after the encrypted live root filesystem has been decrypted and selected for the SquashFS root mount.
|
||||
# - Requires the pinned public key and the signed decrypted-mapper SHA-512 manifest from the mounted live medium.
|
||||
# - Verifies the manifest signature and pinned signer fingerprint, then verifies the complete selected decrypted mapper against
|
||||
# the manifest.
|
||||
# - Panics on missing, malformed, mismatched, or unverifiable evidence.
|
||||
|
||||
set -eu
|
||||
|
||||
@@ -37,9 +34,12 @@ 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 ----------------------
|
||||
export CDLB_MAPPER_NAME="${CDLB_MAPPER_NAME:-crypt_liveiso}"
|
||||
|
||||
### Attestation file locations inside decrypted rootfs. ------------------------------------------------------------------------
|
||||
CDLB_ATTEST_FPR_SHA="${CDLB_ATTEST_FPR_SHA:-/root/root/.ciss/attestation/${CDLB_EXP_FPR}.gpg.sha512sum.txt}"
|
||||
CDLB_ATTEST_FPR_SIG="${CDLB_ATTEST_FPR_SIG:-/root/root/.ciss/attestation/${CDLB_EXP_FPR}.gpg.sha512sum.txt.sig}"
|
||||
### Rootfs selection and attestation file locations. ---------------------------------------------------------------------------
|
||||
CDLB_LUKS_FS="${CDLB_LUKS_FS:-/live/ciss_rootfs.crypt}"
|
||||
CDLB_MAPPER_DEV="${CDLB_MAPPER_DEV:-/dev/mapper/${CDLB_MAPPER_NAME}}"
|
||||
CDLB_MNT_MEDIUM="${CDLB_MNT_MEDIUM:-/run/live/medium}"
|
||||
CDLB_ATTEST_ROOTFS_SHA="${CDLB_ATTEST_ROOTFS_SHA:-${CDLB_MNT_MEDIUM}${CDLB_LUKS_FS}.decrypted.sha512sum.txt}"
|
||||
CDLB_ATTEST_ROOTFS_SIG="${CDLB_ATTEST_ROOTFS_SIG:-${CDLB_ATTEST_ROOTFS_SHA}.sig}"
|
||||
CDLB_KEY_DIR="${CDLB_KEY_DIR:-/etc/ciss/keys}"
|
||||
|
||||
### Declare functions ----------------------------------------------------------------------------------------------------------
|
||||
@@ -91,11 +91,13 @@ require_attestation_file() {
|
||||
|
||||
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}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
log_er "0042() : ${artifact_label} missing: [${artifact_path}]"
|
||||
panic "0042() : ${artifact_label} missing: [${artifact_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
@@ -103,6 +105,7 @@ require_attestation_file() {
|
||||
|
||||
log_er "0042() : ${artifact_label} is not a regular file: [${artifact_path}]"
|
||||
panic "0042() : ${artifact_label} is not a regular file: [${artifact_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
@@ -110,6 +113,7 @@ require_attestation_file() {
|
||||
|
||||
log_er "0042() : ${artifact_label} is empty: [${artifact_path}]"
|
||||
panic "0042() : ${artifact_label} is empty: [${artifact_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
@@ -117,23 +121,56 @@ require_attestation_file() {
|
||||
|
||||
log_er "0042() : ${artifact_label} is not readable: [${artifact_path}]"
|
||||
panic "0042() : ${artifact_label} is not readable: [${artifact_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
HASH_FILE="${CDLB_ATTEST_FPR_SHA}"
|
||||
SIGN_FILE="${CDLB_ATTEST_FPR_SIG}"
|
||||
#######################################
|
||||
# Validate the selected decrypted rootfs payload.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# 1: Absolute payload path
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
require_rootfs_payload() {
|
||||
payload_path="${1}"
|
||||
|
||||
if [ ! -b "${payload_path}" ]; then
|
||||
|
||||
log_er "0042() : Selected rootfs payload is not a block device: [${payload_path}]"
|
||||
panic "0042() : Selected rootfs payload is not a block device: [${payload_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -r "${payload_path}" ]; then
|
||||
|
||||
log_er "0042() : Selected rootfs payload is not readable: [${payload_path}]"
|
||||
panic "0042() : Selected rootfs payload is not readable: [${payload_path}]"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
HASH_FILE="${CDLB_ATTEST_ROOTFS_SHA}"
|
||||
SIGN_FILE="${CDLB_ATTEST_ROOTFS_SIG}"
|
||||
KEYFILE="${CDLB_KEY_DIR}/${CDLB_EXP_FPR}.gpg"
|
||||
|
||||
require_attestation_file "Public key" "${KEYFILE}"
|
||||
require_attestation_file "Attestation data" "${HASH_FILE}"
|
||||
require_attestation_file "Attestation signature" "${SIGN_FILE}"
|
||||
require_attestation_file "Rootfs attestation manifest" "${HASH_FILE}"
|
||||
require_attestation_file "Rootfs attestation signature" "${SIGN_FILE}"
|
||||
require_rootfs_payload "${CDLB_MAPPER_DEV}"
|
||||
|
||||
log_in "0042() : Verifying rootfs attestation with 'gpgv' and inside LUKS encrypted rootfs pinned GPG FPR."
|
||||
log_in "0042() : Verifying signed rootfs attestation manifest with pinned GPG FPR."
|
||||
|
||||
if ! _STATUS="$(/usr/bin/gpgv --keyring "${KEYFILE}" --status-fd 1 "${SIGN_FILE}" "${HASH_FILE}" 2>&1)"; then
|
||||
if ! _STATUS="$(/usr/bin/gpgv --no-default-keyring --keyring "${KEYFILE}" --status-fd 1 "${SIGN_FILE}" "${HASH_FILE}" 2>&1)"; then
|
||||
|
||||
log_er "0042() : gpgv verification failed for signature: [${SIGN_FILE}]"
|
||||
|
||||
@@ -145,6 +182,7 @@ if ! _STATUS="$(/usr/bin/gpgv --keyring "${KEYFILE}" --status-fd 1 "${SIGN_FILE}
|
||||
|
||||
sleep 8
|
||||
panic "0042() : gpgv verification failed for signature: [${SIGN_FILE}]"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
@@ -160,10 +198,51 @@ else
|
||||
log_er "0042() : Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]"
|
||||
sleep 8
|
||||
panic "[FATAL] Signature FPR mismatch: got: [${_CDLB_SIG_FILE_FPR}] expected: [${CDLB_EXP_FPR}]."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
eval "${_SAVED_SET_OPTS}"
|
||||
_ATTEST_RECORD_COUNT="$(awk 'NF && $1 !~ /^#/ { count++ } END { print count + 0 }' "${HASH_FILE}")"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. DNSSEC Status
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Haveged Audit on Netcup RS 2000 G11
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Lynis Audit:
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. SSH Audit by ssh-audit.com
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. TLS Audit:
|
||||
````text
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Hardened Kernel Boot Parameters
|
||||
|
||||
|
||||
+19
-13
@@ -8,11 +8,17 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Changelog
|
||||
|
||||
## V9.14.022.2026.06.10
|
||||
* **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**: [0900_ufw_setup.chroot](../config/hooks/live/0900_ufw_setup.chroot) SSH ufw out exception for Primordial-Workflow™
|
||||
|
||||
## V9.14.020.2026.06.08
|
||||
* **Added**: [bootscreen.txt](../bootscreen.txt)
|
||||
* **Changed**: ``sops 3.13.0`` to ``sops 3.13.1``
|
||||
|
||||
## V9.14.018.2026.06.07
|
||||
@@ -132,7 +138,7 @@ include_toc: true
|
||||
* **Changed**: [lib_check_secrets.sh](../lib/lib_check_secrets.sh) + updated shopt handling.
|
||||
* **Changed**: [lib_ciss_upgrades_boot.sh](../lib/lib_ciss_upgrades_boot.sh) + integrates and generates sha512sum and GPG signatures on CISS specific LIVE boot artifacts.
|
||||
* **Changed**: [lib_gnupg.sh](../lib/lib_gnupg.sh) + integration of optional import of offline GPG CA public keys.
|
||||
* **Changed**: [lib_primordial.sh](../lib/lib_primordial.sh) + Updates for CISS and PhysNet primordial-workflow™.
|
||||
* **Changed**: [lib_primordial.sh](../lib/lib_primordial.sh) + Updates for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Changed**: [lib_usage.sh](../lib/lib_usage.sh) + ``--signing_ca=*``.
|
||||
* **Changed**: [binary_checksums.sh](../scripts/usr/lib/live/build/binary_checksums.sh) + ``! -path './live/filesystem.squashfs'``
|
||||
* **Changed**: [9999_cdi_starter.sh](../scripts/usr/local/sbin/9999_cdi_starter.sh) + increased verbosity.
|
||||
@@ -186,10 +192,10 @@ include_toc: true
|
||||
* **Added**: [marc_s_weidner_msw+deploy@coresecet.dev_0x2CCF4601_public.asc](../.pubkey/marc_s_weidner_msw%2Bdeploy%40coresecet.dev_0x2CCF4601_public.asc)
|
||||
* **Added**: [0870_bashdb.chroot](../config/hooks/live/0870_bashdb.chroot) bashdb debugger https://github.com/Trepan-Debuggers/bashdb.git
|
||||
* **Added**: [0030-ciss-verify-checksums](../config/includes.chroot/usr/lib/live/boot/0030-ciss-verify-checksums) Unified handling via includes.chroot.
|
||||
* **Added**: [lib_ciss_upgrades_boot.sh](../lib/lib_ciss_upgrades_boot.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_primordial.sh](../lib/lib_primordial.sh) Updates for CISS and PhysNet primordial-workflow™.
|
||||
* **Added**: [lib_ciss_upgrades_boot.sh](../lib/lib_ciss_upgrades_boot.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_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.
|
||||
* **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}"
|
||||
@@ -197,11 +203,11 @@ include_toc: true
|
||||
* **Changed**: [generate_PRIVATE_trixie_1.yaml](../.gitea/workflows/generate_PRIVATE_trixie_1.yaml) Rewritten for new secrets handling.
|
||||
* **Changed**: [0000_basic_chroot_setup.chroot](../config/hooks/live/0000_basic_chroot_setup.chroot) + VAR_DATE improvements.
|
||||
* **Changed**: [0001_initramfs_modules.chroot](../config/hooks/live/0001_initramfs_modules.chroot) + VAR_DATE improvements.
|
||||
* **Changed**: [9930_hardening_ssh.chroot](../config/hooks/live/9930_hardening_ssh.chroot) Rewritten for CISS and PhysNet primordial-workflow™.
|
||||
* **Changed**: [9930_hardening_ssh.chroot](../config/hooks/live/9930_hardening_ssh.chroot) Rewritten for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Changed**: [9999_zzzz.chroot](../config/hooks/live/9999_zzzz.chroot) + Final update-initramfs
|
||||
* **Changed**: [sshd_config](../config/includes.chroot/etc/ssh/sshd_config) + Less strict MaxStartups settings.
|
||||
* **Changed**: [live.list.common.chroot](../config/package-lists/live.list.common.chroot) + tmux
|
||||
* **Changed**: [lib_arg_parser.sh](../lib/lib_arg_parser.sh) Rewritten for CISS and PhysNet primordial-workflow™.
|
||||
* **Changed**: [lib_arg_parser.sh](../lib/lib_arg_parser.sh) Rewritten for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Changed**: [lib_arg_priority_check.sh](../lib/lib_arg_priority_check.sh) Unified UI.
|
||||
* **Changed**: [lib_cdi.sh](../lib/lib_cdi.sh) + Commandline parameters: verify-checksums=sha512,sha384 verify-checksums-signatures
|
||||
* **Changed**: [lib_change_splash.sh](../lib/lib_change_splash.sh) Unified UI.
|
||||
@@ -210,11 +216,11 @@ include_toc: true
|
||||
* **Changed**: [lib_check_kernel.sh](../lib/lib_check_kernel.sh) Minor declare unification.
|
||||
* **Changed**: [lib_check_pkgs.sh](../lib/lib_check_pkgs.sh) Improved command checks. Unified UI.
|
||||
* **Changed**: [lib_check_provider.sh](../lib/lib_check_provider.sh) Unified variables.
|
||||
* **Changed**: [lib_clean_up.sh](../lib/lib_clean_up.sh) Secure deletion of CISS and PhysNet primordial-workflow™ artifacts.
|
||||
* **Changed**: [lib_clean_up.sh](../lib/lib_clean_up.sh) Secure deletion of CISS and PhysNet Primordial-Workflow™ artifacts.
|
||||
* **Changed**: [lib_debug.sh](../lib/lib_debug.sh) + Integrated EPOCH in PS4.
|
||||
* **Changed**: [lib_debug_header.sh](../lib/lib_debug_header.sh) + Integrated SOURCE_DATE_EPOCH.
|
||||
* **Changed**: [lib_hardening_root_pw.sh](../lib/lib_hardening_root_pw.sh) Unified UI.
|
||||
* **Changed**: [lib_hardening_ultra.sh](../lib/lib_hardening_ultra.sh) Rewritten for CISS and PhysNet primordial-workflow™.
|
||||
* **Changed**: [lib_hardening_ultra.sh](../lib/lib_hardening_ultra.sh) Rewritten for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Changed**: [lib_hardening_ssh_tcp.sh](../lib/lib_hardening_ssh_tcp.sh) Unified UI.
|
||||
* **Changed**: [lib_lb_build_start.sh](../lib/lib_lb_build_start.sh) Deterministic return code examination.
|
||||
* **Changed**: [lib_lb_config_start.sh](../lib/lib_lb_config_start.sh) Removed potential disown race condition.
|
||||
@@ -254,11 +260,11 @@ include_toc: true
|
||||
## V8.13.290.2025.10.26
|
||||
* **Updated**: [0001_initramfs_modules.chroot](../config/hooks/live/0001_initramfs_modules.chroot) + ESP/FAT/UEFI mods
|
||||
* **Updated**: [9950_hardening_fail2ban.chroot](../config/hooks/live/9950_hardening_fail2ban.chroot)
|
||||
* **Updated**: [9999-cdi-starter](../scripts/usr/local/sbin/9999_cdi_starter.sh) Preparations for CISS and PhysNet primordial-workflow™.
|
||||
* **Updated**: [9999-cdi-starter](../scripts/usr/local/sbin/9999_cdi_starter.sh) Preparations for CISS and PhysNet Primordial-Workflow™.
|
||||
|
||||
## V8.13.288.2025.10.24
|
||||
* **Added**: Preparations for CISS and PhysNet primordial-workflow™.
|
||||
* **Added**: [0865_yq.chroot](../config/hooks/live/0865_yq.chroot)Preparations for CISS and PhysNet primordial-workflow™.
|
||||
* **Added**: Preparations for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Added**: [0865_yq.chroot](../config/hooks/live/0865_yq.chroot)Preparations for CISS and PhysNet Primordial-Workflow™.
|
||||
* **Updated**: [0001_initramfs_modules.chroot](../config/hooks/live/0001_initramfs_modules.chroot) + nftables mods
|
||||
* **Updated**: [9950_hardening_fail2ban.chroot](../config/hooks/live/9950_hardening_fail2ban.chroot) + banaction = nftables-*
|
||||
* **Updated**: [0900_ufw_setup.chroot](../config/hooks/live/0900_ufw_setup.chroot) changed var injection
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Centurion Net - Developer Branch Overview
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Purpose
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Contributing / participating
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Credits
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Download the latest PUBLIC CISS.debian.live.ISO
|
||||
|
||||
|
||||
+21
-3
@@ -8,14 +8,14 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2.1. Usage
|
||||
````text
|
||||
CDLB(1) CISS.debian.live.builder CDLB(1)
|
||||
|
||||
CISS.debian.live.builder from https://git.coresecret.dev/msw
|
||||
Master V9.14.020.2026.06.08
|
||||
Master V9.14.022.2026.06.10
|
||||
A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
|
||||
|
||||
(c) Marc S. Weidner, 2018 - 2026
|
||||
@@ -98,6 +98,24 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
|
||||
Provides statistic only after successful building a CISS.debian.live-ISO. While enabling '--log-statistics-only'
|
||||
the argument '--build-directory' MUST be provided.
|
||||
|
||||
--primordial-key <ssh-identity-filename>
|
||||
SSH identity filename for the Primordial overlay clone. This MUST be a filename only; the runtime path is derived as
|
||||
'/root/.ssh/<ssh-identity-filename>'.
|
||||
Example fragment:
|
||||
./ciss_live_builder.sh --primordial-url https://git.coresecret.dev/ahz/PhysNet.primordial.git \
|
||||
--primordial-key id--git.coresecret.dev--PhysNet.primordial_deploy--ed25519--newton--2025-10 \
|
||||
--primordial-ssh 42842
|
||||
|
||||
--primordial-ssh <INTEGER>
|
||||
Adds one outgoing UFW TCP exception for a bootstrap/recovery SSH port.
|
||||
Outgoing only: no incoming firewall rule is added, and this option does not replace '--ssh-port'.
|
||||
Effective only when the Live System's UFW outgoing policy is 'deny'.
|
||||
Port MUST be a decimal integer between '1' and '65535'.
|
||||
|
||||
--primordial-url <https-git-url>
|
||||
HTTPS Git repository URL for the Primordial CDI overlay. MUST start with 'https://', include a host and path, and end in
|
||||
'.git'. The CDI starter converts this URL to an SSH clone URL at runtime.
|
||||
|
||||
--provider-netcup-ipv6
|
||||
Activates IPv6 support for Netcup Root Server. One unique IPv6 address MUST be provided in this case and MUST be
|
||||
encapsulated with [], e.g., [1234::abcd].
|
||||
@@ -168,7 +186,7 @@ A lightweight Shell Wrapper for building a hardened Debian Live ISO Image.
|
||||
💷 Please consider donating to my work at:
|
||||
🌐 https://coresecret.eu/spenden/
|
||||
|
||||
V9.14.020.2026.06.08 2026-05-17 CDLB(1)
|
||||
V9.14.022.2026.06.10 2026-05-17 CDLB(1)
|
||||
````
|
||||
|
||||
# 3. Booting
|
||||
|
||||
@@ -8,23 +8,28 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. CISS.debian.live.builder – Boot & Trust Chain (Technical Documentation)
|
||||
|
||||
**Status:** 2025-11-12<br>
|
||||
**Status:** 2026-06-10<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 early ISO-edge check (signature and FPR pin) *before* LUKS unlock, and a late root-FS attestation *after* unlock, reinforced by `dm-crypt (AES-XTS)` and `dm-integrity (HMAC-SHA-512)`. 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>
|
||||
**Summary:** The **CISS.debian.live.builder** Live-ISO establishes a two-stage verification chain around the live root: an
|
||||
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
|
||||
|
||||
* **Trust anchor:** Pinned fingerprint (FPR) of the signing key embedded at build time in initramfs hooks.
|
||||
* **Integrity & authenticity verification:**
|
||||
|
||||
1. **Early:** Verify `sha512sum.txt` at the ISO edge using `gpgv` and FPR pin.
|
||||
2. **Late:** Verify an attestation hash list inside the decrypted root FS using `gpgv` and FPR pin.
|
||||
1. **ISO edge:** Verify one supported checksum manifest using `gpgv`, FPR pinning, and the matching checksum tool.
|
||||
2. **Late rootfs attestation:** Verify the signed mapper manifest and the complete selected decrypted mapper
|
||||
`/dev/mapper/crypt_liveiso` with `sha512sum -c`.
|
||||
|
||||
* **Storage-level AEAD (functional):** `dm-crypt` (AES-XTS-512) and `dm-integrity` (HMAC-SHA-512, 4 KiB).
|
||||
* **Storage-level protection:** `dm-crypt` (AES-XTS-512) and, outside runner builds, `dm-integrity` (HMAC-SHA-512, 4 KiB).
|
||||
* **Remotely unlock:** CISS hardened and build dropbear, modern primitives only, no passwords, no agent/forwarding.
|
||||
|
||||
# 3.1. Secure Boot Profiles
|
||||
@@ -52,11 +57,11 @@ private Secure Boot key names are detected in those paths before live-build chec
|
||||
| Component | Primitive / Parameter | Purpose |
|
||||
|--------------|-----------------------------------------------------------|--------------------------------------------------------|
|
||||
| LUKS2 | `aes-xts-plain64`, `--key-size 512`, `--sector-size 4096` | Confidentiality (2×256-bit XTS) |
|
||||
| dm-integrity | `hmac-sha512` (keyed), journal | Adversary-resistant per-sector integrity, authenticity |
|
||||
| dm-integrity | `hmac-sha512` (keyed), journal | Per-sector integrity inside the LUKS mapping; not origin attestation |
|
||||
| PBKDF | `argon2id`, `--iter-time 1000` ms | Key derivation, hardware-agnostic |
|
||||
| Signatures | Ed25519 or RSA-4096 (FPR pinned) | Public verifiability, non-repudiation |
|
||||
| Verification | `gpgv --no-default-keyring` | No agent dependency in initramfs |
|
||||
| Hash lists | `sha512sum` format | Deterministic content verification |
|
||||
| Hash lists | `sha512sum` format | Deterministic ISO-edge and decrypted-mapper verification |
|
||||
| Dropbear | Modern KEX/AEAD (per `localoptions.h`) | Minimal attack surface, remote unlock |
|
||||
|
||||
# 5. Diagram: CISS Live ISO Boot Flow
|
||||
@@ -150,7 +155,8 @@ flowchart TD
|
||||
|
||||
```
|
||||
|
||||
**Note:** Encrypt-then-MAC at the block layer (functionally AEAD-equivalent). Any manipulation ⇒ hard I/O error.
|
||||
**Note:** `dm-integrity` detects sector corruption within its keyed mapping. The signed SHA-512 mapper manifest independently
|
||||
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
|
||||
```sh
|
||||
@@ -172,16 +178,24 @@ cryptsetup luksFormat \
|
||||
"${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).
|
||||
|
||||
# 8. Early ISO-Edge Verification (CISS modified hook 0030-ciss-verify-checksums, live-bottom)
|
||||
|
||||
**Goal:** Before consuming any medium content, verify:
|
||||
**Goal:** During live-boot, require one supported ISO-edge checksum manifest to be successfully verified:
|
||||
|
||||
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.
|
||||
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):**
|
||||
|
||||
```sh
|
||||
@@ -189,12 +203,16 @@ cryptsetup luksFormat \
|
||||
# parse [GNUPG:] VALIDSIG ... <FPR> ...
|
||||
```
|
||||
|
||||
# 9. Late Root-FS Attestation and dmsetup Health (CISS hook 0042_ciss_post_decrypt_attest, called by 9990-overlay.sh)
|
||||
# 9. Late Root-FS Payload Attestation (CISS hook 0042_ciss_post_decrypt_attest, called by 9990-overlay.sh)
|
||||
|
||||
**Goal:** After LUKS unlock, validate the **decrypted** contents and the **actual** mapping topology.
|
||||
**Goal:** After LUKS unlock and rootfs selection, verify the authenticity of the manifest and the content of the actual selected
|
||||
decrypted rootfs payload.
|
||||
|
||||
* **Attestation files:** `/root/.ciss/attestation/<FPR>.sha512sum.txt[.sig]`
|
||||
* **Key source:** `/etc/ciss/keys/*.gpg` (accepted only if FPR == build-pin)
|
||||
* **Exact attested boundary:** the complete `/dev/mapper/crypt_liveiso` block payload selected by `9990-overlay.sh` and mounted
|
||||
read-only as SquashFS, including mapper padding after the SquashFS image.
|
||||
* **Attestation files:** `/run/live/medium/live/ciss_rootfs.crypt.decrypted.sha512sum.txt[.sig]`
|
||||
* **Key source:** `/etc/ciss/keys/<FPR>.gpg` in the initramfs; the valid signature FPR must equal the build-time pin.
|
||||
* **Manifest constraint:** exactly one checksum record is accepted, and it must target the selected mapper path.
|
||||
|
||||
**Core calls (initramfs):**
|
||||
|
||||
@@ -202,13 +220,20 @@ cryptsetup luksFormat \
|
||||
# 1) Signature and FPR pin (no agent)
|
||||
/usr/bin/gpgv --no-default-keyring --keyring "$KEYFILE" --status-fd 1 --verify "$SIG" "$DATA"
|
||||
|
||||
# 2) Optional: Content hash verification
|
||||
( cd "$ROOTMP" && /usr/bin/sha512sum -c --strict --quiet "$DATA" )
|
||||
# 2) Required selected-payload verification
|
||||
( cd / && /usr/bin/sha512sum -c --strict --quiet "$DATA" )
|
||||
```
|
||||
|
||||
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)
|
||||
|
||||
* **Abort** on: missing `VALIDSIG`, FPR mismatch, missing key / signature.
|
||||
* **ISO-edge abort:** no supported manifest, no supported verification tool, failed checksum, failed requested signature, or
|
||||
unknown verification state.
|
||||
* **Rootfs-attestation abort:** missing or malformed manifest/signature/key, missing `VALIDSIG`, FPR mismatch, manifest target
|
||||
mismatch, unreadable or non-block selected mapper, or mapper checksum mismatch.
|
||||
|
||||
# 11. CISS hardened and built dropbear
|
||||
|
||||
@@ -251,17 +276,19 @@ flowchart TD
|
||||
subgraph ISO Build Time
|
||||
A["Embed and pin GPG FPR (into ISO & RootFS as needed)"] e00@--> B["Generate ISO-edge sha512sum.txt and .sig"];
|
||||
B e01@--> C["Build filesystem.squashfs and wrap it into ciss_rootfs.crypt"];
|
||||
C e01a@--> C2["Hash complete decrypted mapper and sign rootfs manifest"];
|
||||
e00@{ animation: fast }
|
||||
e01@{ animation: fast }
|
||||
e01a@{ animation: fast }
|
||||
end
|
||||
|
||||
subgraph ISO Boot Time
|
||||
C e02@--> D["0024 LUKS2, dm-integrity HMAC-SHA512"];
|
||||
C2 e02@--> D["0024 LUKS2, dm-integrity HMAC-SHA512"];
|
||||
D e03@-->|SUCCESSFUL| E["ciss_rootfs.crypt opened"];
|
||||
E e04@--> F["Mounting RootFS"];
|
||||
F e05@--> G["0030 verification of authenticity and integrity via embedded and pinned GPG of ISO edge"];
|
||||
G e06@-->|SUCCESSFUL| H["ISO edge verified"];
|
||||
H e07@--> I["0042 post-decrypt-attestation of RootFS"];
|
||||
H e07@--> I["0042 verifies signed manifest and selected decrypted mapper"];
|
||||
I e08@-->|SUCCESSFUL| J["RootFS attestation successful"];
|
||||
e02@{ animation: fast }
|
||||
e03@{ animation: fast }
|
||||
@@ -285,7 +312,9 @@ I -- FAIL --> X;
|
||||
|
||||
# 14. Closing Remarks
|
||||
|
||||
This achieves a portable, self-contained trust chain without a Microsoft-db, providing strong protection against medium tampering, bitrot, and active attacks **both before and after decryption**. The dual-verification phases make the state transparent and deterministic.
|
||||
The verification path is fail-closed and binds the selected decrypted rootfs mapper to the pinned signing key. `dm-integrity`
|
||||
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/)**
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. SSH Host Key Policy – CISS.debian.live.builder / CISS.debian.installer
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. Resources
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. ``30-ciss-hardening.conf``
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. ``90-ciss-local.hardened``
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ include_toc: true
|
||||
**Centurion Intelligence Consulting Agency Information Security Standard**<br>
|
||||
*Debian Live Build Generator for hardened live environment and CISS Debian Installer*<br>
|
||||
**Master Version**: 9.14<br>
|
||||
**Build**: V9.14.020.2026.06.08<br>
|
||||
**Build**: V9.14.022.2026.06.10<br>
|
||||
|
||||
# 2. ``ciss_live_builder.sh``
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
|
||||
# VAR_ISO8601
|
||||
# VAR_LUKS
|
||||
# VAR_LUKS_KEY
|
||||
# VAR_PRIMORDIAL_KEY
|
||||
# VAR_PRIMORDIAL_SSH_PORT
|
||||
# VAR_PRIMORDIAL_URL
|
||||
# VAR_REIONICE_CLASS
|
||||
# VAR_REIONICE_PRIORITY
|
||||
# VAR_SIGNER
|
||||
@@ -73,6 +76,9 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
|
||||
# ERR__SSH__PORT: on failure
|
||||
#######################################
|
||||
arg_parser() {
|
||||
declare primordial_key_regex='^[A-Za-z0-9._@%+=:,~-]+$'
|
||||
declare primordial_url_regex='^https://[A-Za-z0-9.-]+/[A-Za-z0-9._~/%+=:@,-]+\.git$'
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
|
||||
declare argument="${1}"
|
||||
@@ -287,6 +293,99 @@ arg_parser() {
|
||||
shift 1
|
||||
;;
|
||||
|
||||
--primordial-key)
|
||||
declare primordial_key="${2-}"
|
||||
|
||||
if [[ -n "${primordial_key}" && "${primordial_key}" != -* && "${primordial_key}" != "." && "${primordial_key}" != ".." && "${primordial_key}" != */* && "${primordial_key}" =~ ${primordial_key_regex} ]]; then
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}"
|
||||
shift 2
|
||||
|
||||
else
|
||||
|
||||
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
|
||||
printf "\e[91m❌ Error: --primordial-key MUST be a filename matching '^[A-Za-z0-9._@%%+=:,~-]+$' and MUST NOT be '.', '..', or contain '/'.\e[0m\n" >&2
|
||||
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
exit "${ERR_ARG_MSMTCH}"
|
||||
|
||||
fi
|
||||
;;
|
||||
|
||||
--primordial-key=*)
|
||||
declare primordial_key="${1#*=}"
|
||||
|
||||
if [[ -n "${primordial_key}" && "${primordial_key}" != "." && "${primordial_key}" != ".." && "${primordial_key}" != */* && "${primordial_key}" =~ ${primordial_key_regex} ]]; then
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -gx VAR_PRIMORDIAL_KEY="${primordial_key}"
|
||||
shift 1
|
||||
|
||||
else
|
||||
|
||||
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
|
||||
printf "\e[91m❌ Error: --primordial-key MUST be a filename matching '^[A-Za-z0-9._@%%+=:,~-]+$' and MUST NOT be '.', '..', or contain '/'.\e[0m\n" >&2
|
||||
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
exit "${ERR_ARG_MSMTCH}"
|
||||
|
||||
fi
|
||||
;;
|
||||
|
||||
--primordial-ssh)
|
||||
if [[ -n "${2-}" && "${2}" =~ ^-?[0-9]+$ && "${2}" -ge 1 && "${2}" -le 65535 ]]; then
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -gix VAR_PRIMORDIAL_SSH_PORT="${2}"
|
||||
shift 2
|
||||
|
||||
else
|
||||
|
||||
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
|
||||
printf "\e[91m❌ Error: --primordial-ssh MUST be an integer between '1' and '65535'.\e[0m\n" >&2
|
||||
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
exit "${ERR__SSH__PORT}"
|
||||
|
||||
fi
|
||||
;;
|
||||
|
||||
--primordial-url)
|
||||
declare primordial_url="${2-}"
|
||||
|
||||
if [[ -n "${primordial_url}" && "${primordial_url}" != -* && "${primordial_url}" =~ ${primordial_url_regex} ]]; then
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -gx VAR_PRIMORDIAL_URL="${primordial_url}"
|
||||
shift 2
|
||||
|
||||
else
|
||||
|
||||
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
|
||||
printf "\e[91m❌ Error: --primordial-url MUST be an HTTPS Git URL with non-empty host, non-empty path, and '.git' suffix.\e[0m\n" >&2
|
||||
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
exit "${ERR_ARG_MSMTCH}"
|
||||
|
||||
fi
|
||||
;;
|
||||
|
||||
--primordial-url=*)
|
||||
declare primordial_url="${1#*=}"
|
||||
|
||||
if [[ -n "${primordial_url}" && "${primordial_url}" =~ ${primordial_url_regex} ]]; then
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -gx VAR_PRIMORDIAL_URL="${primordial_url}"
|
||||
shift 1
|
||||
|
||||
else
|
||||
|
||||
if ! ${VAR_HANDLER_AUTOBUILD}; then boot_screen_cleaner; fi
|
||||
printf "\e[91m❌ Error: --primordial-url MUST be an HTTPS Git URL with non-empty host, non-empty path, and '.git' suffix.\e[0m\n" >&2
|
||||
read -p -r $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
exit "${ERR_ARG_MSMTCH}"
|
||||
|
||||
fi
|
||||
;;
|
||||
|
||||
--provider-netcup-ipv6)
|
||||
if [[ -n "${2-}" && "${2}" != -* ]]; then
|
||||
declare -i count=0
|
||||
|
||||
+17
-1
@@ -19,6 +19,9 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
|
||||
# VAR_HANDLER_BUILD_DIR
|
||||
# VAR_HANDLER_CDI
|
||||
# VAR_KERNEL
|
||||
# VAR_PRIMORDIAL_KEY
|
||||
# VAR_PRIMORDIAL_SSH_PORT
|
||||
# VAR_PRIMORDIAL_URL
|
||||
# VAR_WORKDIR
|
||||
# Arguments:
|
||||
# None
|
||||
@@ -38,7 +41,20 @@ cdi() {
|
||||
|
||||
fi
|
||||
|
||||
install -m 0755 -o root -g root "${VAR_WORKDIR}/scripts/usr/local/sbin/9999_cdi_starter.sh" "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/usr/local/sbin/9999_cdi_starter.sh"
|
||||
declare var_cdi_starter="${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/usr/local/sbin/9999_cdi_starter.sh"
|
||||
declare var_primordial_key_q="" var_primordial_ssh_port_q="" var_primordial_url_q=""
|
||||
|
||||
install -m 0755 -o root -g root "${VAR_WORKDIR}/scripts/usr/local/sbin/9999_cdi_starter.sh" "${var_cdi_starter}"
|
||||
|
||||
printf -v var_primordial_key_q '%q' "${VAR_PRIMORDIAL_KEY:-}"
|
||||
printf -v var_primordial_ssh_port_q '%q' "${VAR_PRIMORDIAL_SSH_PORT:-}"
|
||||
printf -v var_primordial_url_q '%q' "${VAR_PRIMORDIAL_URL:-}"
|
||||
|
||||
sed -i \
|
||||
-e "s|^declare -gx VAR_PRIMORDIAL_KEY=.*$|declare -gx VAR_PRIMORDIAL_KEY=${var_primordial_key_q} # Primordial SSH identity filename.|" \
|
||||
-e "s|^declare -gx VAR_PRIMORDIAL_SSH_PORT=.*$|declare -gx VAR_PRIMORDIAL_SSH_PORT=${var_primordial_ssh_port_q} # Primordial SSH port.|" \
|
||||
-e "s|^declare -gx VAR_PRIMORDIAL_URL=.*$|declare -gx VAR_PRIMORDIAL_URL=${var_primordial_url_q} # Primordial HTTPS Git URL.|" \
|
||||
"${var_cdi_starter}"
|
||||
|
||||
declare tmp_entry
|
||||
tmp_entry="$(mktemp)"
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
# 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}"
|
||||
|
||||
#######################################
|
||||
# Integrates and generates sha512sum and GPG signatures on CISS specific LIVE boot artifacts:
|
||||
# - /root/.ciss/attestation/VAR_SIGNING_KEY_FPR.*
|
||||
# - /etc/initramfs-tools/files/unlock_wrapper.sh
|
||||
# - /usr/lib/live/boot/0030-ciss-verify-checksums
|
||||
# Globals:
|
||||
@@ -31,10 +31,7 @@ guard_sourcing || return "${ERR_GUARD_SRCE}"
|
||||
ciss_upgrades_boot() {
|
||||
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=(
|
||||
"/root/.ciss/attestation/${VAR_SIGNING_KEY_FPR}.gpg"
|
||||
"/etc/initramfs-tools/files/unlock_wrapper.sh"
|
||||
"/usr/lib/live/boot/0030-ciss-verify-checksums"
|
||||
)
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
guard_sourcing || return "${ERR_GUARD_SRCE}"
|
||||
|
||||
#######################################
|
||||
# Module for accompanying all 'CISS.debian.hardening' features into the Live ISO image.
|
||||
# Module for following all 'CISS.debian.hardening' features into the Live ISO image.
|
||||
# Globals:
|
||||
# ARY_HANDLER_JUMPHOST
|
||||
# ARY_HANDLER_JUMPHOST_UNIQUE
|
||||
# BASH_SOURCE
|
||||
# VAR_ARCHITECTURE
|
||||
# VAR_HANDLER_BUILD_DIR
|
||||
# VAR_PRIMORDIAL_SSH_PORT
|
||||
# VAR_SSHFP
|
||||
# VAR_SSHPORT
|
||||
# VAR_SSHPUBKEY
|
||||
@@ -196,12 +197,26 @@ hardening_ultra() {
|
||||
sed -i "s|PORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot"
|
||||
|
||||
### /config/hooks/live/0900_ufw_setup.chroot
|
||||
sed -i "s|SSHPORT_MUST_BE_SET|${sshport}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
|
||||
declare ufw_file="${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
|
||||
sed -i "s|SSHPORT_MUST_BE_SET|${sshport}|g" "${ufw_file}"
|
||||
|
||||
declare primordial_ssh_port="${VAR_PRIMORDIAL_SSH_PORT:-}"
|
||||
if [[ -n "${primordial_ssh_port}" ]]; then
|
||||
|
||||
sed -i "s|^# PRIMORDIAL_SSH_PORT_DECLARATION_MUST_BE_SET$|declare -r PRIMORDIAL_SSH_PORT=\"${primordial_ssh_port}\"|" "${ufw_file}"
|
||||
sed -i "s|^[[:space:]]*# PRIMORDIAL_SSH_RULE_MUST_BE_SET$| ufw allow out \"\${PRIMORDIAL_SSH_PORT}\"/tcp comment 'Outgoing Primordial SSH'|" "${ufw_file}"
|
||||
|
||||
else
|
||||
|
||||
sed -i '/^# PRIMORDIAL_SSH_PORT_DECLARATION_MUST_BE_SET$/d' "${ufw_file}"
|
||||
sed -i '/^[[:space:]]*# PRIMORDIAL_SSH_RULE_MUST_BE_SET$/d' "${ufw_file}"
|
||||
|
||||
fi
|
||||
|
||||
### /config/hooks/live/0900_ufw_setup.chroot
|
||||
if [[ ${#ARY_HANDLER_JUMPHOST[@]} -gt 0 ]]; then
|
||||
|
||||
declare file="${VAR_HANDLER_BUILD_DIR}/config/hooks/live/0900_ufw_setup.chroot"
|
||||
declare file="${ufw_file}"
|
||||
|
||||
sed -i "/^ufw allow in \"\${SSHPORT}\"\/tcp comment 'Incoming SSH (Custom-Port)'$/d" "${file}"
|
||||
|
||||
@@ -251,7 +266,7 @@ hardening_ultra() {
|
||||
### ./config/hooks/live/9950_hardening_fail2ban.chroot -----------------------------------------------------------------------
|
||||
if ((${#ARY_HANDLER_JUMPHOST[@]} > 0)); then
|
||||
|
||||
printf "\e[95m🧪 Updating fail2ban Jumphosts IPs ... \e[0m\n"
|
||||
printf "\e[95m🧪 Updating fail2ban Jump-hosts IPs ... \e[0m\n"
|
||||
|
||||
# Join array entries with spaces, preserving any newlines
|
||||
declare ips="${ARY_HANDLER_JUMPHOST[*]}"
|
||||
@@ -265,7 +280,7 @@ hardening_ultra() {
|
||||
# Perform an in-place replacement of IGNORE_IP_MUST_BE_SET with the cleaned list
|
||||
sed -i -E "/^[[:space:]]*ignoreip[[:space:]]*=/ s|IGNORE_IP_MUST_BE_SET|${flat_ips}|g" "${VAR_HANDLER_BUILD_DIR}/config/hooks/live/9950_hardening_fail2ban.chroot"
|
||||
|
||||
printf "\e[92m✅ Updating fail2ban Jumphosts IPs done. \e[0m\n"
|
||||
printf "\e[92m✅ Updating fail2ban Jump-hosts IPs done. \e[0m\n"
|
||||
|
||||
else
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# SPDX-Version: 3.0
|
||||
# SPDX-CreationInfo: 2026-06-10; 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
|
||||
|
||||
#######################################
|
||||
# Logo Wrapper CISS.debian.live.builder
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# None
|
||||
# Returns:
|
||||
# 0: on success
|
||||
#######################################
|
||||
logo() {
|
||||
clear
|
||||
printf '\033[95m'
|
||||
cat centurion.txt
|
||||
printf '\033[0m\n'
|
||||
sleep 4
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f logo
|
||||
# vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh
|
||||
@@ -90,7 +90,7 @@ init_primordial() {
|
||||
|
||||
fi
|
||||
|
||||
### Check for SSH CISS and PhysNet primordial-workflow(tm) integration -------------------------------------------------------
|
||||
### Check for SSH CISS and PhysNet Primordial-Workflow™ integration -------------------------------------------------------
|
||||
if [[ "${VAR_SSHFP,,}" == "true" ]]; then
|
||||
|
||||
install -d -m 0700 "${VAR_HANDLER_BUILD_DIR}/config/includes.chroot/root/.ssh"
|
||||
|
||||
@@ -55,7 +55,7 @@ sanitize_arg() {
|
||||
{
|
||||
printf "❌ Control character : '%s'. \n" "${disallowed_ctrl}"
|
||||
printf "❌ in argument : '%s'. \n" "${input}"
|
||||
printf "❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - + space' \n"
|
||||
printf "❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" @ %% , ~ - + space' \n"
|
||||
printf "\n"
|
||||
} >> "${LOG_ERROR}"
|
||||
|
||||
@@ -63,7 +63,7 @@ sanitize_arg() {
|
||||
|
||||
printf "\e[91m❌ Control character : '%s'. \e[0m\n" "${disallowed_ctrl}" >&2
|
||||
printf "\e[91m❌ in argument : '%s'. \e[0m\n" "${input}" >&2
|
||||
printf "\e[91m❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - + space' \e[0m\n" >&2
|
||||
printf "\e[91m❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" @ %% , ~ - + space' \e[0m\n" >&2
|
||||
|
||||
# shellcheck disable=SC2162
|
||||
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
@@ -73,8 +73,8 @@ sanitize_arg() {
|
||||
fi
|
||||
|
||||
### Step 2: Define allowed characters:
|
||||
### letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, hyphen, space.
|
||||
declare allowed='a-zA-Z0-9._/=\[\]:"\-+ '
|
||||
### letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, @, %, comma, tilde, hyphen, plus, space.
|
||||
declare allowed='a-zA-Z0-9._/=\[\]:"@%,~\-+ '
|
||||
declare disallowed
|
||||
disallowed=$(printf '%s' "${input}" | tr -d "${allowed}")
|
||||
|
||||
@@ -82,7 +82,7 @@ sanitize_arg() {
|
||||
{
|
||||
printf "❌ Invalid character : '%s'. \n" "${disallowed//?/& }"
|
||||
printf "❌ in argument : '%s'. \n" "${input}"
|
||||
printf "❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - + space' \n"
|
||||
printf "❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" @ %% , ~ - + space' \n"
|
||||
printf "\n"
|
||||
} >> "${LOG_ERROR}"
|
||||
|
||||
@@ -90,7 +90,7 @@ sanitize_arg() {
|
||||
|
||||
printf "\e[91m❌ Invalid character : '%s'. \e[0m\n" "${disallowed//?/& }" >&2
|
||||
printf "\e[91m❌ in argument : '%s'. \e[0m\n" "${input}" >&2
|
||||
printf "\e[91m❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" - + space' \e[0m\n" >&2
|
||||
printf "\e[91m❌ Allowed Characters : 'a-z A-Z 0-9 . _ / = [ ] : \" @ %% , ~ - + space' \e[0m\n" >&2
|
||||
|
||||
# shellcheck disable=SC2162
|
||||
read -p $'\e[92m✅ Press \'ENTER\' to exit the script ... \e[0m'
|
||||
@@ -119,8 +119,8 @@ readonly -f sanitize_arg
|
||||
sanitize_string() {
|
||||
declare input="$1"
|
||||
### Define allowed characters:
|
||||
### letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, hyphen, space.
|
||||
declare allowed='a-zA-Z0-9._/=\[\]:"\-+ '
|
||||
### letters, digits, dot, underscore, slash, equals, [, ], colon, double-quote, @, %, comma, tilde, hyphen, plus, space.
|
||||
declare allowed='a-zA-Z0-9._/=\[\]:"@%,~\-+ '
|
||||
printf '%s' "${input}" | tr -cd "${allowed}"
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
|
||||
+20
-2
@@ -39,13 +39,13 @@ usage() {
|
||||
# shellcheck disable=SC2155
|
||||
declare var_header=$(center "CDLB(1) CISS.debian.live.builder CDLB(1)" "${var_cols}")
|
||||
# shellcheck disable=SC2155
|
||||
declare var_footer=$(center "V9.14.020.2026.06.08 2026-06-08 CDLB(1)" "${var_cols}")
|
||||
declare var_footer=$(center "V9.14.022.2026.06.10 2026-06-10 CDLB(1)" "${var_cols}")
|
||||
|
||||
{
|
||||
echo -e "\e[1;97m${var_header}\e[0m"
|
||||
echo
|
||||
echo -e "\e[92mCISS.debian.live.builder from https://git.coresecret.dev/msw \e[0m"
|
||||
echo -e "\e[92mMaster V9.14.020.2026.06.08\e[0m"
|
||||
echo -e "\e[92mMaster V9.14.022.2026.06.10\e[0m"
|
||||
echo -e "\e[92mA lightweight Shell Wrapper for building a hardened Debian Live ISO Image.\e[0m"
|
||||
echo
|
||||
echo -e "\e[97m(c) Marc S. Weidner, 2018 - 2026 \e[0m"
|
||||
@@ -120,6 +120,24 @@ usage() {
|
||||
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
|
||||
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 " 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 -e "\e[97m --primordial-ssh <INTEGER> \e[0m"
|
||||
echo " Adds one outgoing UFW TCP exception for a bootstrap SSH port."
|
||||
echo " Outgoing only: no incoming firewall rule is added, and this option does not replace '--ssh-port'."
|
||||
echo " Effective only when the Live System's UFW outgoing policy is 'deny'."
|
||||
echo " Port MUST be a decimal integer between '1' and '65535'."
|
||||
echo
|
||||
echo -e "\e[97m --primordial-url <https-git-url> \e[0m"
|
||||
echo " HTTPS Git repository URL for the Primordial CDI overlay. MUST start with 'https://', include a host and"
|
||||
echo " path, and end in '.git'. The CDI starter converts this URL to an SSH clone URL at runtime."
|
||||
echo
|
||||
echo -e "\e[97m --provider-netcup-ipv6 \e[0m"
|
||||
echo " Activates IPv6 support for Netcup Root Server. One unique IPv6 address MUST be provided in this case and MUST be"
|
||||
echo " encapsulated with [], e.g., [1234::abcd]."
|
||||
|
||||
@@ -25,7 +25,7 @@ TIMESTAMP ?= $(shell date -u +%Y-%m-%dT%H-%M-%S)
|
||||
|
||||
### Core parameters (safe defaults; override in config.mk, rename config.mk.sample to config.mk and apply the remaining values):
|
||||
ARCH ?= amd64
|
||||
AUTOBUILD ?= 6.16.3+deb13-amd64
|
||||
AUTOBUILD ?= 7.0.10+deb13-amd64
|
||||
CONTROL ?= $(TIMESTAMP)
|
||||
DROPBEAR_VERSION ?= 2026.91
|
||||
SOPS_VERSION ?= 3.13.1
|
||||
@@ -63,6 +63,9 @@ define COMPOSE_AND
|
||||
[[ -n '$(FLAG_DEBUG)' ]] && cmd+=( --debug )
|
||||
[[ -n '$(FLAG_DHCP_CENTURION)' ]] && cmd+=( --dhcp-centurion )
|
||||
[[ -n '$(FLAG_TRIXIE)' ]] && cmd+=( --trixie )
|
||||
[[ -n '$(PRIMORDIAL_URL)' ]] && cmd+=( --primordial-url '$(PRIMORDIAL_URL)' )
|
||||
[[ -n '$(PRIMORDIAL_KEY)' ]] && cmd+=( --primordial-key '$(PRIMORDIAL_KEY)' )
|
||||
[[ -n '$(PRIMORDIAL_SSH_PORT)' ]] && cmd+=( --primordial-ssh '$(PRIMORDIAL_SSH_PORT)' )
|
||||
[[ -n '$(PROVIDER_NETCUP_IPV6)' ]] && cmd+=( --provider-netcup-ipv6 '$(PROVIDER_NETCUP_IPV6)' )
|
||||
[[ -n '$(RENICE)' ]] && cmd+=( --renice-priority '$(RENICE)' )
|
||||
if [[ -n '$(REIONICE_CLASS)' && -n '$(REIONICE_PRIO)' ]]; then
|
||||
|
||||
@@ -48,9 +48,20 @@ Verify_checksums() {
|
||||
|
||||
_KEYFILE=""
|
||||
|
||||
_MANIFEST_FOUND="false"
|
||||
|
||||
_MP=""
|
||||
|
||||
_RETURN_PGP=""
|
||||
|
||||
_RETURN_SHA=""
|
||||
|
||||
_VERIFICATION_EXECUTED="false"
|
||||
|
||||
_VERIFICATION_SUCCEEDED="false"
|
||||
|
||||
### Parse commandline arguments ----------------------------------------------------------------------------------------------
|
||||
# shellcheck disable=SC2154
|
||||
for _PARAMETER in ${LIVE_BOOT_CMDLINE}; do
|
||||
|
||||
case "${_PARAMETER}" in
|
||||
@@ -203,10 +214,12 @@ Verify_checksums() {
|
||||
|
||||
if [ -e "${_CHECKSUM}" ]; then
|
||||
|
||||
_MANIFEST_FOUND="true"
|
||||
printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "${_CHECKSUM}"
|
||||
|
||||
if [ -e "/usr/bin/${_DIGEST}sum" ]; then
|
||||
|
||||
_VERIFICATION_EXECUTED="true"
|
||||
printf "\e[95m[INFO] Found: [%s] ... \n\e[0m" "/usr/bin/${_DIGEST}sum"
|
||||
|
||||
if [ "${LIVE_VERIFY_CHECKSUMS_SIGNATURES}" = "true" ]; then
|
||||
@@ -237,6 +250,7 @@ Verify_checksums() {
|
||||
if grep -v '^#' "${_CHECKSUM}" | /usr/bin/"${_DIGEST}"sum -c > "${_TTY}"; then
|
||||
|
||||
_RETURN_SHA="${?}"
|
||||
_VERIFICATION_SUCCEEDED="true"
|
||||
printf "\e[92m[INFO] Found: [%s] successful verified: [%s] \n\e[0m" "/usr/bin/${_DIGEST}sum" "${_CHECKSUM}"
|
||||
|
||||
else
|
||||
@@ -265,6 +279,33 @@ Verify_checksums() {
|
||||
log_end_msg
|
||||
printf "\n"
|
||||
|
||||
if [ "${_MANIFEST_FOUND}" != "true" ]; then
|
||||
|
||||
printf "\e[91m[FATAL] No supported checksum manifest found. \n\e[0m"
|
||||
sleep 8
|
||||
panic "No supported checksum manifest found."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "${_VERIFICATION_EXECUTED}" != "true" ]; then
|
||||
|
||||
printf "\e[91m[FATAL] No supported checksum verification tool was available. \n\e[0m"
|
||||
sleep 8
|
||||
panic "No supported checksum verification tool was available."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "${_VERIFICATION_SUCCEEDED}" != "true" ]; then
|
||||
|
||||
printf "\e[91m[FATAL] No supported checksum manifest was verified successfully. \n\e[0m"
|
||||
sleep 8
|
||||
panic "No supported checksum manifest was verified successfully."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
case "${_RETURN_PGP},${_RETURN_SHA}" in
|
||||
|
||||
"0,0")
|
||||
@@ -288,6 +329,7 @@ Verify_checksums() {
|
||||
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
|
||||
sleep 8
|
||||
panic "Verification of [GPG signature] file successful, while verification of [sha checksum] file failed."
|
||||
return 1
|
||||
;;
|
||||
|
||||
*",0")
|
||||
@@ -295,6 +337,7 @@ Verify_checksums() {
|
||||
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
|
||||
sleep 8
|
||||
panic "Verification of [GPG signature] file failed, while verification of [sha checksum] file successful."
|
||||
return 1
|
||||
;;
|
||||
|
||||
"na,"*)
|
||||
@@ -302,6 +345,14 @@ Verify_checksums() {
|
||||
printf "\e[91m[FATAL] CDLB modified: [%s] done. \n\e[0m" "${CDLB_SCRIPT_FULL}"
|
||||
sleep 8
|
||||
panic "Verification of checksum file failed."
|
||||
return 1
|
||||
;;
|
||||
|
||||
*)
|
||||
printf "\e[91m[FATAL] Checksum verification ended in an unsupported state. \n\e[0m"
|
||||
sleep 8
|
||||
panic "Checksum verification ended in an unsupported state."
|
||||
return 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
set -Ceuo pipefail
|
||||
umask 0077
|
||||
|
||||
declare -gx VAR_RDNS_DOMAIN="" # Forward-confirmed reverse DNS domain.
|
||||
declare -gx VAR_RDNS_IPV4="" # IPv4 address used for RDNS verification.
|
||||
declare -gx VAR_RDNS_NORMALIZED="" # RDNS domain normalized for Primordial branch names.
|
||||
declare -gx VAR_PRIMORDIAL_KEY="" # Primordial SSH identity filename.
|
||||
declare -gx VAR_PRIMORDIAL_SSH_PORT="" # Primordial SSH port.
|
||||
declare -gx VAR_PRIMORDIAL_URL="" # Primordial HTTPS Git URL.
|
||||
declare -grx VAR_SEMAPHORE="/root/cdi.ciss" # Semaphore to appear.
|
||||
declare -girx VAR_TIMEOUT=3600 # Semaphore timer in seconds.
|
||||
|
||||
@@ -90,6 +96,472 @@ net_wait() {
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f net_wait
|
||||
|
||||
#######################################
|
||||
# Validate an IPv4 address.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# $1: IPv4 address
|
||||
# Returns:
|
||||
# 0: valid IPv4 address
|
||||
# 1: invalid IPv4 address
|
||||
#######################################
|
||||
is_ipv4() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_ip="${1:-}"
|
||||
declare -a ary_octets=()
|
||||
declare var_octet=""
|
||||
|
||||
[[ "${var_ip}" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1
|
||||
|
||||
IFS='.' read -r -a ary_octets <<< "${var_ip}"
|
||||
|
||||
for var_octet in "${ary_octets[@]}"; do
|
||||
|
||||
if ! ((10#${var_octet} <= 255)); then
|
||||
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f is_ipv4
|
||||
|
||||
#######################################
|
||||
# Validate a DNS domain name returned by RDNS.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# $1: domain name
|
||||
# Returns:
|
||||
# 0: valid domain name
|
||||
# 1: invalid domain name
|
||||
#######################################
|
||||
is_dns_name() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_name="${1:-}"
|
||||
|
||||
[[ "${#var_name}" -le 253 ]] || return 1
|
||||
[[ "${var_name}" =~ ^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$ ]] \
|
||||
|| return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f is_dns_name
|
||||
|
||||
#######################################
|
||||
# Retrieve and forward-confirm reverse DNS for the active IPv4 route.
|
||||
# Globals:
|
||||
# VAR_RDNS_DOMAIN
|
||||
# VAR_RDNS_IPV4
|
||||
# Arguments:
|
||||
# $1: module log file
|
||||
# Returns:
|
||||
# 0: on confirmed RDNS
|
||||
# 1: on missing or unconfirmed RDNS
|
||||
#######################################
|
||||
# retrieve_rdns() intentionally probes optional resolver tools and validation helpers inside conditionals.
|
||||
# shellcheck disable=SC2310,SC2312
|
||||
retrieve_rdns() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_log="${1:-}"
|
||||
declare -a ary_a=()
|
||||
declare -a ary_rdns=()
|
||||
declare -a ary_targets=()
|
||||
declare var_a="" var_ipv4="" var_rdns="" var_target=""
|
||||
|
||||
VAR_RDNS_DOMAIN=""
|
||||
VAR_RDNS_IPV4=""
|
||||
|
||||
mapfile -t ary_targets < <(
|
||||
getent ahostsv4 git.coresecret.dev 2>/dev/null \
|
||||
| awk '/^([0-9]{1,3}\.){3}[0-9]{1,3}[[:space:]]/ && !seen[$1]++ { print $1 }'
|
||||
)
|
||||
ary_targets+=( "1.1.1.1" "9.9.9.9" "8.8.8.8" )
|
||||
|
||||
if command -v ip >/dev/null 2>&1; then
|
||||
|
||||
for var_target in "${ary_targets[@]}"; do
|
||||
|
||||
if var_ipv4="$(
|
||||
ip -o -4 route get "${var_target}" 2>/dev/null \
|
||||
| awk '{ for (i = 1; i <= NF; i++) { if ($i == "src") { print $(i + 1); exit } } }'
|
||||
)" && is_ipv4 "${var_ipv4}"; then
|
||||
|
||||
break
|
||||
|
||||
fi
|
||||
|
||||
var_ipv4=""
|
||||
|
||||
done
|
||||
|
||||
if [[ -z "${var_ipv4}" ]]; then
|
||||
|
||||
mapfile -t ary_targets < <(
|
||||
ip -o -4 addr show scope global up 2>/dev/null \
|
||||
| awk '{ split($4, addr, "/"); if (!seen[addr[1]]++) { print addr[1] } }'
|
||||
)
|
||||
|
||||
for var_target in "${ary_targets[@]}"; do
|
||||
|
||||
if is_ipv4 "${var_target}"; then
|
||||
|
||||
var_ipv4="${var_target}"
|
||||
break
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [[ -z "${var_ipv4}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "retrieve_rdns(): no active IPv4 address found; continuing without RDNS."
|
||||
printf "Command: [retrieve_rdns] no active IPv4 address found; continuing without RDNS.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
|
||||
mapfile -t ary_rdns < <(
|
||||
dig +time=3 +tries=1 +short -x "${var_ipv4}" 2>/dev/null \
|
||||
| sed 's/[.]$//' \
|
||||
| awk 'NF && !seen[$0]++ { print $0 }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
if ((${#ary_rdns[@]} == 0)) && command -v host >/dev/null 2>&1; then
|
||||
|
||||
mapfile -t ary_rdns < <(
|
||||
host "${var_ipv4}" 2>/dev/null \
|
||||
| awk '/domain name pointer/ { sub(/[.]$/, "", $NF); if (!seen[$NF]++) { print $NF } }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
if ((${#ary_rdns[@]} == 0)); then
|
||||
|
||||
mapfile -t ary_rdns < <(
|
||||
getent hosts "${var_ipv4}" 2>/dev/null \
|
||||
| awk '{ for (i = 2; i <= NF; i++) { sub(/[.]$/, "", $i); if (!seen[$i]++) { print $i } } }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
for var_rdns in "${ary_rdns[@]}"; do
|
||||
|
||||
var_rdns="${var_rdns%.}"
|
||||
var_rdns="${var_rdns,,}"
|
||||
|
||||
if ! is_dns_name "${var_rdns}"; then
|
||||
|
||||
continue
|
||||
|
||||
fi
|
||||
|
||||
ary_a=()
|
||||
|
||||
if command -v dig >/dev/null 2>&1; then
|
||||
|
||||
mapfile -t ary_a < <(
|
||||
dig +time=3 +tries=1 +short A "${var_rdns}" 2>/dev/null \
|
||||
| awk '/^([0-9]{1,3}\.){3}[0-9]{1,3}$/ && !seen[$0]++ { print $0 }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
if ((${#ary_a[@]} == 0)) && command -v host >/dev/null 2>&1; then
|
||||
|
||||
mapfile -t ary_a < <(
|
||||
host -t A "${var_rdns}" 2>/dev/null \
|
||||
| awk '/ has address / && !seen[$NF]++ { print $NF }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
if ((${#ary_a[@]} == 0)); then
|
||||
|
||||
mapfile -t ary_a < <(
|
||||
getent ahostsv4 "${var_rdns}" 2>/dev/null \
|
||||
| awk '!seen[$1]++ { print $1 }'
|
||||
)
|
||||
|
||||
fi
|
||||
|
||||
for var_a in "${ary_a[@]}"; do
|
||||
|
||||
if is_ipv4 "${var_a}" && [[ "${var_a}" == "${var_ipv4}" ]]; then
|
||||
|
||||
VAR_RDNS_IPV4="${var_ipv4}"
|
||||
VAR_RDNS_DOMAIN="${var_rdns}"
|
||||
logger -t cdi-watcher "retrieve_rdns(): confirmed IPv4 ${VAR_RDNS_IPV4} RDNS ${VAR_RDNS_DOMAIN}."
|
||||
printf "Command: [retrieve_rdns] confirmed IPv4 [%s] RDNS [%s].\n" \
|
||||
"${VAR_RDNS_IPV4}" "${VAR_RDNS_DOMAIN}" >> "${var_log}"
|
||||
return 0
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
logger -t cdi-watcher "retrieve_rdns(): no forward-confirmed RDNS for IPv4 ${var_ipv4}; continuing without RDNS."
|
||||
printf "Command: [retrieve_rdns] no forward-confirmed RDNS for IPv4 [%s]; continuing without RDNS.\n" \
|
||||
"${var_ipv4}" >> "${var_log}"
|
||||
|
||||
return 1
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f retrieve_rdns
|
||||
|
||||
#######################################
|
||||
# Normalize a DNS domain into a Primordial branch name.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# $1: DNS domain name
|
||||
# Returns:
|
||||
# 0: on success
|
||||
# 1: on invalid DNS domain
|
||||
#######################################
|
||||
normalize_rdns_domain() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare var_domain="${1:-}"
|
||||
|
||||
var_domain="${var_domain%.}"
|
||||
var_domain="${var_domain,,}"
|
||||
|
||||
# shellcheck disable=SC2310
|
||||
is_dns_name "${var_domain}" || return 1
|
||||
|
||||
printf '%s\n' "${var_domain//./_}"
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f normalize_rdns_domain
|
||||
|
||||
#######################################
|
||||
# Convert an HTTPS Git URL into the SSH URL used for Primordial clone.
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# $1: HTTPS Git URL
|
||||
# $2: SSH port
|
||||
# Returns:
|
||||
# 0: on success
|
||||
# 1: on invalid URL or port
|
||||
#######################################
|
||||
derive_ssh_git_url() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_https_url="${1:-}"
|
||||
declare -r var_ssh_port="${2:-}"
|
||||
declare var_host="" var_path=""
|
||||
|
||||
if [[ ! "${var_https_url}" =~ ^https://([A-Za-z0-9.-]+)/([A-Za-z0-9._~/%+=:@,-]+\.git)$ ]]; then
|
||||
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
var_host="${BASH_REMATCH[1]}"
|
||||
var_path="${BASH_REMATCH[2]}"
|
||||
|
||||
if [[ -z "${var_host}" || -z "${var_path}" || ! "${var_ssh_port}" =~ ^[0-9]+$ ]] \
|
||||
|| ((10#${var_ssh_port} < 1 || 10#${var_ssh_port} > 65535)); then
|
||||
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
printf 'ssh://git@%s:%s/%s\n' "${var_host}" "${var_ssh_port}" "${var_path}"
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f derive_ssh_git_url
|
||||
|
||||
#######################################
|
||||
# Apply the Primordial overlay and create the CDI semaphore only on success.
|
||||
# Globals:
|
||||
# VAR_PRIMORDIAL_KEY
|
||||
# VAR_PRIMORDIAL_SSH_PORT
|
||||
# VAR_PRIMORDIAL_URL
|
||||
# VAR_RDNS_DOMAIN
|
||||
# VAR_RDNS_NORMALIZED
|
||||
# VAR_SEMAPHORE
|
||||
# Arguments:
|
||||
# $1: module log file
|
||||
# $2: CISS.debian.installer directory
|
||||
# Returns:
|
||||
# 0: on success or optional skip
|
||||
# 1: on failed configured Primordial overlay
|
||||
#######################################
|
||||
apply_primordial_overlay() {
|
||||
### Declare Arrays, HashMaps, and Variables.
|
||||
declare -r var_log="${1:-}"
|
||||
declare -r var_repo_dir="${2:-}"
|
||||
declare -r var_overlay_dir="/root/git/overlay"
|
||||
declare var_identity="" var_ssh_url="" var_rdns_normalized=""
|
||||
|
||||
if [[ -z "${VAR_PRIMORDIAL_URL}" && -z "${VAR_PRIMORDIAL_KEY}" && -z "${VAR_PRIMORDIAL_SSH_PORT}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay not configured; continuing with existing semaphore polling."
|
||||
printf "Command: [apply_primordial_overlay] skipped; Primordial overlay not configured.\n" >> "${var_log}"
|
||||
return 0
|
||||
|
||||
fi
|
||||
|
||||
if ! rm -f -- "${VAR_SEMAPHORE}"; then
|
||||
|
||||
logger -t cdi-watcher "Failed to remove existing CDI semaphore; aborting CDI autostart."
|
||||
printf "Command: [rm -f -- %s] failed; aborting CDI autostart.\n" "${VAR_SEMAPHORE}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ -z "${VAR_PRIMORDIAL_URL}" || -z "${VAR_PRIMORDIAL_KEY}" || -z "${VAR_PRIMORDIAL_SSH_PORT}" || -z "${VAR_RDNS_DOMAIN}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay configuration incomplete; aborting CDI autostart."
|
||||
printf "Command: [apply_primordial_overlay] failed; Primordial URL, key, SSH port, and RDNS domain are required.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2310
|
||||
if ! var_rdns_normalized="$(normalize_rdns_domain "${VAR_RDNS_DOMAIN}")"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay RDNS branch derivation failed; aborting CDI autostart."
|
||||
printf "Command: [normalize_rdns_domain %s] failed; aborting CDI autostart.\n" "${VAR_RDNS_DOMAIN}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
declare -gx VAR_RDNS_NORMALIZED="${var_rdns_normalized}"
|
||||
|
||||
# shellcheck disable=SC2310
|
||||
if ! var_ssh_url="$(derive_ssh_git_url "${VAR_PRIMORDIAL_URL}" "${VAR_PRIMORDIAL_SSH_PORT}")"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial HTTPS Git URL conversion failed; aborting CDI autostart."
|
||||
printf "Command: [derive_ssh_git_url] failed for configured Primordial URL; aborting CDI autostart.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
var_identity="/root/.ssh/${VAR_PRIMORDIAL_KEY}"
|
||||
|
||||
if [[ ! -e "${var_identity}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial SSH identity file is missing; aborting CDI autostart."
|
||||
printf "Command: [test -e /root/.ssh/<primordial-key>] failed; aborting CDI autostart.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ ! -f "${var_identity}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial SSH identity path is not a regular file; aborting CDI autostart."
|
||||
printf "Command: [test -f /root/.ssh/<primordial-key>] failed; aborting CDI autostart.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ ! -r "${var_identity}" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial SSH identity file is not readable by root; aborting CDI autostart."
|
||||
printf "Command: [test -r /root/.ssh/<primordial-key>] failed; aborting CDI autostart.\n" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if ! rm -rf -- "${var_overlay_dir}"; then
|
||||
|
||||
logger -t cdi-watcher "Failed to remove existing Primordial overlay directory; aborting CDI autostart."
|
||||
printf "Command: [rm -rf -- %s] failed; aborting CDI autostart.\n" "${var_overlay_dir}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if ! GIT_SSH_COMMAND="ssh -i ${var_identity} -p ${VAR_PRIMORDIAL_SSH_PORT}" \
|
||||
git clone --branch "${VAR_RDNS_NORMALIZED}" "${var_ssh_url}" "${var_overlay_dir}"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay clone failed; aborting CDI autostart."
|
||||
printf "Command: [git clone --branch %s <primordial-ssh-url> %s] failed; aborting CDI autostart.\n" \
|
||||
"${VAR_RDNS_NORMALIZED}" "${var_overlay_dir}" >> "${var_log}"
|
||||
rm -rf -- "${var_overlay_dir}" || true
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ ! -d "${var_overlay_dir}/.preseed" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay .preseed directory is missing; aborting CDI autostart."
|
||||
printf "Command: [test -d %s/.preseed] failed; aborting CDI autostart.\n" "${var_overlay_dir}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if [[ ! -d "${var_overlay_dir}/includes" ]]; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay includes directory is missing; aborting CDI autostart."
|
||||
printf "Command: [test -d %s/includes] failed; aborting CDI autostart.\n" "${var_overlay_dir}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
install -d -m 0700 "${var_repo_dir}/.preseed" "${var_repo_dir}/includes"
|
||||
|
||||
if ! rsync -av "${var_overlay_dir}/.preseed/" "${var_repo_dir}/.preseed/"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay .preseed rsync failed; aborting CDI autostart."
|
||||
printf "Command: [rsync -av %s/.preseed/ %s/.preseed/] failed; aborting CDI autostart.\n" \
|
||||
"${var_overlay_dir}" "${var_repo_dir}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if ! rsync -av "${var_overlay_dir}/includes/" "${var_repo_dir}/includes"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay includes rsync failed; aborting CDI autostart."
|
||||
printf "Command: [rsync -av %s/includes/ %s/includes] failed; aborting CDI autostart.\n" \
|
||||
"${var_overlay_dir}" "${var_repo_dir}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
if ! install -m 0600 /dev/null "${VAR_SEMAPHORE}"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay applied but semaphore creation failed; aborting CDI autostart."
|
||||
printf "Command: [install -m 0600 /dev/null %s] failed; aborting CDI autostart.\n" "${VAR_SEMAPHORE}" >> "${var_log}"
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay applied for branch ${VAR_RDNS_NORMALIZED}; CDI semaphore created."
|
||||
printf "Command: [apply_primordial_overlay] executed for branch [%s].\n" "${VAR_RDNS_NORMALIZED}" >> "${var_log}"
|
||||
|
||||
return 0
|
||||
}
|
||||
### Prevents accidental 'unset -f'.
|
||||
# shellcheck disable=SC2034
|
||||
readonly -f apply_primordial_overlay
|
||||
|
||||
#######################################
|
||||
# Wrapper for loading CISS hardened Kernel Parameters.
|
||||
# Globals:
|
||||
@@ -129,8 +601,7 @@ main() {
|
||||
var_log="/root/.ciss/cdi/log/9999-cdi-starter_$(date +"%Y-%m-%d_%H-%M-%S").log"
|
||||
touch "${var_log}"
|
||||
|
||||
|
||||
printf "CISS.debian.installer Master V9.14.020.2026.06.08 is up! \n" >> "${var_log}"
|
||||
printf "CISS.debian.live.builder V9.14.022.2026.06.10 calling CISS.debian.installer ... \n" >> "${var_log}"
|
||||
|
||||
### Sleep a moment to settle boot artifacts.
|
||||
sleep 8
|
||||
@@ -153,6 +624,12 @@ main() {
|
||||
fi
|
||||
printf "Command: [net_wait] executed.\n" >> "${var_log}"
|
||||
|
||||
### Retrieve forward-confirmed reverse DNS.
|
||||
printf "Command: [retrieve_rdns] to be executed ... \n" >> "${var_log}"
|
||||
# shellcheck disable=SC2310
|
||||
retrieve_rdns "${var_log}" || true
|
||||
printf "Command: [retrieve_rdns] executed.\n" >> "${var_log}"
|
||||
|
||||
### apt update.
|
||||
if ! apt-get update >> "${var_log}"; then
|
||||
|
||||
@@ -179,6 +656,16 @@ main() {
|
||||
cd "${var_repo_dir}"
|
||||
printf "Command: [git clone %s %s] executed.\n" "${var_repo_url}" "${var_repo_dir}" >> "${var_log}"
|
||||
|
||||
### Apply Primordial overlay before allowing CDI autostart.
|
||||
# shellcheck disable=SC2310
|
||||
if ! apply_primordial_overlay "${var_log}" "${var_repo_dir}"; then
|
||||
|
||||
logger -t cdi-watcher "Primordial overlay failed; CDI autostart aborted before semaphore polling."
|
||||
printf "Command: [apply_primordial_overlay] failed; CDI autostart aborted before semaphore polling.\n" >> "${var_log}"
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
### Poll up to VAR_TIMEOUT seconds for the semaphore to appear and be mode 0600.
|
||||
for ((i=0; i<VAR_TIMEOUT; i++)); do
|
||||
|
||||
@@ -209,7 +696,7 @@ main() {
|
||||
|
||||
### Timeout reached without acceptable semaphore.
|
||||
logger -t cdi-watcher "No valid semaphore ${VAR_SEMAPHORE} (mode 0600) within ${VAR_TIMEOUT}s; exiting idle."
|
||||
printf "CISS.debian.installer Master V9.14.020.2026.06.08: No valid semaphore [%s] within [%s]s.\n" "${VAR_SEMAPHORE}" "${VAR_TIMEOUT}" >> "${var_log}"
|
||||
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}"
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
Executable
+228
@@ -0,0 +1,228 @@
|
||||
#!/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
@@ -25,7 +25,7 @@ declare -grx VAR_GIT_HEAD_FULL="$(git rev-parse HEAD)"
|
||||
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_SYSTEM="$(uname -mnosv)"
|
||||
declare -grx VAR_VERSION="Master V9.14.020.2026.06.08"
|
||||
declare -grx VAR_VERSION="Master V9.14.022.2026.06.10"
|
||||
declare -grx VAR_VER_BASH="$(bash --version | head -n1 | awk '{
|
||||
# Print $4 and $5; include $6 only if it exists
|
||||
out = $4
|
||||
|
||||
@@ -34,6 +34,9 @@ declare -g VAR_HANDLER_CDI="false"
|
||||
declare -g VAR_HANDLER_NETCUP_IPV6="false"
|
||||
declare -g VAR_HANDLER_SPLASH=""
|
||||
declare -g VAR_HASHED_PWD=""
|
||||
declare -g VAR_PRIMORDIAL_KEY=""
|
||||
declare -g VAR_PRIMORDIAL_SSH_PORT=""
|
||||
declare -g VAR_PRIMORDIAL_URL=""
|
||||
declare -g VAR_SCRIPT_SUCCESS="false"
|
||||
declare -g VAR_SOPS_VERSION="3.13.1"
|
||||
declare -g VAR_SSHFP="false"
|
||||
|
||||
Reference in New Issue
Block a user