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).
# 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 VERBOSEPerché 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
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
# 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 || trueSe 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
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.
# 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# 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 sshdPerché 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
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.
# 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 | headFase 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).
# Beispiel: Client-Konfiguration ~/.ssh/config
Host bastion
HostName bastion.example.net
User admin
Host internal-*
User admin
ProxyJump bastion
ServerAliveInterval 60Insidia: 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:
# Auf Client und Zielhost: Zeit prüfen
date -u
# NTP/Chrony Status (Beispiel, distroabhängig)
chronyc tracking 2>/dev/null || true
timedatectl statusSe 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:
sudo sshd -T | grep -i 'trustedusercakeys|authorizedprincipals'
# Datei vorhanden?
sudo ls -l /etc/ssh/trusted-user-ca.pubTrappola: 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:
# 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 FAILSe 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.
# Sichere Prüfsequenz vor dem Reload
sudo sshd -t && echo "Config OK" || echo "Config ERROR"
# Erst wenn OK:
sudo systemctl reload sshdConclusione: 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.