K-114: SSH root login prompt with sshd drop-in in the install path
prompt_lxc_config asks 'SSH-Root-Login erlauben? [Y/n]' (env-presettable via SSH_ROOT_LOGIN, validated, normalized to yes|no). The bootstrap passes the value into the container; configure_ssh_root_login writes /etc/ssh/sshd_config.d/zz-root-login.conf (yes -> PermitRootLogin yes, no -> prohibit-password) and reloads sshd.
This commit is contained in:
@@ -29,6 +29,7 @@ CRED_FILE="/root/authentik.credentials"
|
|||||||
|
|
||||||
# ── base packages + Docker ────────────────────────────────────────────────────
|
# ── base packages + Docker ────────────────────────────────────────────────────
|
||||||
setup_base_apt ca-certificates curl
|
setup_base_apt ca-certificates curl
|
||||||
|
configure_ssh_root_login
|
||||||
if ! command -v docker >/dev/null 2>&1; then
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
msg_info "Installing Docker (get.docker.com)..."
|
msg_info "Installing Docker (get.docker.com)..."
|
||||||
curl -fsSL https://get.docker.com | sh >/dev/null
|
curl -fsSL https://get.docker.com | sh >/dev/null
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ DEVPI_PORT="3141"
|
|||||||
|
|
||||||
# ── packages + user + dirs ───────────────────────────────────────────────────
|
# ── packages + user + dirs ───────────────────────────────────────────────────
|
||||||
setup_base_apt python3 python3-venv python3-pip
|
setup_base_apt python3 python3-venv python3-pip
|
||||||
|
configure_ssh_root_login
|
||||||
|
|
||||||
create_system_user "$DEVPI_USER" "$DEVPI_HOME"
|
create_system_user "$DEVPI_USER" "$DEVPI_HOME"
|
||||||
mkdir -p "$DEVPI_DATA"
|
mkdir -p "$DEVPI_DATA"
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ CRED_FILE="/root/nexus-db.credentials"
|
|||||||
|
|
||||||
# ── packages: PGDG repo + PostgreSQL 16 + pgvector ────────────────────────────
|
# ── packages: PGDG repo + PostgreSQL 16 + pgvector ────────────────────────────
|
||||||
setup_base_apt curl ca-certificates gnupg lsb-release
|
setup_base_apt curl ca-certificates gnupg lsb-release
|
||||||
|
configure_ssh_root_login
|
||||||
|
|
||||||
if [[ ! -f /etc/apt/sources.list.d/pgdg.sources ]] && [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then
|
if [[ ! -f /etc/apt/sources.list.d/pgdg.sources ]] && [[ ! -f /etc/apt/sources.list.d/pgdg.list ]]; then
|
||||||
msg_info "Adding PGDG apt repo..."
|
msg_info "Adding PGDG apt repo..."
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ run_user() { runuser -u "$APP_USER" -- env HOME="$APP_HOME" "$@"; }
|
|||||||
|
|
||||||
# ── packages: git + rsync + sudo ; Node.js via NodeSource ─────────────────────
|
# ── packages: git + rsync + sudo ; Node.js via NodeSource ─────────────────────
|
||||||
setup_base_apt git rsync sudo
|
setup_base_apt git rsync sudo
|
||||||
|
configure_ssh_root_login
|
||||||
|
|
||||||
NODE_HAVE="$(command -v node >/dev/null 2>&1 && node -v | sed -E 's/^v([0-9]+).*/\1/' || echo 0)"
|
NODE_HAVE="$(command -v node >/dev/null 2>&1 && node -v | sed -E 's/^v([0-9]+).*/\1/' || echo 0)"
|
||||||
if [[ "$NODE_HAVE" != "$NODE_MAJOR" ]]; then
|
if [[ "$NODE_HAVE" != "$NODE_MAJOR" ]]; then
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ run_user() { runuser -u "$APP_USER" -- env HOME="$APP_HOME" "$@"; }
|
|||||||
|
|
||||||
# ── packages: git + rsync + sudo ; Node.js via NodeSource ────────────────────
|
# ── packages: git + rsync + sudo ; Node.js via NodeSource ────────────────────
|
||||||
setup_base_apt git rsync sudo
|
setup_base_apt git rsync sudo
|
||||||
|
configure_ssh_root_login
|
||||||
|
|
||||||
NODE_HAVE="$(command -v node >/dev/null 2>&1 && node -v | sed -E 's/^v([0-9]+).*/\1/' || echo 0)"
|
NODE_HAVE="$(command -v node >/dev/null 2>&1 && node -v | sed -E 's/^v([0-9]+).*/\1/' || echo 0)"
|
||||||
if [[ "$NODE_HAVE" != "$NODE_MAJOR" ]]; then
|
if [[ "$NODE_HAVE" != "$NODE_MAJOR" ]]; then
|
||||||
|
|||||||
+24
-1
@@ -147,6 +147,16 @@ is_cidr() {
|
|||||||
|
|
||||||
is_ipcfg() { [[ "$1" == "dhcp" ]] || is_cidr "$1"; }
|
is_ipcfg() { [[ "$1" == "dhcp" ]] || is_cidr "$1"; }
|
||||||
|
|
||||||
|
# Ja/Nein-Antworten (Prompts wie "… erlauben? [Y/n]"). Akzeptiert
|
||||||
|
# deutsch/englisch, normalize_yesno macht daraus kanonisch yes|no.
|
||||||
|
is_yesno() { is_clean_ascii "$1" && [[ "${1,,}" =~ ^(y|yes|j|ja|n|no|nein)$ ]]; }
|
||||||
|
normalize_yesno() {
|
||||||
|
case "${1,,}" in
|
||||||
|
y|yes|j|ja) printf 'yes' ;;
|
||||||
|
*) printf 'no' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
# Space/comma-separated list of IPv4s (DNS prompt). Gesamtstring zuerst
|
# Space/comma-separated list of IPv4s (DNS prompt). Gesamtstring zuerst
|
||||||
# prüfen — die Wort-Splittung würde eingebettete Newlines sonst verstecken.
|
# prüfen — die Wort-Splittung würde eingebettete Newlines sonst verstecken.
|
||||||
is_ipv4_list() {
|
is_ipv4_list() {
|
||||||
@@ -311,6 +321,17 @@ prompt_lxc_config() {
|
|||||||
else
|
else
|
||||||
msg_warn "No network profile for VLAN ${VLAN_TAG:-none}; DHCP DNS will be inherited."
|
msg_warn "No network profile for VLAN ${VLAN_TAG:-none}; DHCP DNS will be inherited."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# SSH-Root-Login (Default: ja, Homelab-Komfort). Umgesetzt wird das im
|
||||||
|
# Install-Pfad per sshd-Drop-in (configure_ssh_root_login, lib/install.func);
|
||||||
|
# bootstrap_install_script reicht den normalisierten Wert in den Container.
|
||||||
|
if [[ -z "${SSH_ROOT_LOGIN:-}" ]]; then
|
||||||
|
prompt_validated SSH_ROOT_LOGIN "SSH-Root-Login erlauben? [Y/n]: " is_yesno "y"
|
||||||
|
else
|
||||||
|
require_valid SSH_ROOT_LOGIN is_yesno "SSH root login (y/n)"
|
||||||
|
fi
|
||||||
|
SSH_ROOT_LOGIN="$(normalize_yesno "$SSH_ROOT_LOGIN")"
|
||||||
|
echo " → SSH root login: $SSH_ROOT_LOGIN"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── template ─────────────────────────────────────────────────────────────────
|
# ── template ─────────────────────────────────────────────────────────────────
|
||||||
@@ -408,7 +429,9 @@ bootstrap_install_script() {
|
|||||||
pct exec "$CTID" -- bash -c "apt-get update -qq && apt-get install -y -qq curl ca-certificates >/dev/null"
|
pct exec "$CTID" -- bash -c "apt-get update -qq && apt-get install -y -qq curl ca-certificates >/dev/null"
|
||||||
|
|
||||||
msg_info "Running installer ($url)..."
|
msg_info "Running installer ($url)..."
|
||||||
pct exec "$CTID" -- bash -c "curl -fsSL '$url' -o /root/${APP}-install.sh && bash /root/${APP}-install.sh"
|
# SSH_ROOT_LOGIN ist durch normalize_yesno kanonisch yes|no — als Env in
|
||||||
|
# den Container durchreichen (configure_ssh_root_login wertet es aus).
|
||||||
|
pct exec "$CTID" -- bash -c "curl -fsSL '$url' -o /root/${APP}-install.sh && SSH_ROOT_LOGIN='${SSH_ROOT_LOGIN:-yes}' bash /root/${APP}-install.sh"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── summary ──────────────────────────────────────────────────────────────────
|
# ── summary ──────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -38,6 +38,36 @@ apt_cleanup() {
|
|||||||
apt-get autoclean -qq >/dev/null || true
|
apt-get autoclean -qq >/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ── ssh ──────────────────────────────────────────────────────────────────────
|
||||||
|
# SSH-Root-Login gemäß Host-Prompt (prompt_lxc_config setzt SSH_ROOT_LOGIN,
|
||||||
|
# bootstrap_install_script reicht es als Env durch; Default: yes).
|
||||||
|
# yes → PermitRootLogin yes (Passwort-Login mit dem generierten Root-Passwort)
|
||||||
|
# no → PermitRootLogin prohibit-password (Debian-Default, nur SSH-Key)
|
||||||
|
# Umsetzung als Drop-in, damit Paket-Updates von sshd_config nicht kollidieren.
|
||||||
|
configure_ssh_root_login() {
|
||||||
|
local choice="${SSH_ROOT_LOGIN:-yes}" value
|
||||||
|
case "$choice" in
|
||||||
|
yes) value="yes" ;;
|
||||||
|
no) value="prohibit-password" ;;
|
||||||
|
*) msg_err "SSH_ROOT_LOGIN must be yes|no, got: '$choice'"; return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ ! -d /etc/ssh/sshd_config.d ]]; then
|
||||||
|
if [[ "$choice" == "no" ]]; then
|
||||||
|
msg_warn "openssh-server not installed — nothing to configure (root login stays off)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
msg_info "Installing openssh-server..."
|
||||||
|
apt-get install -y -qq openssh-server >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Configuring SSH root login: PermitRootLogin $value"
|
||||||
|
printf 'PermitRootLogin %s\n' "$value" >/etc/ssh/sshd_config.d/zz-root-login.conf
|
||||||
|
systemctl reload ssh 2>/dev/null || systemctl restart ssh 2>/dev/null \
|
||||||
|
|| msg_warn "ssh.service not active yet — config applies on first start"
|
||||||
|
msg_ok "SSH root login: $choice"
|
||||||
|
}
|
||||||
|
|
||||||
# ── users / dirs ─────────────────────────────────────────────────────────────
|
# ── users / dirs ─────────────────────────────────────────────────────────────
|
||||||
create_system_user() {
|
create_system_user() {
|
||||||
local user="$1" home="$2"
|
local user="$1" home="$2"
|
||||||
|
|||||||
@@ -77,6 +77,38 @@ assert_false "is_hostname lehnt 'a b' ab" is_hostname "a b"
|
|||||||
assert_true "is_token akzeptiert local-lvm" is_token "local-lvm"
|
assert_true "is_token akzeptiert local-lvm" is_token "local-lvm"
|
||||||
assert_false "is_token lehnt 'a;b' ab" is_token "a;b"
|
assert_false "is_token lehnt 'a;b' ab" is_token "a;b"
|
||||||
|
|
||||||
|
# ── Ja/Nein (SSH-Root-Login-Prompt) ──────────────────────────────────────────
|
||||||
|
assert_true "is_yesno akzeptiert y" is_yesno "y"
|
||||||
|
assert_true "is_yesno akzeptiert Ja" is_yesno "Ja"
|
||||||
|
assert_true "is_yesno akzeptiert NO" is_yesno "NO"
|
||||||
|
assert_true "is_yesno akzeptiert nein" is_yesno "nein"
|
||||||
|
assert_false "is_yesno lehnt 'maybe' ab" is_yesno "maybe"
|
||||||
|
assert_false "is_yesno lehnt leeren Wert ab" is_yesno ""
|
||||||
|
[[ "$(normalize_yesno "J")" == "yes" && "$(normalize_yesno "nein")" == "no" ]] \
|
||||||
|
&& ok "normalize_yesno kanonisiert J→yes, nein→no" \
|
||||||
|
|| nok "normalize_yesno kanonisiert J→yes, nein→no"
|
||||||
|
|
||||||
|
# SSH-Root-Login-Prompt: leere Eingabe = Default Y → normalisiert yes;
|
||||||
|
# explizites 'n' → no.
|
||||||
|
ssh_default="$(
|
||||||
|
printf '\n' | {
|
||||||
|
SSH_ROOT_LOGIN=""
|
||||||
|
prompt_validated SSH_ROOT_LOGIN "SSH-Root-Login erlauben? [Y/n]: " is_yesno "y" >/dev/null 2>&1
|
||||||
|
normalize_yesno "$SSH_ROOT_LOGIN"
|
||||||
|
}
|
||||||
|
)"
|
||||||
|
[[ "$ssh_default" == "yes" ]] && ok "SSH-Root-Login: leere Eingabe → Default yes" \
|
||||||
|
|| nok "SSH-Root-Login Default (got: '$ssh_default')"
|
||||||
|
ssh_no="$(
|
||||||
|
printf 'n\n' | {
|
||||||
|
SSH_ROOT_LOGIN=""
|
||||||
|
prompt_validated SSH_ROOT_LOGIN "SSH-Root-Login erlauben? [Y/n]: " is_yesno "y" >/dev/null 2>&1
|
||||||
|
normalize_yesno "$SSH_ROOT_LOGIN"
|
||||||
|
}
|
||||||
|
)"
|
||||||
|
[[ "$ssh_no" == "no" ]] && ok "SSH-Root-Login: 'n' → no" \
|
||||||
|
|| nok "SSH-Root-Login 'n' (got: '$ssh_no')"
|
||||||
|
|
||||||
# ── require_valid: env-Werte werden sanitisiert + geprüft ────────────────────
|
# ── require_valid: env-Werte werden sanitisiert + geprüft ────────────────────
|
||||||
CHECKVAL=$' 7\r'
|
CHECKVAL=$' 7\r'
|
||||||
require_valid CHECKVAL is_uint "Testwert" && [[ "$CHECKVAL" == "7" ]] \
|
require_valid CHECKVAL is_uint "Testwert" && [[ "$CHECKVAL" == "7" ]] \
|
||||||
@@ -145,12 +177,12 @@ ctid_out="$(
|
|||||||
smoke_out="$(
|
smoke_out="$(
|
||||||
env CTID=999 CT_HOSTNAME=smoke DISK_SIZE=8 CORES=2 RAM=1024 BRIDGE=vmbr0 \
|
env CTID=999 CT_HOSTNAME=smoke DISK_SIZE=8 CORES=2 RAM=1024 BRIDGE=vmbr0 \
|
||||||
VLAN_TAG=20 TEMPLATE_STORAGE=local ROOTFS_STORAGE=local-lvm \
|
VLAN_TAG=20 TEMPLATE_STORAGE=local ROOTFS_STORAGE=local-lvm \
|
||||||
IPCFG=10.11.20.99/24 GATEWAY=10.11.20.1 NAMESERVER="" \
|
IPCFG=10.11.20.99/24 GATEWAY=10.11.20.1 NAMESERVER="" SSH_ROOT_LOGIN=J \
|
||||||
NET_PROFILES_FILE="$REPO_ROOT/lib/networks.conf" \
|
NET_PROFILES_FILE="$REPO_ROOT/lib/networks.conf" \
|
||||||
bash -c "source '$REPO_ROOT/lib/build.func' && prompt_lxc_config >/dev/null && echo SMOKE-OK"
|
bash -c "source '$REPO_ROOT/lib/build.func' && prompt_lxc_config >/dev/null && echo SMOKE-OK:\$SSH_ROOT_LOGIN"
|
||||||
)" || true
|
)" || true
|
||||||
[[ "$smoke_out" == *SMOKE-OK* ]] \
|
[[ "$smoke_out" == *SMOKE-OK:yes* ]] \
|
||||||
&& ok "prompt_lxc_config Dry-Run mit validen env-Werten läuft durch" \
|
&& ok "prompt_lxc_config Dry-Run mit validen env-Werten läuft durch (SSH_ROOT_LOGIN J→yes)" \
|
||||||
|| nok "prompt_lxc_config Dry-Run (got: '$smoke_out')"
|
|| nok "prompt_lxc_config Dry-Run (got: '$smoke_out')"
|
||||||
|
|
||||||
smoke_bad="$(
|
smoke_bad="$(
|
||||||
|
|||||||
Reference in New Issue
Block a user