#!/bin/bash printf "\033c" 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" # Farben für bessere Lesbarkeit RED='\033[1;31m' GREEN='\033[1;32m' YELLOW='\033[1;33m' BLUE='\033[1;34m' WHITE='\033[1;37m' RESET='\033[0m' # Logging-Funktionen log() { echo -e "${GREEN}$1${RESET}" } warn() { echo -e "${YELLOW}$1${RESET}" } error() { echo -e "${RED}$1${RESET}" } # Funktion zur Erkennung des Service-Managers (systemd, init, etc.) 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 } # Funktion zur Erkennung des SSH-Dienstnamens 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 } # 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 } # 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 } # Erkennung des Service-Managers SERVICE_MANAGER=$(detect_service_manager) log "Erkannter Service-Manager: $SERVICE_MANAGER" # 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 # 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 # 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 # 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 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 done # Erstelle SSH-Konfigurationsdatei warn "Erstelle SSH-Konfigurationsdatei..." # 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 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 # 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 # Erstelle die Konfigurationsdatei mit dynamischen Einstellungen je nach System sudo tee "$SSH_CONFIG_FILE" > /dev/null < /dev/null # PAM für zusätzliche Sicherheitsmodule verwenden UsePAM yes # Kein MOTD durch SSH (über PAM regeln) PrintMotd no EOL else cat < /dev/null # PAM ist nicht verfügbar auf diesem System # Basic-Auth-Einstellungen UsePrivilegeSeparation sandbox StrictModes yes MaxAuthTries 3 MaxSessions 5 EOL fi # Füge den Rest der Konfiguration hinzu cat < /dev/null # X11-Weiterleitung deaktivieren (falls nicht benötigt) X11Forwarding no # Pfad zur Authorized Keys-Datei AuthorizedKeysFile .ssh/authorized_keys # SFTP-Subsystem Subsystem sftp $SFTP_PATH # Inaktive SSH-Sitzungen überwachen und beenden ClientAliveInterval 300 ClientAliveCountMax 2 AllowUsers $VALID_USERS EOL log "Prüfe SSH-Konfiguration..." # Überprüfe, ob die Konfiguration gültig ist if command -v sshd &> /dev/null; then if ! sudo sshd -t &> /dev/null; then error "Die SSH-Konfiguration enthält Fehler! Überprüfe die Konfiguration manuell." exit 1 else log "SSH-Konfiguration ist gültig." fi fi # Erkenne den SSH-Dienst und starte ihn neu SSH_SERVICE=$(detect_ssh_service "$SERVICE_MANAGER") if [ "$SSH_SERVICE" == "unknown" ]; then error "Kein SSH-Dienst gefunden. Bitte überprüfe deine Installation." exit 1 fi log "Erkannter SSH-Dienst: $SSH_SERVICE" if ! restart_ssh_service "$SERVICE_MANAGER" "$SSH_SERVICE"; then error "Fehler beim Neustart des SSH-Dienstes. Versuche einen alternativen Ansatz..." # Fallback-Versuche für verschiedene Distributionen if [ "$SERVICE_MANAGER" == "systemd" ]; then # Versuche alle möglichen Dienste bei systemd for service in sshd ssh openssh openssh-server; do if sudo systemctl restart "$service" 2>/dev/null; then log "SSH-Dienst ($service) erfolgreich neu gestartet." exit 0 fi done elif [ "$SERVICE_MANAGER" == "sysvinit" ]; then # Versuche alle möglichen Dienste bei sysvinit for service in sshd ssh openssh openssh-server; do if sudo service "$service" restart 2>/dev/null; then log "SSH-Dienst ($service) erfolgreich neu gestartet." exit 0 fi done elif [ "$SERVICE_MANAGER" == "openrc" ]; then # Versuche alle möglichen Dienste bei OpenRC for service in sshd ssh openssh openssh-server; do if sudo rc-service "$service" restart 2>/dev/null; then log "SSH-Dienst ($service) erfolgreich neu gestartet." exit 0 fi done fi # Als letzte Möglichkeit, versuche einen Kill/HUP-Signal an sshd zu senden if pgrep sshd &>/dev/null && sudo killall -HUP sshd; then log "SSH-Dienst durch Signal neu gestartet." else error "Konnte den SSH-Dienst nicht neu starten. Bitte starte den SSH-Dienst manuell neu." exit 1 fi fi log "Setup abgeschlossen! Nur folgende Benutzer dürfen sich per SSH anmelden: ${WHITE}$VALID_USERS" log "Die SSH-Konfiguration wurde für maximale Sicherheit optimiert."