From 6d9348fc137b3fbaea305538c07b676362d58f23 Mon Sep 17 00:00:00 2001 From: admManuel Date: Wed, 7 May 2025 19:25:53 +0000 Subject: [PATCH] Update Linux/SSH/secure_ssh.sh --- Linux/SSH/secure_ssh.sh | 238 +++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 139 deletions(-) diff --git a/Linux/SSH/secure_ssh.sh b/Linux/SSH/secure_ssh.sh index aeb7b56..37a862c 100644 --- a/Linux/SSH/secure_ssh.sh +++ b/Linux/SSH/secure_ssh.sh @@ -1,182 +1,142 @@ #!/usr/bin/env bash # ────────────────────────────────────────────────────────────────────────────── -# Secure‑SSH Setup – Modern Linux (2025‑edition, PAM‑aware) -# ---------------------------------------------------------- -# ✦ Generates hardened OpenSSH config (IPv4‑only) -# ✦ Installs / updates OpenSSH‑server + creates host keys -# ✦ Creates users, adds SSH public keys, restricts login -# ✦ Removes deprecated directives – fully OpenSSH ≥9.x compliant -# ✦ Dynamically omits UsePAM if PAM isn’t present (e.g. Alpine) -# ✦ Adds post‑quantum KEX, minimal cipher suite, strict auth‑flow, -# rate‑limiting & root lockdown +# Secure-SSH Hardened Setup (OpenSSH ≥9.x) +# ---------------------------------------- +# ✦ Minimal Defaults + Explizite Härtung +# ✦ Unterstützt: +# - Benutzer/Gruppen-Whitelisting +# - Auto-Logoff (Idle-Timeouts) +# - Brute-Force-Rate-Limiting +# - Kein Forwarding (Agent/TCP/X11) +# ✦ Dynamisches PAM-Handling # ────────────────────────────────────────────────────────────────────────────── -printf "\033c" # clear terminal +printf "\033c" # Clear terminal +# ─── Konfigurationsvariablen ───────────────────────────────────────────────── 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" -# ─── ANSI colors ────────────────────────────────────────────────────────────── +# ─── ANSI Colors ───────────────────────────────────────────────────────────── RED='\033[1;31m'; GREEN='\033[1;32m'; YELLOW='\033[1;33m'; BLUE='\033[1;34m'; WHITE='\033[1;37m'; RESET='\033[0m' -log() { echo -e "${GREEN}$1${RESET}"; } -warn() { echo -e "${YELLOW}$1${RESET}"; } -error() { echo -e "${RED}$1${RESET}"; } +log() { echo -e "${GREEN}[+] $1${RESET}"; } +warn() { echo -e "${YELLOW}[!] $1${RESET}"; } +error() { echo -e "${RED}[✗] $1${RESET}"; } -# ─── Service‑manager detection ─────────────────────────────────────────────── +# ─── Service Manager Detection ────────────────────────────────────────────── detect_service_manager() { - if command -v systemctl &>/dev/null; then echo systemd - elif command -v rc-service &>/dev/null; then echo openrc # Alpine, Gentoo… - elif command -v service &>/dev/null; then echo sysvinit - else echo unknown; fi -} - -# ─── SSH service‑name detection ─────────────────────────────────────────────── -detect_ssh_service() { - local manager=$1 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 ;; - openrc) - for s in "${services[@]}"; do rc-service -l | grep -q "^$s$" && { echo $s; return; }; done ;; - sysvinit) - for s in "${services[@]}"; do [ -x "/etc/init.d/$s" ] && { echo $s; return; }; done ;; - esac - [ -x /usr/sbin/sshd ] && echo sshd || echo unknown + if command -v systemctl &>/dev/null; then echo "systemd"; return; fi + command -v rc-service &>/dev/null && echo "openrc" || echo "sysvinit" } +# ─── SSH Service Handling ────────────────────────────────────────────────── restart_ssh_service() { - local manager=$1 service=$2; warn "Starte SSH‑Dienst ($service) neu…" - case $manager in - systemd) sudo systemctl restart "$service" && return 0 ;; - openrc) sudo rc-service "$service" restart && return 0 ;; - sysvinit) sudo "/etc/init.d/$service" restart 2>/dev/null && return 0 ;; - esac - sudo killall -HUP sshd 2>/dev/null && return 0 - return 1 + local service=$1 + case $(detect_service_manager) in + systemd) sudo systemctl restart "$service" ;; + openrc) sudo rc-service "$service" restart ;; + sysvinit) sudo "/etc/init.d/$service" restart 2>/dev/null ;; + *) sudo killall -HUP sshd 2>/dev/null ;; + esac || { error "Failed to restart SSH"; return 1; } } +# ─── Paketinstallation ────────────────────────────────────────────────────── install_package() { - local p=$1; warn "Installiere $p…" - if command -v apt &>/dev/null; then sudo apt update -qq && sudo apt install -y $p -qq - elif command -v dnf &>/dev/null; then sudo dnf install -y $p &>/dev/null - elif command -v yum &>/dev/null; then sudo yum install -y $p &>/dev/null - elif command -v apk &>/dev/null; then sudo apk add $p &>/dev/null - elif command -v pacman &>/dev/null; then sudo pacman -Sy --noconfirm $p &>/dev/null - elif command -v zypper &>/dev/null; then sudo zypper install -y $p &>/dev/null - else error "Paketmanager nicht erkannt – installiere $p manuell."; return 1; fi - log "$p installiert." + local pkg=$1 + warn "Installing $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 apk &>/dev/null; then + sudo apk add "$pkg" &>/dev/null + else + error "Package manager not found. Install $pkg manually." + return 1 + fi || { error "Installation failed"; return 1; } + log "$pkg installed." } -# ─── Preparations ───────────────────────────────────────────────────────────── -SERVICE_MANAGER=$(detect_service_manager); log "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 -[ -d "$SSH_CONFIG_DIR" ] || { warn "Erstelle $SSH_CONFIG_DIR"; sudo mkdir -p "$SSH_CONFIG_DIR"; } +# ─── Hauptsetup ──────────────────────────────────────────────────────────── +log "Starting Secure-SSH Setup..." -# ─── Host keys ──────────────────────────────────────────────────────────────── -for entry in "$ED25519_KEY ed25519" "$ECDSA_KEY ecdsa -b 384"; do - set -- $entry; key=$1; shift; args=$* - [ -f "$key" ] || { warn "Generiere Host-Key $(basename $key)…"; sudo ssh-keygen -t $args -f "$key" -N "" -q && sudo chmod 600 "$key" && log "Key erstellt."; } -done +# ─── Voraussetzungen prüfen ──────────────────────────────────────────────── +command -v sudo &>/dev/null || install_package sudo +command -v sshd &>/dev/null || install_package openssh-server +[ -d "$SSH_CONFIG_DIR" ] || { sudo mkdir -p "$SSH_CONFIG_DIR"; log "Created $SSH_CONFIG_DIR"; } -# ─── 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 -sudo rm -f $SSH_CONFIG_DIR/* +# ─── Host Key (Ed25519) ──────────────────────────────────────────────────── +[ -f "$ED25519_KEY" ] || { + warn "Generating Ed25519 host key..." + sudo ssh-keygen -t ed25519 -f "$ED25519_KEY" -N "" -q && sudo chmod 600 "$ED25519_KEY" + log "Host key generated." +} -# ─── User handling ──────────────────────────────────────────────────────────── -read -rp $'\e[1;34mWelche Benutzer dürfen sich per SSH anmelden? (Leerzeichen-getrennt): \e[0m' SSH_USERS -VALID_USERS="" - -# 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 u in $SSH_USERS; do - if id "$u" &>/dev/null; then log "Benutzer $u existiert."; VALID_USERS+="$u "; continue; fi - read -rp $'\e[1;34mBenutzer '"$u"$' anlegen? [y/N]: \e[0m' create; [[ $create =~ ^[Yy]$ ]] || continue - read -rsp $'\e[1;34mPasswort für '"$u"$': \e[0m' pw; echo - sudo useradd -m -s /bin/bash "$u" && echo "$u:$pw" | sudo chpasswd - sudo usermod -aG "$SUDO_GROUP" "$u" - sudo install -d -m700 -o "$u" -g "$u" "/home/$u/.ssh" - sudo touch "/home/$u/.ssh/authorized_keys" && sudo chmod 600 "/home/$u/.ssh/authorized_keys" && sudo chown "$u":"$u" "/home/$u/.ssh/authorized_keys" - read -rp $'\e[1;34mSSH Public Key für '"$u"$' 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/$u/.ssh/authorized_keys" >/dev/null; fi - VALID_USERS+="$u " -done - -# ─── SFTP binary discovery ─────────────────────────────────────────────────── -for p in /usr/lib/openssh/sftp-server /usr/libexec/openssh/sftp-server /usr/lib/ssh/sftp-server; do [ -x "$p" ] && SFTP_PATH=$p && break; done -SFTP_PATH=${SFTP_PATH:-internal-sftp}; log "SFTP-Pfad: $SFTP_PATH" - -# ─── PAM detection ──────────────────────────────────────────────────────────── -PAM_AVAILABLE=false -[ -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 ausgelassen." - -# ─── Generate secure.conf ───────────────────────────────────────────────────── -warn "Erstelle $SSH_CONFIG_FILE (modern hardened)…" +# ─── Benutzer/Gruppen-Abfrage ────────────────────────────────────────────── +read -rp $'\e[1;34mAllowed SSH users (space-separated): \e[0m' SSH_USERS +read -rp $'\e[1;34mAllowed SSH group (leave empty if unused): \e[0m' SSH_GROUP +# ─── Konfigurationsdatei erstellen ───────────────────────────────────────── +warn "Generating hardened SSH config..." sudo tee "$SSH_CONFIG_FILE" >/dev/null </dev/null +# ─── PAM Handling (dynamisch) ────────────────────────────────────────────── +if [ -d /etc/pam.d ] && find / -name 'libpam.so*' -quit 2>/dev/null; then + echo -e "UsePAM yes\nPrintMotd no" | sudo tee -a "$SSH_CONFIG_FILE" >/dev/null + log "PAM support enabled." fi -log "Secure‑Config geschrieben." +# ─── Konfiguration testen & neu starten ──────────────────────────────────── +sudo sshd -t || { error "Invalid SSH config. Fix errors before restarting."; exit 1; } +restart_ssh_service $(basename "$(command -v sshd)") || exit 1 -# ─── Validate & restart SSH ────────────────────────────────────────────────── -[ -d /run/sshd ] || { sudo mkdir -p /run/sshd; sudo chmod 0755 /run/sshd; } - -sudo sshd -t || { error "SSH-Konfiguration ungültig!"; exit 1; } - -SSH_SERVICE=$(detect_ssh_service "$SERVICE_MANAGER") -[ "$SSH_SERVICE" = unknown ] && { error "SSH-Dienst nicht gefunden."; exit 1; } - -restart_ssh_service "$SERVICE_MANAGER" "$SSH_SERVICE" || { error "Neustart fehlgeschlagen – manuell prüfen."; exit 1; } - -log "Setup abgeschlossen. Zugelassene Benutzer: ${WHITE}${VALID_USERS}${RESET}" +log "Hardened SSH setup complete!" +echo -e "\n${WHITE}→ Allowed users: ${SSH_USERS}${RESET}" +[ -n "$SSH_GROUP" ] && echo -e "${WHITE}→ Allowed group: ${SSH_GROUP}${RESET}" +echo -e "${WHITE}→ Active settings:${RESET}" +sudo sshd -T | grep -Ei "allowusers|allowgroups|permitroot|maxauthtries|clientalive" \ No newline at end of file