Connettersi al server via SSH: Windows, macOS e Linux

Pubblicato il 16 min di lettura

La prima connessione SSH passo dopo passo: PuTTY e OpenSSH su Windows, il terminale su macOS e Linux, come verificare davvero il fingerprint, trasferire file e risolvere i messaggi di errore più comuni.

Un server appena ordinato arriva senza monitor e senza tastiera. L'unica via d'accesso passa da SSH, il protocollo Secure Shell. Questo articolo ti accompagna nella prima connessione da tre sistemi operativi, spiega la richiesta di conferma del fingerprint (quella che quasi tutti i principianti chiudono senza leggere) e mostra come trasferire i file. Alla fine trovi la parte che quasi tutte le guide saltano: cosa fare quando non funziona e da cosa capisci che ha funzionato davvero.

Tutte le indicazioni sono verificate su Debian 13, Debian 12, Ubuntu 24.04 LTS e Ubuntu 22.04 LTS. Dove i quattro sistemi si comportano in modo diverso, lo trovi indicato esplicitamente. I comandi sul server girano come root. Sul tuo computer, invece, lavori con un normale account utente: per questo davanti a ogni comando che modifica il sistema trovi un sudo.

Che cosa ti serve prima della prima connessione

Bastano tre dati: l'indirizzo IP del server, il nome utente e la password oppure la chiave privata. Su KernelHost trovi IP e credenziali nell'area clienti subito dopo l'attivazione. Su un server root KVM o un server dedicato appena installato l'utente predefinito è quasi sempre root.

Come quarto dato c'è la porta. Quella predefinita è la 22. Ti serve un numero diverso solo se l'hai cambiata tu oppure se l'immagine di sistema la usa altrove. Tieni già a mente una trappola che più avanti ti farà risparmiare tempo: ssh vuole la porta in minuscolo (-p), scp la vuole in maiuscolo (-P).

Negli esempi compare sempre 203.0.113.10. Questo indirizzo è riservato ufficialmente alla documentazione e non esiste davvero. Sostituiscilo con l'IP del tuo server.

La prima connessione su Linux e macOS

Entrambi i sistemi includono già il client OpenSSH. Su macOS apri Terminale (nella cartella Utility), su Linux una qualsiasi finestra di terminale. Il comando è identico su tutti e due:

ssh root@203.0.113.10

Se SSH gira su un'altra porta:

ssh -p 2222 root@203.0.113.10

Se il tuo sistema non conosce ssh, cosa che capita con container molto snelli o installazioni minimali, verifichi e installi così:

ssh -V
sudo apt update
apt-cache policy openssh-client
sudo apt install -y openssh-client

L'ordine non è casuale. ssh -V serve a controllare, non a dimostrare che tutto funzioni: se la shell risponde bash: ssh: command not found, manca il pacchetto openssh-client e lo installi con sudo apt install -y openssh-client. sudo apt update va eseguito prima di apt-cache policy openssh-client, perché senza le liste dei pacchetti aggiornate quel comando non restituisce nulla oppure segnala solo Installed: (none). E quel sudo non è un ornamento: senza permessi di amministratore apt si interrompe con Could not open lock file /var/lib/apt/lists/lock.

ssh -V stampa la versione sullo standard error, non sullo standard output. Non è un errore, funziona così da sempre. Su Debian 13 vedi OpenSSH_10.0p2, su Debian 12 OpenSSH_9.2p1, su Ubuntu 24.04 OpenSSH_9.6p1 e su Ubuntu 22.04 OpenSSH_8.9p1. Questi numeri contano più avanti, perché il comportamento di scp è cambiato proprio tra queste versioni.

Il fingerprint, e perché non conviene ignorarlo

Al primissimo tentativo di connessione SSH chiede:

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

Che cosa sta succedendo: ogni server SSH genera durante la propria installazione una coppia di chiavi dedicata, il cosiddetto host key. Il fingerprint è un breve checksum della parte pubblica. Il tuo client non conosce ancora questo server e quindi non può garantire che dall'altra parte ci sia davvero il tuo server e non qualcuno che si è messo in mezzo.

Se digiti yes, il fingerprint viene salvato in ~/.ssh/known_hosts. Da quel momento il tuo client verifica in silenzio, a ogni connessione successiva, che il server presenti la stessa chiave. Quella singola domanda è quindi il momento in cui si costruisce l'intero modello di fiducia. Dopo non te lo chiede più nessuno.

Verificarlo davvero è possibile solo per una seconda via, indipendente. Su un server KVM la scelta naturale è la console nell'area clienti: lì accedi in locale, senza passare dalla rete, e ti fai stampare il fingerprint.

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

L'output è simile a questo:

256 SHA256:qWU2Zx9mF7hLtHkQ4gRXn0aVbC3sYpJ8dKe1TmNoPU root@server (ED25519)

Se la parte dopo SHA256: coincide con quella mostrata dal client, è tutto a posto. Se vuoi provare il formato senza rischi, generati in locale una chiave usa e getta:

ssh-keygen -t ed25519 -f /tmp/demo -N "" -C demo
ssh-keygen -lf /tmp/demo.pub

Due note dalla pratica. Primo: un server ha di solito più host key (ED25519, ECDSA, RSA). Quello mostrato è in genere la chiave ED25519, perché i client moderni la preferiscono. Se per sbaglio confronti con ssh_host_rsa_key.pub, non torna niente pur essendo tutto corretto. Secondo: StrictHostKeyChecking=no disattiva del tutto il controllo e non è una soluzione, è semplicemente la disattivazione della funzione di sicurezza. Se ti serve l'automazione, la scelta giusta è -o StrictHostKeyChecking=accept-new: accetta automaticamente i server sconosciuti, ma continua ad avvisarti quando qualcosa cambia.

Windows: il client OpenSSH integrato

Dalla versione 1809 di Windows 10 Microsoft include lo stesso client OpenSSH usato anche da Linux e macOS. Non ti serve quindi nessun programma aggiuntivo. Apri PowerShell, il prompt dei comandi o Windows Terminal e digita lo stesso comando visto sopra:

ssh root@203.0.113.10

Su Windows 10 e Windows 11 il client è un componente opzionale, già attivo nella maggior parte delle installazioni. Se non lo è, lo verifichi e lo installi da una PowerShell con permessi di amministratore:

Get-WindowsCapability -Online -Name OpenSSH.Client*
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

In alternativa da Impostazioni, Sistema, Funzionalità facoltative. I programmi si trovano poi in C:\Windows\System32\OpenSSH\, mentre la tua configurazione e gli host key conosciuti stanno in %USERPROFILE%\.ssh\, quindi tipicamente C:\Users\Name\.ssh\known_hosts.

La versione Windows è indietro rispetto a quella Linux. Sulle installazioni Windows 11 attuali ssh -V riporta di solito OpenSSH_for_Windows_9.5p2. Per l'uso quotidiano è più che sufficiente.

Una particolarità però c'è: i permessi sui file di Windows. Se salvi una chiave privata leggibile anche da altri account, SSH si rifiuta di procedere con Permissions for 'C:\Users\Name\.ssh\id_ed25519' are too open. Si sistema così:

icacls "$env:USERPROFILE\.ssh\id_ed25519" /inheritance:r /grant:r "$($env:USERNAME):(R)"

Windows: PuTTY

Per anni PuTTY è stato la via standard su Windows e per molti lo è rimasto. La versione attuale è la 0.84, di maggio 2026. Scaricala esclusivamente dal sito dell'autore (chiark.greenend.org.uk) e non da portali di download, perché in passato sono circolate più volte versioni contraffatte di PuTTY con furto di password integrato.

La procedura: in Host Name (or IP address) inserisci l'IP, in Port il 22, tipo di connessione SSH, poi Open. Se vuoi conservare la connessione, prima scrivi un nome in Saved Sessions e clicchi Save. Il nome utente PuTTY lo chiede solo nella finestra, oppure lo memorizzi in Connection, Data, Auto-login username.

Alla prima connessione compare la finestra PuTTY Security Alert, che segnala come l'host key non sia ancora memorizzato in cache. Mostra lo stesso fingerprint SHA256 che mostra anche OpenSSH, quindi puoi confrontare i due valori uno a uno. Accept salva la chiave in modo permanente, Connect Once si collega solo per questa volta senza salvare, Cancel annulla.

Differenza importante rispetto a OpenSSH: PuTTY non ha un file known_hosts. Le chiavi finiscono nel registro di sistema sotto HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys. Chi dopo una reinstallazione del proprio server vuole fare pulizia lì apre regedit e cancella la voce corrispondente. E poi c'è un'altra trappola: PuTTY usa un formato di chiave proprio (.ppk). Una chiave OpenSSH va convertita con PuTTYgen tramite Conversions, Import key prima che PuTTY possa usarla.

Trasferire file con scp e sftp

scp copia i file come cp, solo che lo fa attraverso la rete. Caricare un file:

scp backup.tar.gz root@203.0.113.10:/root/

Scaricare un file (il punto finale significa: nella directory corrente):

scp root@203.0.113.10:/var/log/syslog .

Un'intera directory, e con una porta diversa:

scp -r website root@203.0.113.10:/var/www/
scp -P 2222 backup.tar.gz root@203.0.113.10:/root/

sftp è la variante interattiva, comoda quando prima vuoi dare un'occhiata a dove si trovano le cose:

sftp root@203.0.113.10

Da lì lavori con ls, cd, get file, put file sul lato remoto e con lls, lcd sul tuo computer. bye chiude la sessione. Entrambi i programmi esistono anche su Windows, fanno parte della stessa installazione. PuTTY porta con sé i propri equivalenti, pscp e psftp; chi preferisce un'interfaccia grafica usa WinSCP.

Ed ecco la differenza su cui in molti inciampano: da OpenSSH 9.0 scp non trasferisce più internamente con il vecchio protocollo SCP, ma tramite SFTP. Riguarda Debian 13, Debian 12 e Ubuntu 24.04. Ubuntu 22.04 con OpenSSH 8.9 usa ancora il vecchio metodo. In pratica te ne accorgi in due punti. I caratteri jolly come *.log in un percorso remoto vengono interpretati in modo diverso e, se la controparte non offre SFTP (per esempio apparati di rete oppure un chroot limitato), il trasferimento si interrompe con:

subsystem request failed on channel 0
scp: Connection closed

Il rimedio d'emergenza è scp -O, che forza il vecchio protocollo. La soluzione pulita è attivare sul server la riga Subsystem sftp /usr/lib/openssh/sftp-server in /etc/ssh/sshd_config. Su Debian e Ubuntu il pacchetto necessario openssh-sftp-server viene installato come dipendenza di openssh-server, quindi manca solo in installazioni assemblate in modo davvero particolare.

L'avviso known_hosts dopo una reinstallazione

Reinstalli il server, ti colleghi e al posto del prompt compare un muro di punti esclamativi:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!      @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
Offending ED25519 key in /home/tom/.ssh/known_hosts:7
Host key for 203.0.113.10 has changed and you have requested strict checking.
Host key verification failed.

Non è un errore, è esattamente la funzione per cui la prima volta hai digitato yes. Con una reinstallazione il server genera nuovi host key e la voce salvata non corrisponde più. Lo stesso messaggio compare anche quando lo stesso indirizzo IP è stato assegnato a un altro cliente oppure quando hai avviato una copia del server.

Prima di cancellare la voce, fermati un attimo: hai davvero appena reinstallato? Se sì, rimuovi la vecchia riga:

ssh-keygen -R 203.0.113.10

Con una porta diversa la voce va scritta tra parentesi quadre, altrimenti il comando non trova nulla:

ssh-keygen -R "[203.0.113.10]:2222"

Se una voce esista o meno te lo dice ssh-keygen -F 203.0.113.10. Guardare con un editor di testo di solito serve a poco, perché Debian e Ubuntu salvano per impostazione predefinita i nomi host in known_hosts come hash. Lì dentro cercare non funziona, ed è per questo che servono i due comandi qui sopra.

Al tentativo di connessione successivo SSH chiede di nuovo il fingerprint. È il momento di verificarlo un'altra volta dalla console nell'area clienti, invece di digitare yes per riflesso. È proprio questa seconda occasione il senso di tutto l'avviso.

Su Windows ssh-keygen -R funziona allo stesso modo in PowerShell. Se usi PuTTY, cancelli invece la voce nel registro di sistema oppure, nella finestra WARNING - POTENTIAL SECURITY BREACH!, confermi con Accept che la nuova chiave va salvata.

I messaggi di errore alla lettera, e che cosa c'è dietro

I messaggi che seguono coprono, per esperienza, la grande maggioranza dei casi.

  • Connection refused: la connessione è arrivata fino al server, ma su quella porta non ascolta nessuno. O il servizio SSH non è in esecuzione, oppure ascolta su un'altra porta. Dalla console verifichi con systemctl status ssh e ss -tlnp se la porta 22 è occupata.
  • Connection timed out: non è arrivata nessuna risposta. Tipico di un IP sbagliato, di un server spento o di un firewall che scarta i pacchetti invece di rifiutarli. Controlla l'indirizzo IP carattere per carattere e le regole firewall.
  • Permission denied, please try again.: nome utente o password non sono corretti. La causa più frequente è l'utente sbagliato, per esempio root al posto di ubuntu o viceversa.
  • Permission denied (publickey).: il server non accetta affatto le password, ma solo le chiavi. In molte immagini cloud è l'impostazione predefinita. O carichi la tua chiave pubblica, oppure dalla console consenti temporaneamente PasswordAuthentication yes.
  • Too many authentication failures: il tuo agent propone troppe chiavi una dopo l'altra e il server interrompe prima. Rimedio: ssh -o IdentitiesOnly=yes -i ~/.ssh/mia_chiave root@203.0.113.10.
  • WARNING: UNPROTECTED PRIVATE KEY FILE! insieme a Permissions 0644 for ... are too open: la chiave privata è leggibile da altri e viene quindi ignorata. Su Linux e macOS risolvi con chmod 600 sul file della chiave, su Windows con il comando icacls visto più sopra.
  • Bad owner or permissions on ~/.ssh/config: stessa causa, ma per il file di configurazione. chmod 600 ~/.ssh/config.
  • kex_exchange_identification: read: Connection reset by peer: la connessione è stata interrotta a metà handshake. In pratica è quasi sempre un blocco automatico dopo diversi tentativi falliti, per esempio da parte di fail2ban. Aspetta che il blocco scada oppure rimuovilo dalla console con fail2ban-client unban INDIRIZZO_IP.
  • no matching host key type found. Their offer: ssh-rsa: il server offre solo chiavi RSA firmate con SHA-1. Da OpenSSH 8.8 vengono rifiutate, e come client la cosa riguarda tutti e quattro i sistemi trattati qui. La risposta corretta è aggiornare il vecchio server, non indebolire il client.
  • client_loop: send disconnect: Broken pipe: la sessione si è addormentata ed è stata ripulita da un firewall o da un router. Aggiungi in ~/.ssh/config la riga ServerAliveInterval 60, così la linea resta attiva.

Regola di base per ogni intervento sulla configurazione SSH: mentre provi, lascia aperta una sessione funzionante. Il riavvio del servizio SSH non butta fuori le connessioni già stabilite. Se ti chiudi fuori con una configurazione sbagliata, rientri proprio da quella seconda sessione oppure dalla console nell'area clienti.

Differenze tra Debian 13, Debian 12, Ubuntu 24.04 e 22.04

Per la sola apertura della connessione i quattro sistemi si comportano allo stesso modo. Appena modifichi qualcosa sul server, le strade si dividono.

Attivazione via socket al posto del servizio sempre attivo

Da 22.10 Ubuntu non avvia più il servizio SSH in modo permanente, ma solo alla prima connessione in entrata. Se ne occupa ssh.socket, non ssh.service. Vale per Ubuntu 24.04 e, sui sistemi installati da zero, anche per Debian 13. Debian 12 usa ancora il classico servizio sempre attivo.

Due conseguenze. Primo: lì un Port 2222 in /etc/ssh/sshd_config non cambia nulla, perché sulla porta non ascolta più sshd ma systemd. La porta va quindi in un file supplementare che crei con systemctl edit ssh.socket, con un ListenStream= vuoto per azzerare il valore predefinito e una seconda riga ListenStream=2222. Secondo: sui sistemi Debian 13 installati da zero systemctl reload ssh può interrompersi con fatal: Cannot bind any address. In quel caso usa systemctl restart ssh.service oppure disattiva del tutto l'attivazione via socket con systemctl disable --now ssh.socket.

Algoritmi ed eredità del passato

Debian 13 porta con sé OpenSSH 10.0 e non conosce più affatto le chiavi DSA, nemmeno tramite opzioni di compatibilità. Chi usa ancora una chiave molto vecchia se ne genera prima una nuova. I client più recenti (macOS 26.3 e successivi con OpenSSH 10.1 o superiore) mostrano inoltre un avviso quando il server non offre uno scambio di chiavi resistente ai computer quantistici:

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

È un avviso, non un errore: la connessione si stabilisce comunque. Sparisce non appena il server è abbastanza recente. Debian 12 e Ubuntu 24.04 soddisfano il requisito, Ubuntu 22.04 con OpenSSH 8.9 nella configurazione predefinita no.

Due parole sulle versioni più vecchie

Debian 10 è senza supporto da giugno 2024, Ubuntu 20.04 da maggio 2025. Nessuno dei due riceve più aggiornamenti di sicurezza per OpenSSH. Un server raggiungibile via SSH da internet non dovrebbe più girare su queste versioni.

Digitare meno con ~/.ssh/config

Appena gestisci più di un server, il file di configurazione ripaga la fatica. Crealo e imposta i permessi, altrimenti SSH lo rifiuta:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/config
chmod 600 ~/.ssh/config

Una voce al suo interno è fatta così:

Host web1
    HostName 203.0.113.10
    User root
    Port 2222
    ServerAliveInterval 60

Da quel momento basta ssh web1, e funziona anche scp file web1:/root/. Lo stesso file lo capisce anche il client Windows, dove si trova in %USERPROFILE%\.ssh\config.

Non devi tirare a indovinare se il tuo blocco viene davvero applicato. ssh -G mostra la configurazione finale senza aprire nessuna connessione:

ssh -G localhost

Sostituisci localhost con il tuo nome breve e nelle righe hostname, user e port leggi nero su bianco che cosa userà SSH tra un istante. Un errore di battitura nel nome Host salta fuori così in due secondi, invece che dopo venti minuti di ricerca.

Come capisci che ha funzionato davvero

Un prompt che compare non è ancora una prova. Con più finestre aperte è già capitato a molti di lanciare un rm sul server sbagliato. Quattro comandi brevi fanno chiarezza:

hostname
id
cat /etc/os-release
uptime

hostname deve mostrare il nome del tuo server, non quello del tuo portatile. id mostra uid=0(root) quando lavori come root. cat /etc/os-release indica distribuzione e versione, quindi per esempio Debian GNU/Linux 13 (trixie) oppure Ubuntu 24.04.3 LTS. E uptime restituisce un valore coerente con un server, non con un computer da scrivania che ogni sera viene spento.

Il test più rapido per capire se sei davvero collegato via SSH e non seduto in un terminale locale:

echo $SSH_CONNECTION

Se compare una riga con quattro valori (il tuo IP, la tua porta di origine, l'IP del server, la porta di destinazione), sei collegato. Se resta vuota, stai digitando sul tuo computer. La sessione si chiude con exit oppure con la combinazione di tasti Ctrl e D.

Come proseguire

Il passo successivo sensato è il passaggio dalle password alle chiavi. Una chiave SSH non si indovina e, una volta configurata, puoi disattivare del tutto l'accesso con password, mandando a vuoto la maggior parte dei tentativi di attacco automatizzati. Come si fa lo trovi in Configurare l'autenticazione con chiave SSH. Poi arrivano firewall e blocco automatico, descritti in Mettere in sicurezza il server dopo l'installazione.

Per iniziare vale questo: quando sei entrato una volta, hai verificato il fingerprint e sai come rientrare dopo una reinstallazione, la parte più difficile è fatta. Tutto il resto succede in una finestra che ora puoi aprire.

Domande frequenti

Come mi collego via SSH da Windows senza installare PuTTY?
Windows 10 dalla versione 1809 e Windows 11 includono lo stesso client OpenSSH usato da Linux e macOS. Apri PowerShell o Windows Terminal e digita ssh root@INDIRIZZO-IP. Se il comando manca, lo installi da una PowerShell con permessi di amministratore tramite Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 oppure da Impostazioni, Sistema, Funzionalità facoltative.
Che cosa significa la richiesta del fingerprint alla prima connessione?
SSH non conosce ancora il server e non può garantire che dall'altra parte ci sia davvero il tuo server. Il fingerprint è un checksum della chiave del server. Se confermi con yes, viene salvato in ~/.ssh/known_hosts e da lì in poi verificato automaticamente a ogni connessione successiva. Puoi controllarlo dalla console nell'area clienti con ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub.
Dopo la reinstallazione SSH segnala REMOTE HOST IDENTIFICATION HAS CHANGED. Che cosa faccio?
Con una reinstallazione il server genera nuovi host key e la voce salvata non corrisponde più. Rimuovila con ssh-keygen -R INDIRIZZO-IP, oppure con ssh-keygen -R "[INDIRIZZO-IP]:2222" se la porta è diversa. Al tentativo successivo SSH chiede di nuovo il fingerprint, che confronti con l'output della console del server. PuTTY invece salva gli host key nel registro di sistema sotto HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys.
Perché funzionano scp -P e ssh -p, ma non il contrario?
È una particolarità storica di OpenSSH: ssh vuole la porta come -p minuscolo, scp come -P maiuscolo, perché scp usa già il -p minuscolo per conservare timestamp e permessi. Se scambi i due, scp segnala un'opzione sconosciuta oppure prova a collegarsi sulla porta 22.
scp si interrompe con subsystem request failed on channel 0. Da che cosa dipende?
Da OpenSSH 9.0 scp trasferisce internamente tramite SFTP invece che con il vecchio protocollo SCP. Riguarda Debian 13, Debian 12 e Ubuntu 24.04, mentre Ubuntu 22.04 con OpenSSH 8.9 usa ancora il vecchio metodo. Se la controparte non offre SFTP, nell'immediato aiuta scp -O, in modo definitivo la riga Subsystem attiva in /etc/ssh/sshd_config.
Perché la modifica della porta in sshd_config non ha effetto su Ubuntu 24.04?
Da 22.10 Ubuntu avvia SSH tramite attivazione via socket, e lo stesso vale per i sistemi Debian 13 installati da zero. Sulla porta ascolta systemd, non sshd, quindi la voce in sshd_config viene ignorata. La porta va in un file supplementare che crei con systemctl edit ssh.socket: una riga vuota ListenStream= per azzerare il valore predefinito, sotto ListenStream=2222. Debian 12 usa ancora il servizio classico, lì basta sshd_config.
Come capisco di essere finito davvero sul server giusto?
Verifica con hostname il nome del server, con id l'account utente, con cat /etc/os-release la distribuzione e con uptime il tempo di attività. Se sei davvero collegato via SSH e non stai digitando in un terminale locale te lo dice echo $SSH_CONNECTION: se compaiono quattro valori, la sessione è una vera connessione SSH.

SSH Linux Windows macOS Debian Ubuntu PuTTY scp sftp Amministrazione server