espo-deploy/rmm-tasks/ESPO-01-Grundeinrichtung.sh
Gordon Zimm 6623036011 ESPO-01: sshd -t scheitert auf einer VM ohne bisherige SSH-Verbindung
Gemeldet von der ersten Pilotkunden-VM: "Missing privilege separation
directory: /run/sshd". Ubuntu 24.04 startet sshd ueber ssh.socket erst bei
der ersten Verbindung; /run/sshd legt systemd dabei an (RuntimeDirectory).
Auf einer frisch installierten VM, an der bisher nur die Hyper-V-Konsole
benutzt wurde, existiert das Verzeichnis deshalb nicht - und sshd -t bricht
ab, obwohl die Konfiguration einwandfrei ist. Auf der Test-VM fiel das nicht
auf, weil dort per SSH gearbeitet wurde.

Das Skript legt /run/sshd jetzt selbst an (0755, wie die Unit), laedt sshd
nur neu, wenn er ueberhaupt als Dienst laeuft, und gibt die wirksamen Werte
aus sshd -T aus. Sind sie nicht auslesbar, ist die Haertung unbewiesen und
der Lauf ein Fehler.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-25 10:09:24 +02:00

104 lines
4.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ESPO-01-Grundeinrichtung – schliesst die Basis-VM ab.
# Laeuft als root, ist idempotent und kann jederzeit wiederholt werden.
# Aufruf: bash ESPO-01-Grundeinrichtung.sh "<Kundenkuerzel>"
# Der RMM-Task ist nur ein duenner Ausloeser, der dieses Skript holt und mit %companyuniqueid%
# aufruft - der "Company Unique Id" aus den Stammdaten. Sie ist Pflichtfeld und eindeutig,
# im Gegensatz zum Firmennamen kurz und stabil (glasfaktor statt glasfaktor Ingenieure GmbH).
# Ob der Lauf erlaubt ist, entscheidet der Task selbst per If/Then auf espo_zustand.
set -u
# Standzeile: zeigt im Protokoll, welche Fassung tatsaechlich gelaufen ist.
echo "ESPO-01-Grundeinrichtung, Skriptstand 2026-09-25"
KUERZEL_ROH="${1:-}"
FEHLER=0
# 1. Hostname aus dem Kundenkuerzel ableiten (klein, nur a-z 0-9 und Bindestrich), damit die
# Flotte im RMM und in Logs eindeutig benannt ist.
KUERZEL=$(printf '%s' "$KUERZEL_ROH" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed 's/-\+/-/g; s/^-//; s/-$//')
SOLL="espo-${KUERZEL}"
IST=$(hostnamectl --static)
if [ -z "$KUERZEL" ]; then
echo "FEHLER: Kundenkuerzel leer - ist die Company Unique Id im RMM gesetzt?"; FEHLER=1
elif [ "$IST" != "$SOLL" ]; then
hostnamectl set-hostname "$SOLL" && sed -i "s/\b${IST}\b/${SOLL}/g" /etc/hosts
echo "Hostname: $IST -> $SOLL"
else
echo "Hostname: $SOLL (unveraendert)"
fi
# 2. Hinweis auf das Initialpasswort aus dem Konsolen-Login entfernen - er hat nach der
# Erstanmeldung keinen Zweck mehr und steht sonst dauerhaft am Anmeldebildschirm.
if grep -q "Initialpasswort" /etc/issue; then
sed -i '/Initialpasswort/d; /beim ersten Anmelden/d' /etc/issue
echo "/etc/issue: Hinweis auf das Initialpasswort entfernt"
else
echo "/etc/issue: kein Hinweis vorhanden"
fi
# 3. Pruefen, dass das Konto ein gueltiges Passwort hat (Status P) - sonst ist die
# Erstinbetriebnahme unvollstaendig.
if [ "$(passwd -S administrator | awk '{print $2}')" = "P" ]; then
echo "Konto administrator: Passwort gesetzt"
else
echo "FEHLER: Konto administrator hat kein gueltiges Passwort"; FEHLER=1
fi
# 4. SSH haerten: keine Root-Anmeldung, wenige Fehlversuche, kurze Anmeldefrist.
install -d -m 755 /etc/ssh/sshd_config.d
cat > /etc/ssh/sshd_config.d/10-espo.conf <<'CONF'
PermitRootLogin no
MaxAuthTries 3
LoginGraceTime 20
CONF
# /run/sshd muss dafuer existieren: `sshd -t` bricht ohne das Verzeichnis ab
# ("Missing privilege separation directory"). Ubuntu 24.04 startet sshd ueber ssh.socket
# erst bei der ersten Verbindung, und erst dann legt systemd (RuntimeDirectory=sshd) es an.
# Auf einer VM, auf der bisher nur die Konsole benutzt wurde, fehlt es deshalb.
install -d -m 0755 /run/sshd
if sshd -t; then
# Laeuft sshd als Dienst, muss er die Aenderung nachlesen. Unter ssh.socket laeuft er nicht
# dauerhaft - dort liest jede neue Verbindung die Konfiguration ohnehin neu.
if systemctl is-active --quiet ssh; then
systemctl reload ssh || { echo "FEHLER: sshd laedt die Konfiguration nicht neu"; FEHLER=1; }
fi
# Nachweis statt Zusicherung: die Werte so ausgeben, wie sshd sie tatsaechlich anwendet.
# Laesst sich das nicht auslesen, ist die Haertung unbewiesen - dann ist der Lauf ein Fehler.
SSH_IST="$(sshd -T | grep -iE '^(permitrootlogin|maxauthtries|logingracetime) ')"
if [ -n "$SSH_IST" ]; then
echo "$SSH_IST" | sed 's/^/SSH: /'
else
echo "FEHLER: wirksame SSH-Werte nicht auslesbar"; FEHLER=1
fi
else
echo "FEHLER: sshd-Konfiguration ungueltig"; FEHLER=1
fi
# 5. Journal begrenzen, damit Logs das Wurzeldateisystem nicht fuellen koennen.
install -d -m 755 /etc/systemd/journald.conf.d
printf '[Journal]\nSystemMaxUse=500M\n' > /etc/systemd/journald.conf.d/10-espo.conf
systemctl restart systemd-journald && echo "journald: SystemMaxUse=500M"
# 6. needrestart daran hindern, containerd automatisch neu zu starten - das wuerde die
# laufenden Container mitreissen. docker ist ab Werk schon ausgenommen.
install -d -m 755 /etc/needrestart/conf.d
printf '# containerd nicht automatisch neu starten (Container haengen daran).\n$nrconf{override_rc}{qr(^containerd)} = 0;\n' > /etc/needrestart/conf.d/10-espo.conf
echo "needrestart: containerd ausgenommen"
# 7. Zeitzone sicherstellen.
if [ "$(timedatectl show -p Timezone --value)" != "Europe/Berlin" ]; then
timedatectl set-timezone Europe/Berlin && echo "Zeitzone auf Europe/Berlin gesetzt"
else
echo "Zeitzone: Europe/Berlin"
fi
# 8. Automatische Sicherheitsupdates nur pruefen, nicht aendern - sie sind Ubuntu-Standard.
if grep -qs '"1"' /etc/apt/apt.conf.d/20auto-upgrades; then
echo "unattended-upgrades: aktiv"
else
echo "WARNUNG: unattended-upgrades nicht aktiv"; FEHLER=1
fi
# 9. Ergebniszeile fuer Monitor und Custom Field.
if [ "$FEHLER" -eq 0 ]; then echo "ESPO01_ERGEBNIS: OK"; exit 0; else echo "ESPO01_ERGEBNIS: FEHLER"; exit 1; fi