#!/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 "" # 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