From 3a84f9b7b055adb51b50b2265a996cd17ec2d8cf Mon Sep 17 00:00:00 2001 From: admManuel Date: Tue, 6 May 2025 11:29:53 +0000 Subject: [PATCH] Update Linux/SSH/secure_ssh.sh --- Linux/SSH/secure_ssh.sh | 458 +++++++++++++++++++++++++++++++++++----- 1 file changed, 400 insertions(+), 58 deletions(-) diff --git a/Linux/SSH/secure_ssh.sh b/Linux/SSH/secure_ssh.sh index f1d242a..4e4ea2a 100644 --- a/Linux/SSH/secure_ssh.sh +++ b/Linux/SSH/secure_ssh.sh @@ -8,6 +8,7 @@ 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' @@ -15,6 +16,7 @@ BLUE='\033[1;34m' WHITE='\033[1;37m' RESET='\033[0m' +# Logging-Funktionen log() { echo -e "${GREEN}$1${RESET}" } @@ -27,44 +29,204 @@ error() { echo -e "${RED}$1${RESET}" } -install_package() { - local package=$1 - local cmd=$2 - warn "Installiere $package..." - if eval "$cmd" &> /dev/null; then - log "$package wurde erfolgreich installiert." +# 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 - error "Fehler bei der Installation von $package." - exit 1 + 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 - install_package "sudo" "apt update && apt install -y sudo" + apt update && apt install -y sudo elif command -v dnf &> /dev/null; then - install_package "sudo" "dnf install -y sudo" + dnf install -y sudo + elif command -v yum &> /dev/null; then + yum install -y sudo elif command -v apk &> /dev/null; then - install_package "sudo" "apk add sudo" + 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" "sudo apt update && sudo apt install -y openssh-server" - elif command -v dnf &> /dev/null; then - install_package "OpenSSH-Server" "sudo dnf install -y openssh-server" + 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-Server" "sudo apk add openssh" + 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 @@ -73,6 +235,14 @@ 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 @@ -101,8 +271,18 @@ else log "Host-Schlüssel ssh_host_ecdsa_key ist bereits vorhanden." fi +# Konfiguriere SSH für die Include-Direktive +# Prüfe zunächst, ob die Include-Direktive bereits in der Hauptkonfigurationsdatei vorhanden ist +if ! sudo grep -q "^Include $SSH_CONFIG_DIR" "$SSH_MAIN_CONFIG" 2>/dev/null; then + warn "Include-Direktive wird zur Hauptkonfigurationsdatei hinzugefügt..." + echo "Include $SSH_CONFIG_DIR/*" | sudo tee -a "$SSH_MAIN_CONFIG" > /dev/null + log "Include-Direktive hinzugefügt." +else + log "Include-Direktive ist bereits in der Hauptkonfigurationsdatei vorhanden." +fi + +# Bereinige alte Konfigurationsdateien im SSH_CONFIG_DIR sudo rm -f $SSH_CONFIG_DIR/* -echo "Include $SSH_CONFIG_DIR/*" | sudo tee $SSH_MAIN_CONFIG > /dev/null echo -en "${BLUE}Welche Benutzer dürfen sich per SSH anmelden? (Benutzer durch ${WHITE}Leerzeichen${BLUE} trennen): ${RESET}" read SSH_USERS @@ -110,26 +290,38 @@ read SSH_USERS VALID_USERS="" # Bestimme die sudo-Gruppe abhängig von der Distribution +SUDO_GROUP="sudo" # Standard-Wert + +# Erkennung der korrekten sudo-Gruppe if [ -f /etc/os-release ]; then . /etc/os-release case "$ID" in - ubuntu|debian) + ubuntu|debian|raspbian) SUDO_GROUP="sudo" ;; - centos|fedora|rhel|almalinux|rocky) + centos|fedora|rhel|almalinux|rocky|ol) SUDO_GROUP="wheel" ;; arch|manjaro) SUDO_GROUP="wheel" ;; + alpine) + SUDO_GROUP="wheel" + ;; + opensuse*|sles) + SUDO_GROUP="wheel" + ;; *) - SUDO_GROUP="sudo" # Fallback auf "sudo" + # Prüfe, ob die Gruppe wheel existiert + if getent group wheel &>/dev/null; then + SUDO_GROUP="wheel" + fi ;; esac -else - SUDO_GROUP="sudo" # Fallback falls os-release nicht existiert fi +log "Benutze sudo-Gruppe: $SUDO_GROUP" + for user in $SSH_USERS; do if id "$user" &>/dev/null; then log "Benutzer $user existiert." @@ -137,34 +329,120 @@ for user in $SSH_USERS; do else echo -en "${BLUE}Benutzer ${WHITE}$user${BLUE} existiert nicht. Soll dieser erstellt werden? ${YELLOW}[${WHITE}y/n${YELLOW}]${RESET}: " read CREATE_USER - echo -en "${BLUE}Gib ein Passwort für ${WHITE}$user${BLUE} ein: ${RESET}" - read -s USER_PASSWORD - echo if [ "$CREATE_USER" == "y" ]; then - if sudo adduser --disabled-password --gecos "" "$user" &>/dev/null && echo "$user:$USER_PASSWORD" | sudo chpasswd &>/dev/null && sudo usermod -aG $SUDO_GROUP "$user" &>/dev/null; then - log "Benutzer $user wurde erstellt und zur $SUDO_GROUP-Gruppe hinzugefügt." - 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 + 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 - VALID_USERS+="$user " else - error "Fehler bei der Erstellung von Benutzer $user." + 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..." -sudo tee $SSH_CONFIG_FILE > /dev/null </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 -# X11-Weiterleitung deaktivieren (falls nicht benötigt) -X11Forwarding no - # 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 (Standard) -Subsystem sftp /usr/lib/openssh/sftp-server +# SFTP-Subsystem +Subsystem sftp $SFTP_PATH # Inaktive SSH-Sitzungen überwachen und beenden ClientAliveInterval 300 @@ -227,21 +525,65 @@ AllowUsers $VALID_USERS EOL log "Prüfe SSH-Konfiguration..." -# Überprüfe, ob der Dienst 'ssh' oder 'sshd' existiert und starte ihn -if systemctl list-units --type=service | grep -q "ssh"; then - SERVICE_NAME="ssh" -elif systemctl list-units --type=service | grep -q "sshd"; then - SERVICE_NAME="sshd" -else - error "Kein SSH-Dienst gefunden." + +# Ü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 -if sudo systemctl restart $SERVICE_NAME; then - log "SSH-Dienst erfolgreich neu gestartet." -else - error "Fehler beim Neustart des SSH-Dienstes." - exit 1 +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" \ No newline at end of file +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." \ No newline at end of file