V9.14.022.2026.06.10
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
🛡️ Retrieve DNSSEC status of coresecret.dev. / 🛡️ Retrieve DNSSEC status of coresecret.dev. (push) Has been cancelled
🛡️ Shell Script Linting / 🛡️ Shell Script Linting (push) Has been cancelled
💙 Generating a PUBLIC Live ISO. / 💙 Generating a PUBLIC Live ISO. (push) Has been cancelled
🔐 Generating a Private Live ISO TRIXIE. / 🔐 Generating a Private Live ISO TRIXIE. (push) Has been cancelled
Signed-off-by: Marc S. Weidner <msw@coresecret.dev>
This commit is contained in:
@@ -365,10 +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-ssh <port>` 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.
|
||||
* **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.
|
||||
|
||||
@@ -524,7 +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-ssh 2222 \
|
||||
--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
|
||||
@@ -574,7 +577,9 @@ preview it or run it.
|
||||
SSH_PUBKEY=/dev/shm/cdlb_secrets
|
||||
|
||||
# Optional
|
||||
PRIMORDIAL_SSH_PORT=2222
|
||||
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]
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
.:-=++***#####***+==-:.
|
||||
.-=*#%%@@@@@@@@@@@@@@@@@@@@@%%#*=-.
|
||||
.=*#@@@@@@@%%%%%%%%%%%%%%%%%%%%%@@@@@@@%*=:
|
||||
:+#@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@%*=.
|
||||
.+#@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@#=:
|
||||
:*%@@%%%%%%%%%%%%%%%%@@@@@@@@@@@@@%%%%%%%%%%%%%%%%@@@@%%%*=
|
||||
:*@@%%%%%%%%%%%%%%@@@@@%%#*******#%%@@@@%%%%%%%%%@@%#+-:.
|
||||
.+@@%%%%%%%%%%%%%%@@%#+-. .-+#%@@%%%%@@#=.
|
||||
-%@%%%%%%%%%%%%%@@%*-. :-+**####**+-: .-*%@@@*:
|
||||
+@@%%%%%%%%%%%%%@%+. :+#%@@@@@@@@@@@@@@%#+: .+#:
|
||||
*@%%%%%%%%%%%%%%@*. =#@@@@%%%%%%%%%%%%%%@@@@#-
|
||||
*@%%%%%%%%%%%%%%@- -%@@%%%%%%%%%%%%%%%%%%%%%%@@#-
|
||||
+@%%%%%%%%%%%%%%@- +@@%%%%%%%%%%%%%%%%%%%%%%%%%%@@+-*#
|
||||
-@%%%%%%%%%%%%%%@+ +@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@-
|
||||
%%%%%%%%%%%%%%%%% :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
-@%%%%%%%%%%%%%%@* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@=
|
||||
#%%%%%%%%%%%%%%%@= *@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
.%%%%%%%%%%%%%%%%@+ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@%%%%%%%=
|
||||
-@%%%%%%%%%%%%%%%@* :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@@@@@.
|
||||
=@%%%%%%%%%%%%%%%%%. #@%%%%%%%%%%%%%%%%%%%%%%%%%%%*..:--==+*-
|
||||
=@%%%%%%%%%%%%%%%%@= :@%%%%%%%%%%%%%%%%%%%%%%%%%%%@#:
|
||||
=@%%%%%%%%%%%%%%%%%%. +@%%%%%%%%%%%%%%%%%%%%%%%%%%%@@+
|
||||
:@%%%%%%%%%%%%%%%%%@# #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@#::::.
|
||||
%@%%%%%%%%%%%%%%%%%@= :@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@@@%#:
|
||||
*%%%%%%%%%%%%%%%%%%- *@%%%%%%%%%%%%%%%@@@@%%%%%%%%%%%%%%%@@@.
|
||||
:@%%%%%%%%%%%%%%%@- -@%%%%%%%%%%%%@@@%%%%%@@%%%%%%%%%%%%%%%.
|
||||
*@%%%%%%%%%%%%%@+ .%%%%%%%%%%%@@*=:. .-*@%%%%%%%%%%%%@=
|
||||
.%%%%%%%%%%%%%%%. .%%%%%%%%%@@*: :%%%%%%%%%%%@+
|
||||
=@%%%%%%%%%%%@* -@%%%%%%%@#: =@%%%%%%%%@*
|
||||
+@%%%%%%%%%%@. *@%%%%%@@+ .@%%%%%%%%%.
|
||||
*@%%%%%%%%@+ -@%%%%%@%- .@%%%%%%%@=
|
||||
+@%%%%%@@* :%%%%%@@*. -@%%%%%%%%
|
||||
=@@@@@#- :%%%%@@%- #%%%%%%%@+
|
||||
:#*+: :%%%@@%+ -@@@%%%%%@:
|
||||
=@@@@#=. :+#@@@@%%.
|
||||
.*%#*=. .=*%@%
|
||||
::. .-+
|
||||
@@ -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
|
||||
|
||||
|
||||
+3
-1
@@ -15,7 +15,9 @@ BUILD_DIR ?=
|
||||
DROPBEAR_VERSION ?=
|
||||
### Optional SOPS release override; empty uses VAR_SOPS_VERSION from var/global.var.sh:
|
||||
SOPS_VERSION ?=
|
||||
### Optional outgoing bootstrap/recovery SSH port; empty disables the extra UFW rule:
|
||||
### 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 ?=
|
||||
|
||||
@@ -13,6 +13,7 @@ include_toc: true
|
||||
# 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™
|
||||
|
||||
|
||||
+12
-2
@@ -98,13 +98,23 @@ 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'.
|
||||
Example fragment:
|
||||
./ciss_live_builder.sh --ssh-port 42842 --primordial-ssh 2222
|
||||
|
||||
--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
|
||||
|
||||
@@ -38,7 +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
|
||||
@@ -74,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}"
|
||||
@@ -288,6 +293,44 @@ 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
|
||||
|
||||
@@ -305,6 +348,44 @@ arg_parser() {
|
||||
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)"
|
||||
|
||||
@@ -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
|
||||
@@ -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'.
|
||||
|
||||
@@ -120,12 +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]."
|
||||
|
||||
@@ -63,6 +63,8 @@ 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)' )
|
||||
|
||||
@@ -15,6 +15,10 @@ 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.
|
||||
|
||||
@@ -324,6 +328,240 @@ retrieve_rdns() {
|
||||
# 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:
|
||||
@@ -363,7 +601,6 @@ main() {
|
||||
var_log="/root/.ciss/cdi/log/9999-cdi-starter_$(date +"%Y-%m-%d_%H-%M-%S").log"
|
||||
touch "${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.
|
||||
@@ -419,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
|
||||
|
||||
|
||||
@@ -34,7 +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