Rischi dell'agent forwarding SSH e cosa usare al suo posto

Con ssh -A il tuo agent resta sul tuo computer, ma l'host remoto riceve un socket che parla con lui. Root su quell'host può usare il socket per accedere ovunque funzionino le tue chiavi, finché resti connesso. La chiave in sé non viene copiata. Usa invece ssh -J per passare da un jump host.

Aggiornata il . Provato con OpenSSH 10.3 su macOS e un ssh-agent di prova separato contro OpenSSH 10.0 su Debian 13.

Cosa fa -A

Senza inoltro, le tue chiavi non servono più una volta che sei su un server, quindi un secondo salto da lì non può usarle. ssh -A risolve il problema collegando l'host remoto al tuo agent:

ssh -A user@server
echo "$SSH_AUTH_SOCK"
/tmp/ssh-G63yAM532X/agent.1441

Quel percorso è un socket Unix sul server. Tutto ciò che gli viene inviato torna all'agent sul tuo computer, che firma quanto richiesto e restituisce il risultato. Il server non riceve mai la chiave privata.

La posizione dipende dalla versione del server. Su OpenSSH 10.0 abbiamo visto /tmp/ssh-XXXXXXXXXX/agent.<pid>. La versione 10.1 ha spostato i socket dell'agent in ~/.ssh/agent/.

Per caricare prima le chiavi in un agent locale, vedi ssh-agent e il portachiavi di macOS.

Cosa può fare root sull'host remoto

I permessi dei file proteggono il socket dagli altri utenti normali, e root ignora quei permessi. L'abbiamo provato su un server mentre un utente era connesso con -A. Come root:

# find /tmp -type s -name 'agent.*'
/tmp/ssh-G63yAM532X/agent.1441

# SSH_AUTH_SOCK=/tmp/ssh-G63yAM532X/agent.1441 ssh-add -l
256 SHA256:IikDwOZxEooOrmm+d3MXJXlobc7rwEyUrQNIBXHzXaU key (ED25519)

# SSH_AUTH_SOCK=/tmp/ssh-G63yAM532X/agent.1441 ssh user@203.0.113.11 id -un
user

Quindi root ha usato la chiave per accedere a un'altra macchina, senza alcuna richiesta sul lato dell'utente. Ecco il quadro completo:

  • Può: usare ogni chiave nel tuo agent, per accedere a qualsiasi server o servizio che le accetta, compreso un account su un servizio di hosting del codice. Può anche elencare le tue chiavi pubbliche e rimuovere chiavi dal tuo agent: ssh-add -D eseguito sul server ha svuotato il nostro agent locale.
  • Non può: copiare la chiave privata. L'agent non la consegna. Un socket rubato smette di funzionare quando la tua sessione finisce, e abbiamo verificato che in quel momento il socket sparisce.
  • Un altro utente normale è stato rifiutato: Error connecting to agent: Permission denied.

"Root" qui comprende chiunque sia entrato nel server e abbia ottenuto root. Un accesso fatto mentre sei connesso può piazzare una propria chiave sulla destinazione e mantenere l'accesso ben dopo che te ne sei andato. Per questo la breve vita del socket rassicura meno di quanto sembri.

L'alternativa: ProxyJump

Molte persone usano l'inoltro per passare da un bastion. Con -J il tuo computer apre una connessione cifrata attraverso il jump host fino al server finale, e le chiavi vengono usate solo dal tuo computer:

ssh -J user@bastion user@server

Oppure in ~/.ssh/config:

Host server
    HostName 10.0.0.5
    ProxyJump user@bastion

Nella nostra prova la connessione ha funzionato, $SSH_AUTH_SOCK era vuoto sulla destinazione e sul jump host non esisteva alcun socket dell'agent. Un bastion compromesso non ha nulla da usare. Vedi ProxyJump e jump host.

Se l'inoltro ti serve davvero

Un caso tipico è eseguire git pull su un server con le tue credenziali personali. Prima chiediti se basterebbe una deploy key per quel solo repository, tenuta sul server. Se l'inoltro ti serve comunque, riduci ciò che espone.

Chiedi conferma a ogni uso: ssh-add -c

ssh-add -c ~/.ssh/id_ed25519

Ora il tuo agent chiede conferma sul tuo schermo ogni volta che la chiave viene usata, così una richiesta inattesa si nota. Se rifiuti, il login fallisce:

sign_and_send_pubkey: signing failed for ED25519 "key" from agent: agent refused operation

Serve un programma ssh-askpass sul tuo computer, che potresti dover installare. Su macOS non ne abbiamo trovato nessuno di serie. Senza, prova prima di farci affidamento.

Esponi meno chiavi

  • Avvia un agent separato che contiene solo la chiave che ti serve, e inoltra quello con ForwardAgent /path/to/agent.sock nel blocco dell'host.
  • Limita per quanto tempo le chiavi restano caricate con ssh-add -t 1h ~/.ssh/id_ed25519.
  • Usa una chiave che apre solo ciò che serve a questo lavoro, e non la tua chiave principale.
  • Guarda i vincoli di destinazione, ssh-add -h, che limitano dove una chiave può essere usata.

Inoltra solo verso host con nome

Host build-box
    ForwardAgent yes

Non impostare mai ForwardAgent yes sotto Host *. È disattivato per impostazione predefinita, e giustamente. Un solo ssh distratto verso un server di cui non ti fidi del tutto consegnerebbe a quel server il tuo agent per la durata della sessione.

Quando è accettabile

È un compromesso ragionevole quando valgono tutte queste condizioni: ti fidi di chiunque abbia root su quell'host e ritieni che l'host non sia compromesso; la sessione è breve; e non potresti fare il lavoro con -J o con una deploy key. Evitalo sui server condivisi, sugli host esposti a internet gestiti da altri, e su qualsiasi cosa a cui non lasceresti il tuo portatile sbloccato.

Disattivarlo su un server

AllowAgentForwarding no

Con questa riga in sshd_config, ssh -A nella nostra prova si è connesso normalmente ma non è comparso alcun socket. Il manuale avverte che gli utenti con accesso alla shell possono comunque configurare propri inoltri, quindi consideralo un'impostazione predefinita che previene gli incidenti, non una barriera rigida.

Domande

L'agent forwarding SSH è sicuro?

Solo su server dove ti fidi di chiunque abbia root. Mentre sei connesso, root può usare le tue chiavi per entrare altrove a nome tuo. Non può copiare la chiave privata.

Che differenza c'è tra ssh -A e ssh -J?

-A permette all'host remoto di usare il tuo agent. -J passa attraverso un jump host fino alla destinazione, e le chiavi si usano solo dal tuo computer: il jump host non ha nulla da sfruttare.

Come disattivo l'agent forwarding su un server?

Metti AllowAgentForwarding no in sshd_config e ricarica sshd. Chi ha una shell può comunque crearsi un inoltro proprio, quindi è un'impostazione contro gli incidenti, non una barriera.

Fonti

Altro in Mettere in sicurezza un server

Tutte le guide