SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor

Storia di SSH: da telnet a OpenSSH

Un attacco del 1995 a Helsinki portò alla nascita di SSH: ecco la timeline verificata da telnet e rlogin a OpenSSH e ai default post-quantum.

Dove inizia la storia di SSH

La storia di SSH inizia con le password rubate. Prima del 1995, per accedere a una macchina Unix remota si usavano telnet o rlogin, che trasmettevano entrambi la password sulla rete in testo leggibile. Chiunque potesse monitorare il traffico poteva leggerla e, già all'inizio degli anni 1990, questo avveniva su larga scala.

SSH fu la risposta di una sola persona a questo problema. Fu scritto nel 1995 e distribuito gratuitamente. Da allora il protocollo è stato riscritto una volta e il programma utilizzato oggi dalla quasi totalità degli utenti è un fork di un fork. Le date riportate di seguito sono importanti, perché ogni passaggio rispondeva a un problema specifico.

Cosa trasmettevano realmente telnet e rlogin

Telnet è definito nella RFC 854, pubblicata nel maggio 1983 da Jon Postel e Joyce Reynolds. Descrive una sessione terminale trasportata tramite TCP e non prevede alcun tipo di crittografia. Ogni byte digitato, inclusa la password, viaggia come byte in chiaro che qualsiasi dispositivo lungo il percorso può leggere.

rlogin deriva da Berkeley Unix e fu descritto successivamente nella RFC 1282 (BSD Rlogin, B. Kantor, dicembre 1991). Introduceva un rischio ancora maggiore rispetto a una password leggibile: la fiducia basata sull'host. Era possibile configurare un server affinché accettasse senza password i login provenienti da un host specifico. La RFC contiene una sezione intitolata "A Cautionary Tale" che afferma: "Bypassing password authentication from trusted hosts opens ALL the systems so configured when just one is compromised." Nota inoltre che la fiducia si basa sui nomi host, quindi una compromissione del DNS (domain name system) o un indirizzo contraffatto sono sufficienti per aggirarla.

Entrambi i progetti erano adatti alla rete per cui erano stati concepiti. Le prime reti Ethernet utilizzavano un mezzo condiviso: ogni macchina di un segmento riceveva ogni frame e doveva ignorare quelli non indirizzati a essa. Una macchina che smetteva di ignorarli, cioè che entrava in modalità promiscua, poteva vedere il traffico degli altri host. Se un'università assegnava account shell a migliaia di studenti, un singolo account compromesso poteva quindi trasformarsi in uno strumento per raccogliere le password di un intero dipartimento.

L'avviso del 1994 arrivato senza una correzione

Il 3 febbraio 1994 CERT pubblicò l'avviso CA-94:01, "Ongoing Network Monitoring Attacks". L'avviso riferiva che gli intrusi avevano acquisito le informazioni di accesso di decine di migliaia di sistemi su Internet. Lo strumento utilizzato impostava l'interfaccia di rete in modalità promiscua e registrava l'inizio di ogni nuova sessione telnet, rlogin e FTP, cioè la parte che contiene il nome utente e la password.

CERT consigliava ai siti di cambiare la password di ogni account accessibile tramite rete. Se si considera questa indicazione alla luce dei protocolli, il problema è evidente: la nuova password attraversa la stessa rete in testo in chiaro al primo utilizzo. Non esisteva alcuna correzione applicabile a telnet o rlogin, perché nessuno dei due protocolli prevedeva un meccanismo in cui inserirla.

Perché un attacco di sniffing a Helsinki ha portato alla nascita di SSH

Nel 1995, la rete dell'Helsinki University of Technology fu colpita da un attacco di sniffing delle password del tipo descritto da CERT. Tatu Ylönen, un ricercatore dell'università, scrisse un sostituto e lo distribuì come freeware nel luglio 1995. Lo chiamò Secure Shell.

Alla base c'erano due decisioni progettuali. La sessione era cifrata, quindi chi intercettava il traffico sul segmento non poteva ricavarne informazioni utili. Inoltre, il server dimostrava la propria identità tramite una chiave, così il client poteva verificare di essersi connesso alla macchina corretta. Questo era il punto debole lasciato aperto dalla fiducia nel nome host di rlogin.

Il software si diffuse anche perché i comandi corrispondevano a quelli che gli utenti digitavano già. ssh sostituiva rsh e rlogin, mentre scp sostituiva rcp. Il passaggio richiedeva di cambiare un'abitudine, non il flusso di lavoro. Alla fine del 1995 la base utenti aveva raggiunto circa 20,000 utenti in cinquanta paesi. Nel dicembre dello stesso anno, Ylönen fondò SSH Communications Security per sviluppare e vendere il software.

Da una release gratuita a un prodotto commerciale

Quando SSH è diventato un’attività commerciale, la licenza del codice sorgente è cambiata. Le release successive hanno introdotto condizioni che limitavano ciò che altri potevano fare con il codice, e l’ultima release che chiunque poteva riutilizzare liberamente era ssh 1.2.12. Non c’è nulla di improprio. Semplicemente, la versione di SSH su cui il resto del mondo poteva basarsi ha smesso di evolvere, mentre lo sviluppo è proseguito in un contesto che quel mondo non poteva seguire. Le licenze determinano quale codice continua a essere utilizzabile, un tema che vale la pena approfondire in come le licenze open source hanno plasmato l’infrastruttura moderna.

Perché OpenBSD fece il fork di OpenSSH nel 1999

All'inizio del 1999 Björn Grönvall riprese quell'ultima release libera e iniziò a correggerne i bug. La sua versione si chiamava OSSH e supportava soltanto il protocollo SSH 1.3.

Il progetto OpenBSD adottò OSSH e lo ricostruì. Secondo il resoconto del progetto, Theo de Raadt, Niels Provos, Markus Friedl, Bob Beck, Aaron Campbell e Dug Song si occuparono di ripulire, verificare ed estendere il codice. Il risultato fu OpenSSH 1.2.2, distribuito con OpenBSD 2.6 il 1 dicembre 1999.

Perché il fork di un piccolo progetto di sistema operativo finì per essere presente su quasi tutte le macchine? Per le esigenze di OpenBSD. OpenBSD distribuisce un sistema di base sottoposto ad audit, progettato per essere sicuro nella configurazione predefinita. Per questo l'accesso remoto cifrato doveva rientrare nel sistema di base e usare una licenza senza restrizioni. Codice sottoposto ad audit e distribuito con una licenza senza restrizioni era esattamente ciò che volevano anche tutti gli altri fornitori di sistemi operativi. Damien Miller, Philip Hands e altri avviarono quasi subito un ramo portabile, da cui deriva il p in una versione come 10.5p1. OpenBSD sviluppa la versione pulita, mentre il ramo portabile aggiunge il codice di integrazione necessario per tutto il resto. Il modo in cui Unix si è suddiviso nei sistemi che usiamo oggi spiega perché quel codice di integrazione sia necessario.

Il supporto per la seconda versione del protocollo arrivò in seguito. OpenSSH 2.0 fu distribuito con OpenBSD 2.7 il 15 giugno 2000.

Perché SSH-2 è un nuovo protocollo e non un semplice aggiornamento di versione

SSH-1 proteggeva l'integrità del flusso cifrato con CRC-32, un checksum progettato per rilevare gli errori di trasmissione, non per resistere a un attaccante. Nel 1998 Ariel Futoransky ed Emiliano Kargieman di CORE SDI hanno dimostrato le conseguenze. Con le modalità di cifratura CBC o CFB e un controllo CRC-32, un attaccante che conosce anche solo 16 byte del testo in chiaro può inserire testo cifrato scelto da lui che il destinatario accetta come autentico. Questo consente di eseguire comandi sul server.

Il difetto era nel protocollo, quindi non poteva essere corretto senza interrompere la compatibilità. Le implementazioni hanno invece incluso un rilevatore, cioè codice in un file chiamato deattack.c, che tentava di riconoscere l'attacco mentre era in corso. Nel febbraio 2001 è emerso che il rilevatore conteneva a sua volta un integer overflow, CVE-2001-0144, che consentiva l'esecuzione remota di codice contro i server e i client che avevano applicato la patch. Un design che non può essere corretto accumula patch, e le patch introducono a loro volta nuovi bug.

SSH-2 è stato definito da un gruppo di lavoro IETF denominato secsh e pubblicato come serie di RFC nel gennaio 2006: l'architettura in RFC 4251, il livello di trasporto in RFC 4253, l'autenticazione degli utenti in RFC 4252 e il livello di connessione in RFC 4254. La suddivisione in livelli è l'aspetto più importante, perché consente di sostituire ogni livello separatamente. Gran parte della storia successiva consiste proprio nella sostituzione di questi componenti.

Emergono due cambiamenti principali. La protezione dell'integrità è passata da CRC-32 a un HMAC (codice di autenticazione dei messaggi basato su hash) con una chiave derivata da un segreto condiviso. Un attaccante che non può calcolare il MAC non può falsificare un pacchetto. Anche l'accordo sulla chiave è passato a Diffie-Hellman. In SSH-1 il client sceglieva la chiave di sessione e la inviava cifrata con le chiavi RSA del server. Chiunque avesse ottenuto in seguito quelle chiavi private avrebbe quindi potuto decifrare una sessione registrata. Diffie-Hellman deriva un nuovo segreto per ogni sessione e non lo trasmette mai. Di conseguenza, registrare il traffico e rubare in seguito la chiave dell'host non consente di ricavare nulla. Questa proprietà è chiamata forward secrecy.

SSH-2 non condivide alcuna compatibilità a livello di protocollo con SSH-1. Per questo il numero è cambiato, invece di limitarsi a un incremento decimale.

Perché SSH-1 è stato rimosso invece di essere corretto

La rimozione è avvenuta in tre release di OpenSSH. La versione 7.0, dell'11 agosto 2015, ha disabilitato il protocollo 1 per impostazione predefinita in fase di compilazione. La versione 7.4, del 19 dicembre 2016, ha rimosso il supporto lato server. La versione 7.6, del 3 ottobre 2017, ha eliminato anche il lato client, insieme alle relative opzioni di configurazione e alla documentazione.

Mantenere il protocollo come opzione per le apparecchiature obsolete sarebbe stata la scelta più compatibile, ma il rilevatore CRC-32 spiega perché è stata rifiutata. L'overflow era raggiungibile solo perché il codice del protocollo 1 veniva incluso nella compilazione, e si trovava in un percorso che la maggior parte degli amministratori riteneva inattivo sui propri sistemi. Il codice incluso in una release può essere raggiunto. Il codice eliminato non può esserlo.

Perché la prima connessione SSH avvisa sulla chiave host

La crittografia indica che il traffico è privato. Non indica chi si trova all'altra estremità. Se un attaccante si inserisce nel percorso e risponde al posto del server, si ottiene una sessione perfettamente crittografata con l'attaccante: è un attacco machine-in-the-middle. SSH risponde a questo rischio con una chiave host: il server dimostra di possedere la parte privata di una coppia di chiavi e il client verifica quella chiave confrontandola con il valore registrato in precedenza. Per informazioni sul funzionamento della connessione, vedere cosa accade quando si apre una connessione SSH.

Alla prima connessione non esiste un valore precedente. Il client non ha quindi nulla con cui effettuare il confronto e deve chiedere conferma:

The authenticity of host 'vps.example.com (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:BQ0Qs2jVXhH2lPZ2rM0aQ0mQ8f9pQ0m3nH0oQ1bYqkE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Rispondendo yes, la chiave viene salvata in ~/.ssh/known_hosts. A ogni connessione successiva viene effettuato il confronto con il valore salvato. Se i valori non corrispondono, viene visualizzato il messaggio più importante disponibile nel programma:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

Il significato corretto del primo messaggio è che il protocollo ammette il proprio unico momento di debolezza. Il trust on first use indica che la sicurezza della prima connessione dipende esclusivamente dalla rete utilizzata. È possibile ridurre questo rischio. Leggete l'impronta digitale nella console del provider o nel log della build del server prima di connettervi. Pubblicatela nel DNS come record SSHFP (RFC 4255), ma questa misura è utile soltanto se utilizzate DNSSEC. In alternativa, firmate le chiavi host con una vostra certificate authority (CA), in modo che i client si fidino della CA e non di ogni singola chiave. Nella pratica, la maggior parte delle persone accetta il messaggio senza effettuare verifiche. È importante tenerne conto.

Come le chiavi pubbliche hanno messo da parte le password

L’autenticazione a chiave pubblica era disponibile fin dalle prime release di SSH, ma sono serviti anni perché diventasse la pratica normale. Il meccanismo è asimmetrico: il client dimostra di possedere una chiave privata firmando una challenge, e la chiave privata non lascia mai il client. Una password funziona al contrario. Anche se SSH la trasmette all’interno del canale cifrato, il server riceve il secret effettivo. Di conseguenza, un server compromesso o ostile conserva un elemento che può riutilizzare contro di te altrove.

Il secondo motivo è matematico. Qualsiasi server con la porta 22 aperta su un indirizzo pubblico riceve tentativi di accesso automatizzati senza interruzione, e una password è una stringa che si può indovinare. Una chiave non è indovinabile in alcun senso pratico. L’impostazione PasswordAuthentication no elimina questa intera categoria di attacchi, per questo compare in ogni checklist di hardening. La generazione e la rotazione delle chiavi sono descritte in Nozioni di base sulla gestione delle chiavi SSH, mentre le impostazioni lato server sono trattate in Hardening di SSH su un VPS.

Perché l'elenco degli algoritmi SSH cambia continuamente

Un protocollo a livelli consente di ritirare gli algoritmi senza introdurre un nuovo protocollo. OpenSSH ha sfruttato questa possibilità in modo costante, come mostra la sequenza delle release.

Ed25519 è arrivato in OpenSSH 6.5 il 30 January 2014, insieme al cifrario chacha20-poly1305 e a un formato per le chiavi private protetto da bcrypt. Le firme Ed25519 derivano il nonce usato per ogni firma in modo deterministico. Un generatore di numeri casuali debole durante la firma non può quindi esporre la chiave privata. È esattamente così che sono state recuperate chiavi private DSA ed ECDSA in incidenti reali.

DSA ha seguito il percorso opposto. Nel 2015, OpenSSH 7.0 ha disabilitato ssh-dss le chiavi host e utente in fase di esecuzione, perché l'algoritmo è limitato a una chiave privata di 160 bit e a SHA-1. La versione 9.8, il 1 July 2024, ha disabilitato DSA in fase di compilazione. La versione 10.0, il 9 April 2025, lo ha rimosso, con le parole del progetto: "completing the deprecation process that began in 2015". Dieci anni dalla disabilitazione alla rimozione.

RSA non è scomparso, ma è scomparso il suo vecchio formato di firma. OpenSSH 8.8, il 26 September 2021, ha smesso di accettare per impostazione predefinita le firme RSA generate con SHA-1. Le note di rilascio indicano chiaramente il motivo: SHA-1 è compromesso dal punto di vista crittografico e le collisioni a prefisso scelto erano ottenibili con meno di USD 50,000. Se durante la connessione a un server obsoleto hai mai incontrato sign_and_send_pubkey: no mutual signature supported, si tratta di questa modifica. La chiave è valida. Non lo è l'algoritmo di firma richiesto dall'altra estremità.

Lo stesso processo riguarda ora lo scambio di chiavi, questa volta in anticipo rispetto alla minaccia. Il traffico acquisito oggi può essere archiviato e decifrato anni dopo da chi per primo possiederà un computer quantistico sufficientemente potente. Per questo l'accordo sulle chiavi doveva cambiare prima che una macchina simile esistesse. OpenSSH 9.0, l'8 April 2022, ha reso predefinito uno scambio di chiavi ibrido: sntrup761x25519-sha512@openssh.com combina un algoritmo post-quantistico con lo scambio X25519. Il risultato non è quindi più debole della parte classica se il nuovo algoritmo si dimostra inadeguato. OpenSSH 9.9, il 19 September 2024, ha aggiunto mlkem768x25519-sha256, basato su ML-KEM (meccanismo di incapsulamento delle chiavi su reticoli), standardizzato da NIST nel 2024. OpenSSH 10.0 lo ha reso predefinito per l'accordo sulle chiavi, e la pagina post-quantistica del progetto spiega le motivazioni. OpenSSH 10.1, il 6 October 2025, ha iniziato a mostrare un avviso quando l'altra estremità non lo supporta:

** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded.

L'avviso è attivo per impostazione predefinita ed è controllato dall'opzione WarnWeakCrypto in ssh_config. Il significato pratico e le azioni da intraprendere per un server che lo attiva sono descritti in le impostazioni predefinite dello scambio di chiavi SSH post-quantistico.

Cosa significa questa storia per il server che stai gestendo

Il comando che digiti è cambiato pochissimo dal 1995. Quasi tutto ciò che sta sotto è stato sostituito: il controllo di integrità, lo scambio di chiavi, gli algoritmi di firma e lo stesso codice sorgente. È stato possibile soltanto perché ogni sostituzione si è conclusa con una rimozione pianificata, e ogni rimozione ha causato problemi a qualcuno.

La sicurezza SSH dipende quindi soprattutto dalla versione in uso. I valori predefiniti determinano quali algoritmi vengono offerti, quali vengono rifiutati e quali avvisi vengono visualizzati. Un server obsoleto continua a offrire gli algoritmi consentiti dalla propria release e continua a negoziare una versione meno sicura per soddisfare un client datato. Ad agosto 2026 la release corrente è OpenSSH 10.5, pubblicata l'11 agosto 2026. La distanza tra questa versione e quella installata su una macchina che nessuno ha aggiornato da tre anni indica l'entità del problema. Verificare la versione rientra nelle prime dieci attività da svolgere su un nuovo VPS.

FAQ

Chi ha creato SSH e perché?

Tatu Ylönen, ricercatore presso la Helsinki University of Technology, ha scritto SSH nel 1995 dopo un attacco di sniffing delle password sulla rete dell'università. Gli strumenti di accesso remoto dell'epoca, telnet e rlogin, trasmettevano le password sulla rete come testo leggibile. Chiunque monitorasse un segmento condiviso poteva quindi raccogliere le credenziali durante il transito. Ha rilasciato il programma come freeware nel luglio 1995. Alla fine di quell'anno contava circa 20,000 utenti in cinquanta paesi e, nel dicembre 1995, ha fondato SSH Communications Security.

Qual è la differenza tra SSH-1 e SSH-2?

Sono protocolli diversi e non compatibili a livello di wire protocol. SSH-1 era un unico protocollo monolitico che usava CRC-32 per l'integrità e faceva inviare al client una chiave di sessione cifrata con le chiavi RSA del server. SSH-2 separa le funzioni in un livello di trasporto, un livello di autenticazione e un livello di connessione (RFCs 4251 to 4254, gennaio 2006), usa un HMAC per l'integrità e deriva le chiavi di sessione con Diffie-Hellman. In questo modo, il traffico registrato resta riservato anche se la host key viene sottratta in seguito. SSH-1 è stato rimosso da OpenSSH in più fasi, fino alla versione 7.6 nell'ottobre 2017.

Perché OpenSSH ha sostituito l'implementazione SSH originale?

Lo sviluppo dell'originale è confluito in un prodotto commerciale con una licenza restrittiva e l'ultima release liberamente riutilizzabile era ssh 1.2.12. All'inizio del 1999 Björn Grönvall ha ripreso quella release creando OSSH. Il team OpenBSD ha poi derivato OpenSSH da OSSH, includendolo in OpenBSD 2.6 il 1 dicembre 1999. OpenBSD aveva bisogno di codice sottoposto ad audit e distribuito con una licenza senza restrizioni per il proprio sistema base. Queste due caratteristiche hanno permesso a tutti gli altri sistemi operativi di distribuire la stessa implementazione tramite il ramo portable.

Perché SSH chiede conferma della host key la prima volta che mi connetto?

Perché il client non ha mai visto prima quel server e non ha alcun valore con cui confrontare la sua chiave. La sola cifratura non consente di distinguere un server legittimo da una macchina che si trova nel mezzo del percorso. SSH identifica quindi i server tramite la chiave e registra ciò che ha rilevato in ~/.ssh/known_hosts. La prima connessione è l'unico momento in cui non esiste un valore memorizzato da verificare. Per questo il client chiede conferma a te. Confronta l'impronta con quella ottenuta dalla console del provider o direttamente dal server. Considera ogni successivo messaggio REMOTE HOST IDENTIFICATION HAS CHANGED un evento reale finché non riesci a spiegarlo.

Perché le vecchie chiavi SSH smettono di funzionare dopo un aggiornamento?

Perché OpenSSH dismette gli algoritmi secondo una pianificazione pubblicata. Le chiavi DSA (ssh-dss) sono state disabilitate per impostazione predefinita in OpenSSH 7.0 nel 2015 e rimosse completamente in OpenSSH 10.0 il 9 aprile 2025. Le chiavi RSA continuano a funzionare, ma le firme generate con SHA-1 sono state disabilitate per impostazione predefinita in OpenSSH 8.8 nel settembre 2021. Quando raggiungi un server obsoleto, questo problema viene visualizzato come sign_and_send_pubkey: no mutual signature supported. Una chiave Ed25519, disponibile da OpenSSH 6.5 nel gennaio 2014, evita entrambi i problemi.