🔐

SSH

Connessioni remote sicure, tunnel, chiavi, config. Tutto quello che ti serve per lavorare su server remoti senza impazzire.

Ultimo aggiornamento: 2026-03-28

0 Comandi
0 Sezioni
0 Quiz
Comandi Essenziali base
base
ssh user@hostname

Connessione base a un server remoto. Se l'utente locale e quello remoto coincidono, basta ssh hostname.

Esempio:
$ ssh steven@178.104.35.42
steven@178.104.35.42's password:
Last login: Fri Mar 27 14:30:00 2026
steven@deltoide:~$
base
ssh -p 2222 user@hostname

Connessione su porta non standard. Molti server spostano SSH dalla porta 22 per ridurre il rumore degli scanner automatici.

Esempio:
$ ssh -p 2222 deploy@staging.example.com
deploy@staging:~$
base
ssh-keygen -t ed25519 -C "commento"

Genera una coppia di chiavi. ed25519 e il tipo consigliato: piu sicuro e veloce di RSA. Il commento -C serve per identificarla (tipicamente la tua email).

Esempio:
$ ssh-keygen -t ed25519 -C "steven@stevetech.it"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/steven/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Your identification has been saved in /home/steven/.ssh/id_ed25519
Your public key has been saved in /home/steven/.ssh/id_ed25519.pub
Tip: Usa sempre una passphrase. Se qualcuno ti ruba la chiave privata, la passphrase e l'ultima difesa.
base
ssh-copy-id user@hostname

Copia la tua chiave pubblica sul server e la aggiunge a ~/.ssh/authorized_keys. Dopo non ti chiede piu la password.

Esempio:
$ ssh-copy-id steven@178.104.35.42
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed
steven@178.104.35.42's password:
Number of key(s) added: 1

$ ssh steven@178.104.35.42   # niente password!
base
scp file.txt user@host:/path/

Copia file via SSH. Funziona come cp ma tra macchine diverse. Usa -r per cartelle intere. La direzione si inverte: scp user@host:/remote/file ./local/.

Esempio:
# Upload: locale → server
$ scp deploy.sh steven@deltoide:/home/steven/scripts/

# Download: server → locale
$ scp steven@deltoide:/var/log/nginx/error.log ./

# Cartella intera
$ scp -r ./my-project/ steven@deltoide:/home/steven/
base
ssh user@host "comando"

Esegui un comando sul server senza aprire una sessione interattiva. Perfetto per check veloci o script.

Esempio:
$ ssh steven@deltoide "df -h / && uptime"
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        75G  5.8G   69G   8% /
 19:30:00 up 42 days,  3:15,  1 user,  load average: 0.08, 0.03, 0.01
Comandi Intermedi intermedio
intermedio
~/.ssh/config

Il file config ti salva la vita: definisci alias, porte, chiavi e opzioni per ogni server. Invece di ssh -p 2222 -i ~/.ssh/key_staging user@staging.lungo.dominio.com scrivi ssh staging.

~/.ssh/config
Host deltoide
    HostName 178.104.35.42
    User steven
    IdentityFile ~/.ssh/id_ed25519

Host staging
    HostName staging.example.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_staging

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes
Tip: Il blocco Host * in fondo si applica a tutte le connessioni. ServerAliveInterval 60 manda un keepalive ogni 60 secondi ed evita che la connessione cada per inattivita.
intermedio
ssh -L 5432:localhost:5432 user@host

Local port forwarding: rendi accessibile un servizio remoto sulla tua macchina locale. Qui il PostgreSQL del server diventa raggiungibile su localhost:5432 del tuo Mac.

Esempio:
# Accedi al Postgres del server dal tuo Mac
$ ssh -L 5432:localhost:5432 steven@deltoide

# In un altro terminale, connettiti come se fosse locale
$ psql -h localhost -U myuser mydb

# Con -N e -f: solo tunnel, senza shell, in background
$ ssh -N -f -L 5432:localhost:5432 steven@deltoide
intermedio
ssh -A user@host

Inoltra il tuo SSH agent al server remoto. Utile quando dal server devi fare git pull con la tua chiave GitHub senza copiare chiavi private in giro.

Esempio:
# Dal tuo Mac
$ ssh-add ~/.ssh/id_ed25519     # aggiungi chiave all'agent
$ ssh -A steven@deltoide        # connessione con forwarding

# Sul server, la tua chiave e disponibile
steven@deltoide:~$ git pull     # usa la TUA chiave GitHub
Attenzione: Non usare -A su server di cui non ti fidi. Chi ha root su quel server puo usare il tuo agent per autenticarsi come te.
intermedio
ssh -J bastion user@internal-host

Connessione via jump host (bastion). Raggiungi server interni passando da un gateway pubblico, senza fare due SSH manuali.

Esempio:
# Diretto
$ ssh -J admin@bastion.example.com deploy@10.0.1.50

# Nella config, ancora meglio:
Host internal-db
    HostName 10.0.1.50
    User deploy
    ProxyJump bastion.example.com

$ ssh internal-db   # fatto
intermedio
rsync -avz ./local/ user@host:/remote/

Come scp ma intelligente: trasferisce solo i file cambiati. -a preserva permessi, -v verbose, -z comprime. Molto meglio di scp per cartelle grandi.

Esempio:
# Sync locale → remoto (deploy)
$ rsync -avz --exclude '.git' ./my-app/ steven@deltoide:/var/www/my-app/

# Sync remoto → locale (backup)
$ rsync -avz steven@deltoide:/home/steven/brain/ ./backup-brain/

# Dry run: vedi cosa farebbe senza fare nulla
$ rsync -avzn ./my-app/ steven@deltoide:/var/www/my-app/
Tip: Il trailing slash / conta! ./src/ copia il contenuto di src. ./src (senza slash) copia la cartella stessa.
intermedio
ssh-add ~/.ssh/id_ed25519

Aggiunge una chiave privata all'SSH agent, cosi non devi inserire la passphrase a ogni connessione. ssh-add -l per vedere le chiavi caricate.

Esempio:
# Aggiungi chiave (chiede la passphrase una volta sola)
$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/steven/.ssh/id_ed25519:
Identity added: /home/steven/.ssh/id_ed25519 (steven@stevetech.it)

# Lista chiavi caricate
$ ssh-add -l
256 SHA256:abc123... steven@stevetech.it (ED25519)

# Rimuovi tutte le chiavi dall'agent
$ ssh-add -D
Comandi Avanzati avanzato
avanzato
ssh -R 8080:localhost:3000 user@host

Reverse tunnel: esponi un servizio che gira sulla tua macchina locale attraverso il server remoto. Chi visita host:8080 finisce sul tuo localhost:3000. Tipo ngrok ma gratis.

Esempio:
# Stai sviluppando un'app su localhost:3000
# La vuoi mostrare a un cliente

$ ssh -R 8080:localhost:3000 steven@deltoide

# Ora http://178.104.35.42:8080 mostra la tua app locale
# Con -N: solo tunnel, senza shell
$ ssh -N -R 8080:localhost:3000 steven@deltoide
Attenzione: Il server deve avere GatewayPorts yes in /etc/ssh/sshd_config per accettare connessioni esterne sul tunnel. Altrimenti il tunnel e raggiungibile solo da localhost del server.
avanzato
ssh -D 1080 user@host

Crea un proxy SOCKS5 locale. Configura il browser per usare localhost:1080 come proxy e tutto il traffico passa attraverso il server. VPN dei poveri.

Esempio:
# Apri il tunnel SOCKS
$ ssh -D 1080 -N -f steven@deltoide

# Testa con curl
$ curl --socks5 localhost:1080 https://ifconfig.me
178.104.35.42   # IP del server, non il tuo

# Nel browser: Settings → Proxy → SOCKS5 → localhost:1080
avanzato
ControlMaster auto

Riusa una singola connessione SSH per piu sessioni. La seconda connessione allo stesso host e istantanea (zero handshake). Da mettere in ~/.ssh/config.

~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

# Crea la cartella per i socket
$ mkdir -p ~/.ssh/sockets

# Prima connessione: handshake normale
$ ssh deltoide         # ~1 secondo

# Seconda connessione: istantanea
$ ssh deltoide         # ~0.05 secondi
avanzato
/etc/ssh/sshd_config

Configurazione del server SSH. Le prime cose da fare su un server nuovo: disabilita login root e autenticazione via password.

Impostazioni consigliate:
# /etc/ssh/sshd_config

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
X11Forwarding no

# Dopo le modifiche:
$ sudo systemctl reload sshd
Attenzione: Prima di disabilitare PasswordAuthentication, assicurati che la tua chiave pubblica sia in authorized_keys e funzioni. Altrimenti ti chiudi fuori dal server.
avanzato
~.

Escape sequences SSH. Quando la connessione si blocca (freeze, lag infinito), premi Enter poi ~. per uccidere la sessione. Funziona SEMPRE, anche quando Ctrl+C non fa nulla.

Sequenze utili:
# Sessione bloccata? Premi Enter, poi:
~.      # Chiudi la connessione (kill)
~?      # Lista tutte le escape sequences
~#      # Lista connessioni forwarded
~C      # Apri command line SSH (per aggiungere tunnel al volo)
~~      # Scrivi letteralmente un ~
Tip: La sequenza ~. deve essere preceduta da Enter (newline). Se non funziona, prova Enter Enter ~.
Combinazioni e Workflow pratico
pratico
Deploy via rsync + restart

Pattern classico per deploy manuali: sync dei file e riavvio del servizio in un colpo solo.

Script di deploy:
#!/bin/bash
# deploy.sh - sync e restart in un comando
SERVER="steven@deltoide"
REMOTE="/var/www/my-app"

rsync -avz --exclude '.git' --exclude 'node_modules' \
  ./src/ $SERVER:$REMOTE/

ssh $SERVER "cd $REMOTE && npm install --production && sudo systemctl restart my-app"

echo "Deploy completato"
pratico
SSH multi-hop + tunnel

Raggiungi un database interno passando da un bastion, con tunnel per la porta. Tutto in una riga.

Esempio reale:
# Accedi al Postgres di un server interno via bastion
$ ssh -J admin@bastion.example.com \
    -L 5432:localhost:5432 \
    deploy@10.0.1.50

# Oppure in ~/.ssh/config:
Host prod-db
    HostName 10.0.1.50
    User deploy
    ProxyJump bastion.example.com
    LocalForward 5432 localhost:5432

# Poi basta:
$ ssh prod-db
$ psql -h localhost -U app mydb   # nel secondo terminale
pratico
Backup remoto via SSH

Backup incrementale da remoto con rsync, perfetto da mettere in crontab.

Esempio:
# Backup incrementale giornaliero
$ rsync -avz --delete \
    steven@deltoide:/home/steven/brain/ \
    /backups/brain-$(date +%Y%m%d)/

# Tar compresso via SSH (stream diretto, zero spazio temporaneo)
$ ssh steven@deltoide "tar czf - /home/steven/brain/" \
    > backup-brain-$(date +%Y%m%d).tar.gz

# In crontab (ogni notte alle 3):
0 3 * * * rsync -az steven@deltoide:/home/steven/brain/ /backups/brain/
Troubleshooting debug
debug
ssh -vvv user@host

Massimo livello di debug. Mostra ogni step dell'handshake: risoluzione DNS, negoziazione algoritmi, tentativi di autenticazione. Il 90% dei problemi SSH si diagnostica qui.

Cosa cercare nell'output:
$ ssh -vvv steven@deltoide 2>&1 | head -30

# Cose da guardare:
debug1: Connecting to deltoide port 22.       # connessione OK?
debug1: Connection established.                # handshake partito?
debug1: Offering public key: ~/.ssh/id_ed25519 # sta provando la chiave giusta?
debug1: Authentication succeeded (publickey).  # autenticazione OK?

# Se vedi "Permission denied (publickey)":
# → la chiave non e in authorized_keys del server
# → permessi sbagliati su ~/.ssh/ (devono essere 700)
# → permessi sbagliati su authorized_keys (deve essere 600)
debug
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*

Il problema piu comune: permessi sbagliati. SSH rifiuta di usare chiavi se la cartella o i file sono leggibili da altri. Fix universale.

Permessi corretti:
# Fix permessi (fallo sia su client che su server)
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_ed25519        # chiave privata
$ chmod 644 ~/.ssh/id_ed25519.pub    # chiave pubblica
$ chmod 600 ~/.ssh/authorized_keys   # chiavi autorizzate
$ chmod 600 ~/.ssh/config            # config

# Verifica
$ ls -la ~/.ssh/
drwx------  2 steven steven 4096 Mar 28 19:00 .
-rw-------  1 steven steven  411 Mar 28 19:00 id_ed25519
-rw-r--r--  1 steven steven   97 Mar 28 19:00 id_ed25519.pub
-rw-------  1 steven steven  220 Mar 28 19:00 authorized_keys
debug
ssh-keygen -R hostname

Quando vedi "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED" — significa che il fingerprint del server e cambiato. Succede dopo una reinstallazione o cambio IP. Rimuovi la vecchia entry.

Esempio:
# Rimuovi la vecchia fingerprint
$ ssh-keygen -R 178.104.35.42
# Host 178.104.35.42 found: line 15
/home/steven/.ssh/known_hosts updated.

# Riprova la connessione (accetta il nuovo fingerprint)
$ ssh steven@178.104.35.42
The authenticity of host '178.104.35.42' can't be established.
ED25519 key fingerprint is SHA256:abc123...
Are you sure you want to continue connecting (yes/no)? yes
Attenzione: Se non hai reinstallato il server e vedi questo warning, potrebbe essere un attacco man-in-the-middle. Verifica prima di accettare il nuovo fingerprint.

Quiz — Verifica le tue conoscenze

1. Quale tipo di chiave e consigliato generare oggi?

2. Quale flag crea un tunnel locale (local port forwarding)?

3. Quali permessi deve avere la cartella ~/.ssh/?

4. Come chiudi una sessione SSH bloccata?

5. Cosa fa ssh-copy-id?

6. Quale flag usi per connettere via jump host (bastion)?

7. Cosa fa ssh -D 1080?

8. Perche rsync e meglio di scp per cartelle grandi?

Punteggio: 0/0