diff --git a/Linux/SSH/secure_ssh.sh b/Linux/SSH/secure_ssh.sh index bdee185..d5e77fb 100644 --- a/Linux/SSH/secure_ssh.sh +++ b/Linux/SSH/secure_ssh.sh @@ -1,15 +1,24 @@ -#!/bin/bash +#!/usr/bin/env bash -printf "\033c" +# ────────────────────────────────────────────────────────────────────────────── +# Secure-SSH Setup for Modern Linux (2025-edition) +# ------------------------------------------------ +# * Generates hardened OpenSSH configuration (IPv4-only) +# * Installs/updates OpenSSH-server + creates host keys +# * Creates users, adds SSH public keys, restricts login +# * Removes all legacy / deprecated directives +# * Adds post-quantum KEX, rate-limiting, strict auth flow & root lockdown +# ────────────────────────────────────────────────────────────────────────────── + +printf "\033c" # clear terminal SSH_CONFIG_DIR="/etc/ssh/sshd_config.d" SSH_MAIN_CONFIG="/etc/ssh/sshd_config" SSH_CONFIG_FILE="$SSH_CONFIG_DIR/secure.conf" ED25519_KEY="/etc/ssh/ssh_host_ed25519_key" ECDSA_KEY="/etc/ssh/ssh_host_ecdsa_key" -RSA_KEY="/etc/ssh/ssh_host_rsa_key" # Hinzugefügt für Kompatibilität mit älteren Clients -# Farben für bessere Lesbarkeit +# ─── ANSI colors ────────────────────────────────────────────────────────────── RED='\033[1;31m' GREEN='\033[1;32m' YELLOW='\033[1;33m' @@ -17,665 +26,185 @@ BLUE='\033[1;34m' WHITE='\033[1;37m' RESET='\033[0m' -# Logging-Funktionen -log() { - echo -e "${GREEN}$1${RESET}" -} +log() { echo -e "${GREEN}$1${RESET}"; } +warn() { echo -e "${YELLOW}$1${RESET}"; } +error() { echo -e "${RED}$1${RESET}"; } -warn() { - echo -e "${YELLOW}$1${RESET}" -} - -error() { - echo -e "${RED}$1${RESET}" -} - -# Funktion zur Erkennung des Service-Managers (systemd, init, etc.) +# ─── Service-Manager detection (systemd │ sysvinit │ openrc) ─────────────────── detect_service_manager() { - if command -v systemctl &> /dev/null; then - echo "systemd" - elif command -v service &> /dev/null; then - echo "sysvinit" - elif [ -x /sbin/rc-service ]; then - echo "openrc" - else - echo "unknown" - fi + if command -v systemctl &>/dev/null; then echo "systemd" + elif command -v service &>/dev/null; then echo "sysvinit" + elif [ -x /sbin/rc-service ]; then echo "openrc" + else echo "unknown"; fi } -# Funktion zur Erkennung des SSH-Dienstnamens +# ─── SSH service name detection ─────────────────────────────────────────────── detect_ssh_service() { - local service_manager=$1 - - # Liste möglicher SSH-Dienstnamen - local ssh_services=("sshd" "ssh" "openssh-server" "openssh") - - case "$service_manager" in - systemd) - for service in "${ssh_services[@]}"; do - if systemctl list-units --type=service | grep -q "$service"; then - echo "$service" - return 0 - fi - done - ;; - sysvinit) - for service in "${ssh_services[@]}"; do - if service --status-all 2>&1 | grep -q "$service"; then - echo "$service" - return 0 - fi - done - ;; - openrc) - for service in "${ssh_services[@]}"; do - if rc-service -l | grep -q "$service"; then - echo "$service" - return 0 - fi - done - ;; - esac - - # Fallback: Prüfe die üblichen Verzeichnisse auf ausführbare SSHd-Dateien - if [ -x /usr/sbin/sshd ]; then - echo "sshd" - elif [ -x /usr/bin/sshd ]; then - echo "sshd" - else - echo "unknown" - fi + local manager=$1 + local services=(sshd ssh openssh-server openssh) + case $manager in + systemd) for s in "${services[@]}"; do systemctl list-units --type=service | grep -q $s && echo $s && return; done ;; + sysvinit) for s in "${services[@]}"; do service --status-all | grep -q $s && echo $s && return; done ;; + openrc) for s in "${services[@]}"; do rc-service -l | grep -q $s && echo $s && return; done ;; + esac + [ -x /usr/sbin/sshd ] && echo sshd || echo unknown } -# Funktion zum Neustart des SSH-Dienstes restart_ssh_service() { - local service_manager=$1 - local service_name=$2 - - warn "Starte SSH-Dienst ($service_name) neu..." - - case "$service_manager" in - systemd) - if sudo systemctl restart "$service_name"; then - log "SSH-Dienst erfolgreich neu gestartet." - return 0 - fi - ;; - sysvinit) - if sudo service "$service_name" restart; then - log "SSH-Dienst erfolgreich neu gestartet." - return 0 - fi - ;; - openrc) - if sudo rc-service "$service_name" restart; then - log "SSH-Dienst erfolgreich neu gestartet." - return 0 - fi - ;; - *) - # Direkter Neustart als letzter Ausweg - if sudo killall -HUP sshd 2>/dev/null; then - log "SSH-Dienst durch Signal neu gestartet." - return 0 - fi - ;; - esac - - error "Fehler beim Neustart des SSH-Dienstes." - return 1 + local manager=$1 service=$2 + warn "Starte SSH-Dienst ($service) neu…" + case $manager in + systemd) sudo systemctl restart "$service" && return 0 ;; + sysvinit) sudo service "$service" restart && return 0 ;; + openrc) sudo rc-service "$service" restart && return 0 ;; + esac + sudo killall -HUP sshd 2>/dev/null && return 0 + return 1 } -# Funktion zur Paketinstallation basierend auf dem Paketmanager install_package() { - local package=$1 - - warn "Installiere $package..." - - # Erkennung des Paketmanagers - if command -v apt &> /dev/null; then - # Debian/Ubuntu - if sudo apt update &> /dev/null && sudo apt install -y "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - elif command -v dnf &> /dev/null; then - # RHEL 8+/Fedora - if sudo dnf install -y "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - elif command -v yum &> /dev/null; then - # Ältere RHEL/CentOS - if sudo yum install -y "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - elif command -v apk &> /dev/null; then - # Alpine Linux - if sudo apk add "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - elif command -v pacman &> /dev/null; then - # Arch Linux - if sudo pacman -Sy --noconfirm "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - elif command -v zypper &> /dev/null; then - # openSUSE - if sudo zypper install -y "$package" &> /dev/null; then - log "$package wurde erfolgreich installiert." - return 0 - fi - else - error "Nicht unterstütztes System. Bitte $package manuell installieren." - return 1 - fi - - error "Fehler bei der Installation von $package." - return 1 + local pkg=$1 + warn "Installiere $pkg…" + if command -v apt &>/dev/null; then sudo apt update -qq && sudo apt install -y $pkg -qq ; + elif command -v dnf &>/dev/null; then sudo dnf install -y $pkg &>/dev/null ; + elif command -v yum &>/dev/null; then sudo yum install -y $pkg &>/dev/null ; + elif command -v apk &>/dev/null; then sudo apk add $pkg &>/dev/null ; + elif command -v pacman&>/dev/null; then sudo pacman -Sy --noconfirm $pkg &>/dev/null ; + elif command -v zypper&>/dev/null; then sudo zypper install -y $pkg &>/dev/null ; + else error "Kein unterstützter Paketmanager – installiere $pkg manuell."; return 1; fi + log "$pkg wurde installiert." } -# Funktion zur Erkennung der OpenSSH-Version -detect_openssh_version() { - if command -v ssh -V &> /dev/null; then - local version_output=$(ssh -V 2>&1) - echo "$version_output" | grep -oP 'OpenSSH_\K[0-9]+\.[0-9]+' | head -1 - else - echo "unknown" - fi -} +# ─── Setup prerequisites ───────────────────────────────────────────────────── +SERVICE_MANAGER=$(detect_service_manager); log "Service-Manager: $SERVICE_MANAGER" -# Erkennung des Service-Managers -SERVICE_MANAGER=$(detect_service_manager) -log "Erkannter Service-Manager: $SERVICE_MANAGER" +command -v sudo &>/dev/null || { warn "sudo fehlt – Installation…"; install_package sudo; } +command -v sshd &>/dev/null || install_package openssh-server -# Prüfe, ob sudo installiert ist -if ! command -v sudo &> /dev/null; then - warn "sudo ist nicht installiert. Versuche, sudo zu installieren..." - - # Installiere sudo basierend auf dem erkannten Paketmanager - if command -v apt &> /dev/null; then - apt update && apt install -y sudo - elif command -v dnf &> /dev/null; then - dnf install -y sudo - elif command -v yum &> /dev/null; then - yum install -y sudo - elif command -v apk &> /dev/null; then - apk add sudo - elif command -v pacman &> /dev/null; then - pacman -Sy --noconfirm sudo - elif command -v zypper &> /dev/null; then - zypper install -y sudo - else - error "Nicht unterstütztes System. Bitte sudo manuell installieren." - exit 1 - fi - - if command -v sudo &> /dev/null; then - log "sudo wurde erfolgreich installiert." - else - error "Fehler bei der Installation von sudo." - exit 1 - fi -else - log "sudo ist bereits installiert." -fi +[ -d "$SSH_CONFIG_DIR" ] || { warn "Erstelle $SSH_CONFIG_DIR"; sudo mkdir -p "$SSH_CONFIG_DIR"; } -# Prüfe und installiere OpenSSH-Server -if ! command -v sshd &> /dev/null; then - warn "OpenSSH-Server wird installiert..." - - if command -v apt &> /dev/null; then - install_package "openssh-server" - elif command -v dnf &> /dev/null || command -v yum &> /dev/null; then - install_package "openssh-server" - elif command -v apk &> /dev/null; then - install_package "openssh" - elif command -v pacman &> /dev/null; then - install_package "openssh" - elif command -v zypper &> /dev/null; then - install_package "openssh" - else - error "Nicht unterstütztes System. Bitte OpenSSH manuell installieren." - exit 1 - fi -else - log "OpenSSH-Server ist bereits installiert." -fi +# ─── Host keys (ed25519 & ecdsa-p384) ───────────────────────────────────────── +for key in "$ED25519_KEY ed25519" "$ECDSA_KEY ecdsa -b 384"; do + set -- $key; file=$1; shift; args=$*; + [ -f "$file" ] || { + warn "Generiere Host-Schlüssel $(basename $file)…"; + sudo ssh-keygen -t $args -f "$file" -N "" -q && sudo chmod 600 "$file" && log "Schlüssel $(basename $file) erstellt."; + } +done -# Erkennen der OpenSSH-Version -SSH_VERSION=$(detect_openssh_version) -if [ "$SSH_VERSION" != "unknown" ]; then - log "Erkannte OpenSSH-Version: $SSH_VERSION" -fi +# ─── Replace main config with include only ──────────────────────────────────── +warn "Setze $SSH_MAIN_CONFIG auf Include…" +echo "Include $SSH_CONFIG_DIR/*.conf" | sudo tee "$SSH_MAIN_CONFIG" >/dev/null -# Stelle sicher, dass das Konfigurationsverzeichnis existiert -if [ ! -d "$SSH_CONFIG_DIR" ]; then - warn "SSH Konfigurationsverzeichnis existiert nicht. Es wird erstellt..." - sudo mkdir -p "$SSH_CONFIG_DIR" - log "SSH Konfigurationsverzeichnis erstellt." -fi - -# Generiere fehlende Schlüssel -if [ ! -f "$ED25519_KEY" ]; then - warn "Host-Schlüssel fehlt. Generiere ssh_host_ed25519_key..." - if sudo ssh-keygen -t ed25519 -f "$ED25519_KEY" -N "" &> /dev/null; then - sudo chown root:root "$ED25519_KEY" - sudo chmod 600 "$ED25519_KEY" - log "Host-Schlüssel ssh_host_ed25519_key wurde erstellt." - else - error "Fehler beim Erstellen des Host-Schlüssels." - exit 1 - fi -else - log "Host-Schlüssel ssh_host_ed25519_key ist bereits vorhanden." -fi - -if [ ! -f "$ECDSA_KEY" ]; then - warn "Host-Schlüssel fehlt. Generiere ssh_host_ecdsa_key..." - if sudo ssh-keygen -t ecdsa -b 384 -f "$ECDSA_KEY" -N "" &> /dev/null; then - sudo chown root:root "$ECDSA_KEY" - sudo chmod 600 "$ECDSA_KEY" - log "Host-Schlüssel ssh_host_ecdsa_key wurde erstellt." - else - error "Fehler beim Erstellen des Host-Schlüssels." - exit 1 - fi -else - log "Host-Schlüssel ssh_host_ecdsa_key ist bereits vorhanden." -fi - -# Prüfe auf RSA-Schlüssel für die Kompatibilität -if [ ! -f "$RSA_KEY" ]; then - warn "Host-Schlüssel fehlt. Generiere ssh_host_rsa_key für Kompatibilität..." - if sudo ssh-keygen -t rsa -b 4096 -f "$RSA_KEY" -N "" &> /dev/null; then - sudo chown root:root "$RSA_KEY" - sudo chmod 600 "$RSA_KEY" - log "Host-Schlüssel ssh_host_rsa_key wurde erstellt." - else - error "Fehler beim Erstellen des Host-Schlüssels." - # Kein Exit hier, da RSA optional ist - fi -else - log "Host-Schlüssel ssh_host_rsa_key ist bereits vorhanden." -fi - -# Konfiguriere SSH für die Include-Direktive -warn "Setze /etc/ssh/sshd_config zurück auf Include-Direktive..." -sudo tee "$SSH_MAIN_CONFIG" > /dev/null </dev/null; then - SUDO_GROUP="wheel" - fi - ;; - esac -fi - +# distribution-specific sudo group +declare -A distro_sudo=( [ubuntu]=sudo [debian]=sudo [raspbian]=sudo [centos]=wheel [fedora]=wheel [rhel]=wheel [almalinux]=wheel [rocky]=wheel [ol]=wheel [arch]=wheel [manjaro]=wheel [alpine]=wheel ) +SUDO_GROUP="sudo" +[ -f /etc/os-release ] && { . /etc/os-release; SUDO_GROUP=${distro_sudo[$ID]:-sudo}; } log "Benutze sudo-Gruppe: $SUDO_GROUP" for user in $SSH_USERS; do - if id "$user" &>/dev/null; then - log "Benutzer $user existiert." - VALID_USERS+="$user " - else - echo -en "${BLUE}Benutzer ${WHITE}$user${BLUE} existiert nicht. Soll dieser erstellt werden? ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " - read CREATE_USER - if [ "$CREATE_USER" == "y" ]; then - echo -en "${BLUE}Gib ein Passwort für ${WHITE}$user${BLUE} ein: ${RESET}" - read -s USER_PASSWORD - echo - - # Benutzer erstellen basierend auf der Distribution - if command -v useradd &> /dev/null; then - # Linux-Standard - if sudo useradd -m -s /bin/bash "$user" &>/dev/null && echo "$user:$USER_PASSWORD" | sudo chpasswd &>/dev/null; then - log "Benutzer $user wurde erstellt." - # Füge Benutzer zur sudo-Gruppe hinzu - if getent group "$SUDO_GROUP" &>/dev/null; then - sudo usermod -aG "$SUDO_GROUP" "$user" &>/dev/null - log "Benutzer $user wurde zur $SUDO_GROUP-Gruppe hinzugefügt." - else - warn "Gruppe $SUDO_GROUP existiert nicht. Der Benutzer erhält keine sudo-Rechte." - fi - else - error "Fehler bei der Erstellung von Benutzer $user." - continue - fi - elif command -v adduser &> /dev/null; then - # Debian/Ubuntu-spezifisch - if sudo adduser --disabled-password --gecos "" "$user" &>/dev/null && echo "$user:$USER_PASSWORD" | sudo chpasswd &>/dev/null; then - log "Benutzer $user wurde erstellt." - # Füge Benutzer zur sudo-Gruppe hinzu - if getent group "$SUDO_GROUP" &>/dev/null; then - sudo usermod -aG "$SUDO_GROUP" "$user" &>/dev/null - log "Benutzer $user wurde zur $SUDO_GROUP-Gruppe hinzugefügt." - else - warn "Gruppe $SUDO_GROUP existiert nicht. Der Benutzer erhält keine sudo-Rechte." - fi - else - error "Fehler bei der Erstellung von Benutzer $user." - continue - fi - else - error "Kein Befehl zum Erstellen von Benutzern gefunden." - continue - fi - - # SSH-Verzeichnis und Schlüsseldatei erstellen - sudo mkdir -p "/home/$user/.ssh" - sudo touch "/home/$user/.ssh/authorized_keys" - sudo chown -R "$user":"$user" "/home/$user/.ssh" - sudo chmod 700 "/home/$user/.ssh" - sudo chmod 600 "/home/$user/.ssh/authorized_keys" - - echo -en "${BLUE}Möchtest du einen SSH Public Key für ${WHITE}$user${BLUE} hinzufügen? ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " - read ADD_KEY - if [ "$ADD_KEY" == "y" ]; then - echo -en "${BLUE}Füge den SSH Public Key hier ein: ${RESET}" - read SSH_KEY - echo "$SSH_KEY" | sudo tee -a "/home/$user/.ssh/authorized_keys" &> /dev/null - fi - - VALID_USERS+="$user " - fi - fi + if id "$user" &>/dev/null; then + log "Benutzer $user existiert." + VALID_USERS+="$user " + continue + fi + read -rp $'\e[1;34mBenutzer '"$user"$' existiert nicht. Anlegen? [y/N]: \e[0m' CREATE + [[ $CREATE =~ ^[Yy]$ ]] || continue + read -rsp $'\e[1;34mPasswort für '"$user"$': \e[0m' PW; echo + sudo useradd -m -s /bin/bash "$user" && echo "$user:$PW" | sudo chpasswd + sudo usermod -aG "$SUDO_GROUP" "$user" + sudo install -d -m700 -o "$user" -g "$user" "/home/$user/.ssh" + sudo touch "/home/$user/.ssh/authorized_keys" && sudo chmod 600 "/home/$user/.ssh/authorized_keys" && sudo chown "$user":"$user" "/home/$user/.ssh/authorized_keys" + read -rp $'\e[1;34mSSH Public Key für '"$user"$' hinzufügen? [y/N]: \e[0m' ADDKEY + if [[ $ADDKEY =~ ^[Yy]$ ]]; then + read -rp $'\e[1;34mPublic Key: \e[0m' KEY + echo "$KEY" | sudo tee -a "/home/$user/.ssh/authorized_keys" >/dev/null + fi + VALID_USERS+="$user " done -# Erstelle SSH-Konfigurationsdatei -warn "Erstelle SSH-Konfigurationsdatei..." +# ─── Determine SFTP-server binary ───────────────────────────────────────────── +for path in /usr/lib/openssh/sftp-server /usr/libexec/openssh/sftp-server /usr/lib/ssh/sftp-server; do [ -x "$path" ] && SFTP_PATH=$path && break; done +SFTP_PATH=${SFTP_PATH:-internal-sftp} +log "SFTP-Pfad: $SFTP_PATH" -# Bestimme den Pfad zum SFTP-Server basierend auf der Distribution -SFTP_PATH="/usr/lib/openssh/sftp-server" # Standard für Debian/Ubuntu - -# Finde den tatsächlichen Pfad des SFTP-Servers -if [ -f /usr/lib/openssh/sftp-server ]; then - SFTP_PATH="/usr/lib/openssh/sftp-server" -elif [ -f /usr/libexec/openssh/sftp-server ]; then - SFTP_PATH="/usr/libexec/openssh/sftp-server" -elif [ -f /usr/lib/ssh/sftp-server ]; then - SFTP_PATH="/usr/lib/ssh/sftp-server" -else - # Suche nach der sftp-server-Binärdatei im System - SFTP_PATH_FIND=$(find /usr -name sftp-server -type f 2>/dev/null | head -1) - if [ -n "$SFTP_PATH_FIND" ]; then - SFTP_PATH="$SFTP_PATH_FIND" - else - SFTP_PATH="internal-sftp" # Fallback auf internen SFTP-Server - fi -fi - -log "Verwende SFTP-Server-Pfad: $SFTP_PATH" - -# Prüfe, ob PAM verfügbar ist +# ─── Check for PAM ──────────────────────────────────────────────────────────── PAM_AVAILABLE=false -if [ -d "/etc/pam.d" ] && (command -v pam &>/dev/null || ls /lib*/*/libpam.so* &>/dev/null || ls /lib/*/libpam.so* &>/dev/null || ls /usr/lib*/*/libpam.so* &>/dev/null || ls /usr/lib/*/libpam.so* &>/dev/null); then - PAM_AVAILABLE=true - log "PAM ist auf diesem System verfügbar." -else - warn "PAM scheint auf diesem System nicht verfügbar zu sein." -fi +[ -d /etc/pam.d ] && { find / -maxdepth 2 -name 'libpam.so*' -quit | grep -q libpam && PAM_AVAILABLE=true; } +$PAM_AVAILABLE && log "PAM verfügbar." || warn "PAM nicht gefunden – UsePAM wird deaktiviert." -# Prüfe, ob ModuliFile existiert und ob es ersetzt werden soll -MODULI_FILE="/etc/ssh/moduli" -if [ -f "$MODULI_FILE" ]; then - # Prüfe, ob eine Optimierung der moduli-Datei erwünscht ist - echo -en "${BLUE}Möchtest du die Diffie-Hellman-Parameter optimieren? Dies kann die SSH-Sicherheit erhöhen, benötigt aber etwas Zeit. ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " - read OPTIMIZE_MODULI - if [ "$OPTIMIZE_MODULI" == "y" ]; then - warn "Optimiere Diffie-Hellman-Parameter (Dies kann einige Minuten dauern)..." - # Sichere die Original-Datei - sudo cp "$MODULI_FILE" "${MODULI_FILE}.bak" - # Behalte nur starke Moduli (3072 Bit oder mehr) - sudo awk '$5 >= 3071' "$MODULI_FILE" | sudo tee "${MODULI_FILE}.tmp" > /dev/null - sudo mv "${MODULI_FILE}.tmp" "$MODULI_FILE" - log "Diffie-Hellman-Parameter wurden optimiert." - fi -fi +# ─── Generate modern, hardened secure.conf ──────────────────────────────────── +warn "Erstelle $SSH_CONFIG_FILE (modern hardened)…" -# Frage, ob ein nicht-Standard-Port genutzt werden soll (besserer Schutz vor automatisierten Scans) -echo -en "${BLUE}Möchtest du einen non-Standard SSH-Port verwenden? (Standard ist 22) ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " -read USE_CUSTOM_PORT -SSH_PORT="22" -if [ "$USE_CUSTOM_PORT" == "y" ]; then - echo -en "${BLUE}Gib einen alternativen SSH-Port (1024-65535) ein: ${RESET}" - read CUSTOM_PORT - if [[ "$CUSTOM_PORT" =~ ^[0-9]+$ ]] && [ "$CUSTOM_PORT" -gt 1023 ] && [ "$CUSTOM_PORT" -lt 65536 ]; then - SSH_PORT="$CUSTOM_PORT" - log "Verwende benutzerdefinierten SSH-Port: $SSH_PORT" - else - warn "Ungültiger Port. Verwende Standard-Port 22." - fi -fi +sudo tee "$SSH_CONFIG_FILE" >/dev/null < /dev/null < /dev/null < /dev/null - -# PAM für zusätzliche Sicherheitsmodule verwenden -UsePAM yes - -# Kein MOTD durch SSH (über PAM regeln) +# PAM (if available) +UsePAM $($PAM_AVAILABLE && echo yes || echo no) PrintMotd no -EOL -else - cat < /dev/null -# PAM ist nicht verfügbar auf diesem System -# Basic-Auth-Einstellungen -StrictModes yes -EOL -fi - -# Füge den Rest der Konfiguration hinzu -cat < /dev/null - -# X11-Weiterleitung deaktivieren (falls nicht benötigt) +# X11 forwarding disabled X11Forwarding no -# TCP-Weiterleitung deaktivieren -AllowTcpForwarding no -GatewayPorts no - -# Verhindern von Tunnel-Nutzung -PermitTunnel no - -# Verhindern von SSH-Agent-Forwarding (wenn nicht benötigt) -AllowAgentForwarding no - -# Banner-Anzeige deaktivieren (keine Systeminfo für potenzielle Angreifer) -Banner none - -# Deaktiviere .rhosts Dateien -IgnoreRhosts yes -HostbasedAuthentication no - -# Pfad zur Authorized Keys-Datei -AuthorizedKeysFile .ssh/authorized_keys - -# SFTP-Subsystem +# SFTP subsystem Subsystem sftp $SFTP_PATH -# Inaktive SSH-Sitzungen überwachen und beenden +# Keepalive ClientAliveInterval 300 ClientAliveCountMax 2 -# Kompression deaktivieren (Schutz vor CRIME/BREACH-ähnlichen Angriffen) -Compression no +AllowUsers ${VALID_USERS%% } # strip trailing space +EOF -# Erlaubte Benutzer festlegen -AllowUsers $VALID_USERS +log "Secure-Config geschrieben." -# Trendchecking aktivieren für verdächtige Aktivitäten -DebianBanner no +# ─── Validate & restart SSH ────────────────────────────────────────────────── +[ -d /run/sshd ] || { sudo mkdir -p /run/sshd; sudo chmod 0755 /run/sshd; } -# Anzeige der letzten Anmeldung deaktivieren -PrintLastLog no -EOL +sudo sshd -t || { error "SSH-Konfiguration ungültig!"; exit 1; } -log "Prüfe SSH-Konfiguration..." +SSH_SERVICE=$(detect_ssh_service "$SERVICE_MANAGER") +[ "$SSH_SERVICE" = unknown ] && { error "SSH-Dienst nicht gefunden."; exit 1; } -# Stelle sicher, dass das Privilege-Separation-Verzeichnis existiert -if [ ! -d /run/sshd ]; then - warn "/run/sshd fehlt - erstelle Verzeichnis..." - sudo mkdir -p /run/sshd - sudo chown root:sys /run/sshd || sudo chown root:root /run/sshd - sudo chmod 0755 /run/sshd - log "/run/sshd wurde erstellt." -fi +restart_ssh_service "$SERVICE_MANAGER" "$SSH_SERVICE" || { error "Neustart fehlgeschlagen – manuell prüfen."; exit 1; } -# Erstelle oder modifiziere die Datei /etc/hosts.deny für zusätzliche Sicherheit -if [ -f "/etc/hosts.deny" ]; then - # Prüfe, ob SSHD bereits in hosts.deny vorhanden ist - if ! grep -q "sshd" /etc/hosts.deny; then - echo "sshd: ALL" | sudo tee -a /etc/hosts.deny > /dev/null - log "SSHD-Eintrag zu /etc/hosts.deny hinzugefügt." - fi -else - echo "sshd: ALL" | sudo tee /etc/hosts.deny > /dev/null - log "Datei /etc/hosts.deny mit SSHD-Eintrag erstellt." -fi - -# Erstelle oder modifiziere die Datei /etc/hosts.allow für vertrauenswürdige IPs -echo -en "${BLUE}Möchtest du bestimmte IP-Adressen explizit für SSH zulassen? ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " -read ADD_ALLOWED_IPS -if [ "$ADD_ALLOWED_IPS" == "y" ]; then - echo -en "${BLUE}Gib vertrauenswürdige IP-Adressen ein (durch Leerzeichen getrennt, z.B. 192.168.1.10 10.0.0.5): ${RESET}" - read ALLOWED_IPS - - if [ -n "$ALLOWED_IPS" ]; then - FORMATTED_IPS=$(echo "$ALLOWED_IPS" | tr ' ' ',') - echo "sshd: $FORMATTED_IPS : allow" | sudo tee -a /etc/hosts.allow > /dev/null \ No newline at end of file +log "Setup abgeschlossen. Zugelassene Benutzer: ${WHITE}${VALID_USERS}${RESET}"