IT-Admin.tech

Hardening SSH e gestione delle chiavi: Bastion Hosts, Autorità di certificazione e rotazione delle chiavi

Architekturdiagramm mit Bastion-Host, SSH-CA und Verbindungsflüssen für gehärtete SSH-Zugänge
Bastion-Host und SSH-CA als zentrale Bausteine für kontrollierte, kurzlebige Admin-Zugänge.

In molti ambienti SSH è ancora il principale accesso operativo per i server Linux, host virtuali, gateway di rete e anche per Docker-Hosts. Proprio per questo SSH-Hardening non è un compito «imposta e dimentica», ma un insieme coordinato di indurimento del protocollo, percorsi di accesso, identità (chiavi/certificati) e un ciclo di vita solido per il materiale chiave. Chi limita gli interventi a singole manopole (p. es. «disabilitare il login root»), ma tollera la proliferazione incontrollata di chiavi, l’assenza di rotazione o percorsi di salto non controllati, sposta solo i rischi.

Questo articolo mostra un’architettura obiettivo applicabile in ambito operativo con Bastion-Host (Jump Host come punto di ingresso centrale), SSH Certificate Authority (CA per la firma di certificati SSH a breve durata) e Key-Rotation come processo operativo pianificato. Il focus è su esercizio, amministrazione, auditabilità, troubleshooting, insidie tipiche e una strategia di fallback che non dovrete improvvisare solo durante un incidente.

Perché l’SSH-Hardening fallisce spesso senza gestione delle chiavi

SSH in sé è criptograficamente robusto, ma nella pratica si fallisce di solito su tre punti:

  • Caos di identità: chiavi personali a lunga durata senza scadenza, spesso copiate, senza una visione centrale.
  • Percorsi non controllati: accessi diretti da reti arbitrarie verso sistemi di produzione, spesso complicati da eccezioni VPN o aperture temporanee del firewall.
  • Scarsa disciplina operativa: nessuna rotazione, nessuna possibilità di revoca in pochi minuti, nessuna tracciabilità delle modifiche a authorized_keys.

Le conseguenze sono un’estensione graduale dei privilegi, processi di offboarding difficili, MTTR elevato negli incidenti (perché non è chiaro quale chiave funzioni ancora) e lacune nei requisiti di compliance e audit.

Obiettivo: Bastion-Host, SSH-CA e accessi a breve durata

Un obiettivo praticabile non è un «Big Bang», ma può essere introdotto in modo incrementale:

  • Bastion-Host: un punto d’ingresso indurito e strettamente monitorato attraverso il quale passano le connessioni SSH verso i segmenti interni. Il Bastion-Host riduce la superficie di attacco, centralizza il logging e semplifica le regole di rete.
  • Certificati SSH (OpenSSH Certificates): invece di distribuire chiavi pubbliche su ogni sistema target, i certificati utente a breve durata vengono firmati da una SSH Certificate Authority. Il sistema target si fida della CA e determina i diritti di accesso in base agli attributi del certificato e alle policy locali.
  • Key-Rotation: le host-keys, le CA-keys e (dove ancora necessari) le chiavi utente vengono ruotate secondo regole stabilite. La rotazione è quindi un processo operativo con punti di misurazione, non solo una questione criptografica.

Importante: «Zero Trust» è spesso usato come buzzword; nel contesto SSH significa concretamente dare maggiore peso all’identità, al contesto e alla validità (durate brevi) rispetto al principio «chi è nella rete, può già accedere».

Indurimento di base di OpenSSH: sshd_config, parametri crittografici, superficie di attacco

La base rimane il corretto indurimento del demone SSH (sshd). L’obiettivo è: solo funzioni necessarie, parametri crittografici sicuri, percorsi di autenticazione chiari.

Principio di minima esposizione per autenticazione e funzionalità

Molti rischi derivano da configurazioni «compatibili a ogni costo». Misure tipiche:

  • Disabilitare il login con password (quando organizzativamente possibile) a favore di chiavi o certificati.
  • Controllare il login root (ideale: disabilitarlo; in alternativa: solo tramite certificato e fortemente limitato).
  • Consentire selettivamente Port-Forwarding / Tunneling, anziché abilitare globalmente.
  • Assegnazione dei login tramite gruppi anziché tramite singoli account.
  • Ini
    # Esempio: hardening conservativo di sshd (adattare alle vostre policy)
    # File: /etc/ssh/sshd_config
    
    Protocol 2
    PermitRootLogin no
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PubkeyAuthentication yes
    
    # Consentire solo se realmente necessario
    AllowTcpForwarding no
    X11Forwarding no
    PermitTunnel no
    
    # Ridurre la superficie di attacco esposta
    MaxAuthTries 4
    LoginGraceTime 30
    ClientAliveInterval 300
    ClientAliveCountMax 2
    
    # Gestire l'accesso a livello di policy (esempio)
    AllowGroups ssh-admins ssh-ops
    
    # Logging: per tracciabilità (senza eccesso di log)
    LogLevel VERBOSE

    Perché funziona: Ogni modalità di autenticazione disattivata è un vettore di attacco in meno (credential stuffing, password deboli, phishing). La riduzione delle opzioni di forwarding impedisce che SSH venga usato come «tunnel universale» per movimenti laterali.

    Quando fallisce: Se avete ancora automazioni legacy (p. es. backup/deployment) che richiedono l’accesso tramite password o il port-forwarding. Pertanto: raccogliete le dipendenze prima della disattivazione e migrate in test su host pilota.

    Host Keys: Fingerprints, Algorithmen, planbares Trust-On-First-Use ersetzen

    Molti team vivono con il «Trust On First Use» (TOFU): al primo contatto SSH la chiave host viene accettata e poi messa in cache. Questo è rischioso in ambienti di grandi dimensioni, perché un Man-in-the-Middle al primo contatto è difficile da individuare. Meglio: certificati host tramite una SSH-CA o almeno una distribuzione gestita del file known_hosts.

    Se ruotate gli host key o migrate da RSA a default più moderni, pianificate la cascata: monitoring/automation, Bastion, gestione della configurazione, laptop degli sviluppatori e client Break-Glass.

    Bastion-Host (Jump Host): Architektur, Betrieb und typische Stolperfallen

    Grafica senza testo di una topologia di accesso SSH con il Bastion-Host come unico percorso verso i server interni
    Principio topologico: gli accessi diretti sono bloccati, SSH passa attraverso il Bastion-Host.

    Un Bastion-Host è un server dedicato in un segmento strettamente controllato che funge da unico punto d’accesso SSH per una rete interna. Non sostituisce l’hardening dei sistemi target, ma centralizza i controlli di accesso e la telemetria.

    Principi di rete e firewall

    • Inbound solo da reti admin definite (z. B. VPN, Privileged Access Segment) verso la porta 22 (o una porta alternativa fissa, ma non considerarla «security by obscurity»).
    • Outbound dal Bastion-Host solo verso i subnet/porte di destinazione necessari (di solito 22). Nessun «il Bastion può andare ovunque».
    • Nessuna raggiungibilità diretta degli host di produzione dalla rete utenti/ufficio.

    Trappola: se gestite Docker-Host, spesso si trovano in reti che sono „in qualche modo raggiungibili“, perché gli accessi a build/registry si sono sviluppati storicamente. Separate in modo rigoroso gli accessi di gestione (SSH) dai percorsi dati (Registry, API) ed evitate che un build-runner compromesso possa aprire direttamente una sessione SSH verso la produzione.

    Controllo delle sessioni e tracciabilità

    Per gli audit non conta solo „chi era autorizzato“, ma anche „chi ha fatto cosa e quando“. Approcci classici:

    • SSH-LogLevel VERBOSE per informazioni tracciabili su chiavi/certificati.
    • Derivazione centrale dei log (es. via journald/rsyslog) verso un SIEM o un backend di log.
    • Session Recording (input da tastiera/output del terminale) solo se chiarito correttamente dal punto di vista legale e organizzativo; tecnicamente sensato soprattutto per accessi altamente privilegiati.

    Importante: Bastion-Logging non sostituisce i log locali sui sistemi target. In un incidente servono entrambe le prospettive (Ingress e eventi Host).

    Passaggi di verifica: validare il Bastion-Host nella routine

    Shell
    # 1) Auf dem Bastion: eingehende SSH-Verbindungen prüfen (Linux )
    ss -tnp | grep ':22 '
    
    # 2) Journald: Authentifizierungsereignisse
    journalctl -u ssh -S -2h --no-pager
    
    # 3) Fail2ban/Rate-Limits (falls eingesetzt)
    sudo fail2ban-client status sshd 2>/dev/null || true

    Se qui vedete già „rumore“ (molti fallimenti da reti non previste), è un segnale: le regole Inbound e i controlli a monte (VPN, MFA, Conditional Access) sono troppo aperti.

    SSH Certificate Authority: la distribuzione di chiavi è ormai obsoleta

    Hardware-Token neben Diagramm für SSH-Zertifikate und CA im Admin-Kontext
    Certificati SSH basati su CA: l’identità viene firmata centralmente invece di essere distribuita su ogni host.

    OpenSSH supporta SSH-Zertifikate: un utente mantiene comunque una coppia di chiavi, ma invece di memorizzare la chiave pubblica su ogni server in authorized_keys, viene emesso un certificato. Questo certificato contiene, tra l’altro, l’identità (Principals), la validità (NotBefore/NotAfter) e restrizioni opzionali. Il server si fida della CA tramite una voce TrustedUserCAKeys.

    Vantaggi in esercizio

    • Accessi a breve durata (es. 8–24 ore) riducono significativamente il rischio di chiavi rubate.
    • Offboarding immediato: interrompere l’emissione dalla CA, opzionalmente impostare certificati a breve durata. Non è necessario toccare gli authorized_keys su 200 host.
    • Policy centralizzata: i Principals possono rappresentare ruoli (es. „ops“, „db-admin“), invece di mantenere elenchi per ogni host.
    • Auditabilità: i numeri di serie dei certificati e i Principals compaiono nei log.

    Configurazione di base sui sistemi target

    Sui sistemi target definite la fiducia nella User-CA e mappate i Principals sui permessi locali (tipicamente tramite gruppi Unix e regole sudo). Concetto di esempio:

    • CA-Public-Key è presente come file sull’host.
    • TrustedUserCAKeys lo indica.
    • AuthorizedPrincipalsFile o AuthorizedPrincipalsCommand stabilisce quali Principals sono accettati per quale account.
    Ini
    # Datei: /etc/ssh/sshd_config.d/10-ca.conf (Beispielpfad, distroabhängig)
    
    # Vertrauen in die User-CA
    TrustedUserCAKeys /etc/ssh/trusted-user-ca.pub
    
    # Principals pro Ziel-User definieren
    AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
    
    # Zertifikate erzwingen (optional, abhängig von Ihrer Übergangsphase)
    AuthenticationMethods publickey
    Shell
    # Principals-Dateien anlegen (Beispiel)
    sudo install -d -m 0755 /etc/ssh/auth_principals
    
    echo 'ops' | sudo tee /etc/ssh/auth_principals/admin >/dev/null
    echo 'breakglass' | sudo tee /etc/ssh/auth_principals/emergency >/dev/null
    
    sudo chmod 0644 /etc/ssh/auth_principals/*
    
    # sshd neu laden
    sudo systemctl reload sshd

    Perché questo funziona: L’host non verifica più «la chiave pubblica è nel mio file», ma «questo certificato è firmato dalla mia CA e il Principal è consentito per questo account». La CA diventa così la radice centrale di fiducia.

    Quando fallisce: Se c’è deriva di orario. I certificati sono vincolati al tempo; con orario di sistema errato risulteranno „non ancora validi“ o „scaduti“. NTP/Chrony non è quindi opzionale. Controllate la stabilità dell’orologio in particolare dopo snapshot/RESTore delle VM.

    Proteggere la chiave CA: questa è la vostra „Master Key“

    La User-CA è altamente critica. Chi possiede la CA-Private-Key può firmare qualsiasi accesso. Requisiti minimi:

    • Offline o fortemente isolata (idealmente non sul Bastion-Host stesso).
    • Firma tramite un workflow controllato (ad es. Ticket/Approval, durate brevi, registrazione).
    • Backup e Recovery con controllo degli accessi chiaro.

    Molti team utilizzano qui una PKI interna o una piattaforma per secrets. Ciò che conta non è lo strumento, ma che emissione, durata e revoca/stop siano operationalizzate in modo chiaro.

    Rotazione delle chiavi: Host-Keys, User-Keys, CA-Keys – e cosa può andare storto

    Textfreie Grafik einer Rotation über Zeit mit Parallelvertrauen für SSH-Keys und CA
    Rotazione senza downtime: pianificare la fiducia parallela nella finestra di migrazione.

    Key-Rotation è la sostituzione pianificata delle chiavi, prima che vengano compromesse. Nell’ambito SSH ci sono tre classi che dovRESTe considerare separatamente:

    • Host Keys: Identità del server verso i client. La rotazione riguarda known_hosts, automazione e monitoring.
    • User Keys / Certificati: Identità degli utenti/automazioni verso i server. Con i certificati SSH ruotate soprattutto la policy della CA, mentre la base di chiavi utente viene aggiornata meno frequentemente.
    • CA Keys: Radice di fiducia. La rotazione è possibile, ma deve essere pianificata come finestra di migrazione (fidarsi di più CA in parallelo).

    Rotazione senza downtime: fiducia parallela e finestre di migrazione

    Una procedura pratica è „consentire in parallelo, poi disattivare“:

    • Introdurre una nuova CA e fidarsi di essa sui host target in aggiunta (TrustedUserCAKeys può contenere più chiavi, o in un singolo file o in file separati, a seconda della configurazione).
    • I client ricevono nuovi certificati dalla nuova CA.
    • Dopo la scadenza dei vecchi certificati e alla data stabilita, rimuovere la fiducia nella vecchia CA.

    Per le chiavi host vale un principio analogo tramite known_hosts gestiti oppure tramite certificati host.

    Insidie tipiche nella rotazione

    • Automazioni dimenticate: CI-Runner, server di backup, controlli di monitoring, gestione della configurazione. Spesso utilizzano chiavi proprie.
    • Client embedded: appliance o immagini datate con voci known_hosts codificate.
    • „Accettato una volta“: workstation degli amministratori su cui gli avvisi sul host key sono stati chiusi con un clic. Questo si ripercuote durante una rotazione effettiva.
    • Deriva dell’orologio (nei certificati) e incoerenze DNS/IP (mismatch della host key).

    Implementazione a tappe: dai quick wins all’architettura obiettivo pulita

    Se oggi avete un panorama eterogeneo (server classici, VM, Docker-Host, eventualmente nodi Kubernetes), un piano a tappe è più realistico di una migrazione completa.

    Fase 1: visibilità e igiene

    • Inventariare: dove è aperta la porta 22? Quali sistemi sono raggiungibili direttamente?
    • Igiene delle chiavi: quali authorized_keys si trovano dove? Chi le possiede? Esistono chiavi condivise?
    • Centralizzare il logging: almeno la Bastion e le classi di server critiche verso un backend di log.
    Shell
    # Grober Check: Welche Accounts haben authorized_keys?
    sudo find /home /root -maxdepth 2 -type f -name authorized_keys -print
    
    # Inhalte prüfen (Vorsicht: sensible Daten)
    # Tipp: nur Fingerprints der Public Keys extrahieren
    sudo awk '{print $1" "$2}' /home/*/.ssh/authorized_keys 2>/dev/null | sort -u | head

    Fase 2: imporre il Bastion-Host

    Tecnicamente lo si impone tramite regole di rete (Security Groups/Firewall) e tramite policy del server SSH sui host target (solo l’IP della Bastion può raggiungere la porta 22). A livello organizzativo gli strumenti per gli admin e i runbook devono essere adattati (ProxyJump, ProxyCommand).

    Ssh
    # Beispiel: Client-Konfiguration ~/.ssh/config
    Host bastion
      HostName bastion.example.net
      User admin
    
    Host internal-*
      User admin
      ProxyJump bastion
      ServerAliveInterval 60

    Insidia: se gestite la Bastion come single point of failure, scambiate un rischio con un altro. Pianificate almeno una ridondanza (p.es. due Bastion in domini di failure separati) e una procedura documentata di break-glass.

    Fase 3: introdurre una SSH-CA per gli accessi utente

    Avviate con un segmento pilota. Impostate durate brevi (p.es. una giornata lavorativa) e definite i principals in modo che corrispondano ai vostri ruoli. Costruite in parallelo una possibilità di revoca: se potete interrompere l’emissione, il danno massimo dovuto a un certificato compromesso è limitato alla sua durata.

    Fase 4: modellare le automazioni correttamente (nicht „Admin-Key für alles“)

    Le automazioni necessitano di identità proprie. Separate:

    • Accesso amministrativo umano (interattivo, di breve durata, tracciabile)
    • Accesso macchina (non interattivo, strettamente limitato, idealmente anch’esso basato su logica di certificati o su deploy-key chiaramente isolati)

    Se amministrate Docker-Host via SSH (p.es. per emergenze), definite per essi principals/account dedicati e evitate che i sistemi CI utilizzino lo stesso percorso.

    Troubleshooting: Quando i certificati SSH o le connessioni Bastion non funzionano

    In pratica servono passaggi di verifica rapidi, utilizzabili senza conoscenze specialistiche.

    1) Certificato scaduto o „non ancora valido“

    Sintomo: il login fallisce nonostante la configurazione corretta. La causa è spesso una deriva temporale. Verificare:

    Shell
    # Auf Client und Zielhost: Zeit prüfen
    date -u
    
    # NTP/Chrony Status (Beispiel, distroabhängig)
    chronyc tracking 2>/dev/null || true
    timedatectl status

    Se l’orario non è corretto: risolvere prima il problema di tempo, poi riprovare. L’autenticazione tramite certificato in questo caso è rigorosamente vincolante.

    2) Il server si fida della CA sbagliata (o di nessuna)

    Verificare che la chiave pubblica della CA sia corretta e caricata:

    Shell
    sudo sshd -T | grep -i 'trustedusercakeys|authorizedprincipals'
    
    # Datei vorhanden?
    sudo ls -l /etc/ssh/trusted-user-ca.pub

    Trappola: split della configurazione tramite sshd_config.d e l’ordine dei file. Validare sempre con sshd -T, perché mostra la configurazione effettiva.

    3) Il proxy Bastion si interrompe (rete/firewall)

    Se ProxyJump si blocca o si interrompe, spesso non è un problema SSH ma di routing/firewall. Verificare dal Bastion la raggiungibilità della porta di destinazione:

    Shell
    # Auf dem Bastion-Host: Zielhost erreichbar?
    TARGET=internal-host-01
    nc -vz $TARGET 22
    
    # Alternativ mit bash TCP (ohne nc)
    timeout 3 bash -c "</dev/tcp/$TARGET/22" && echo OK || echo FAIL

    Se questo fallisce, i log SSH sul client sono di scarsa utilità. A quel punto il percorso di rete e i gruppi di sicurezza sono il livello corretto da indagare.

    Checklist: Hardening SSH in ambienti aziendali (orientata all’esercizio)

    • Rete: porta 22 accessibile solo dal segmento admin/Bastion, nessuna eccezione diretta “temporanea” senza scadenza.
    • Auth: login con password disabilitato o fortemente limitato; controllo di gruppo chiaro (AllowGroups).
    • Bastion: rinforzato, versione software minimale, RESTrizioni sulle connessioni in uscita, log centralizzati, processo di Break-Glass definito.
    • Certificati: SSH-CA introdotta, durate brevi, Principals basati sui ruoli, tempo/NTP stabile.
    • Rotazione: Host-Keys/CA-Keys/User-Keys pianificati, trust parallelo nella finestra di migrazione, automazioni inventariate.
    • Audit: LogLevel, correlazione centrale dei log, tracciabilità degli accessi amministrativi.

    Strategia di fallback: cosa fare se la nuova autenticazione blocca tutto?

    Ogni indurimento può, in caso di errore, provocare un „interruzione auto-inflitta“. Pianificate quindi esplicitamente una strategia di fallback:

    • Accesso out-of-band: console/iDRAC/IPMI/Cloud-Serial-Console – ma protetto e testato.
    • Break-Glass Account: account dedicato con accesso strettamente controllato, idealmente accessibile solo tramite Bastion e attivabile per periodi limitati.
    • Rollout a fasi: prima pilota, poi ondate. Mai migrare l’intero parco simultaneamente.
    • Cambi di configurazione atomici: distribuire le modifiche in modo che sia possibile un reload (e non un riavvio forzato nel mezzo di un errore).

    Pratica consolidata: prima di ogni modifica a sshd_config mantenere una seconda sessione già aperta, verificare sintassi (sshd -t) e solo dopo eseguire il reload.

    Shell
    # Sichere Prüfsequenz vor dem Reload
    sudo sshd -t && echo "Config OK" || echo "Config ERROR"
    
    # Erst wenn OK:
    sudo systemctl reload sshd

    Conclusione: l’hardening SSH diventa davvero gestibile con CA e rotazione

    L’hardening SSH è più efficace quando non ci si limita a «irrobustire» soltanto il processo sshd, ma si operationalizza l’intero percorso di accesso: Bastion-Hosts riducono la superficie d’attacco e concentrano la telemetria; una CA per SSH rende le identità controllabili e di breve durata; la rotazione delle chiavi cessa di essere un’eccezione fastidiosa per diventare un processo pianificato. È fondamentale considerare fin dall’inizio la stabilità del tempo (NTP), le dipendenze (automazioni) e una strategia di rollback testata. In questo modo SSH non solo diventa più sicuro, ma anche più gestibile nella routine operativa.

    Per questo tema sono importanti anche Ssh Key Management e Ssh Zertifikate. Il contributo inquadra questi aspetti in modo comprensibile e indica cosa conta nell’operatività quotidiana.

    Weiterfuehrend

    Passende weitere Inhalte