Created on 29 May 2013 ;    Modified on 29 Sep 2016

Usare chiavi pubbliche/private per l'autenticazione della console

Ad un sistemista capita spesso di utilizzare la console per dare comandi ad una macchina remota.

E, in qualche caso, questa necessità riguarda anche programmi che devono lanciare comandi su altri sistemi.

Nell'ambito dei sistemi Unix like (Linux, Solaris, ...) una delle console più usate è sicuramente il client ssh. Che lavora superbamente verso server che gestiscono connessioni remote con il protocollo openssh.

Per connettersi utilizzando ssh, si usa la classica coppia utenza + password.

Ma può essere molto utile e produttivo istruire il server cui ci colleghiamo ad accettare automaticamente richieste di collegamento dal client normalmente utilizzato (si noti bene: è una macchina ben precisa: se vorremo collegarci da un altro PC, dovremo rispolverare l'autenticazione classica utenza + pasword).

Per fare questo, il processo è abbastanza semplice. Concettualmente dobbiamo:

In pratica (in CentOS, ma gli altri sistemi Linux sono simili), nel client Linux da cui ci colleghiamo:

$ ssh-keygen -t rsa   # genera due file: ~/.ssh/id_rsa (ch.privata) e  ~/.ssh/id_rsa.pub (ch.pubblica). <CR> per non aver passphrase
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_rsa
$ restorecon -Rv ~/.ssh  # se selinux è attivo e in enforcing mode

Dopo di che, nel server Linux a cui ci colleghiamo, copiamo il file id_rsa_pub e lo aggiungiamo alle chiavi autorizzate:

$ cat id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
$ restorecon -Rv ~/.ssh  # se selinux attivo e in enforcing mode

Attenzione al fatto che nei precedenti comandi riteniamo esistente la directory ~/.ssh.

Per provare il collegamento, nel computer da cui ci colleghiamo:

$ ssh root@computer_a_cui_ci_colleghiamo

se è tutto ok, questo deve effettuare il collegamento senza ulteriori richieste.

Problemi?

Se il comando

$ ssh root@computer_a_cui_ci_colleghiamo

non effettua il collegamento, capire perché può essere complicato. Vediamo alcuni possibili motivi.

Prima di tutto controllare i permessi delle directory ~/.ssh e del file ~/.ssh/autorized_keys. Il protocollo ssh è stato pensato per rendere più sicuri il collegamento tra computer, rispetto protocolli più attaccabili, quali Telnet. Quindi il client ssh e il servizio sshd sono piuttosto paranoici riguardo i permessi dei file che maneggiano. Se un file è troppo pubblico lo ignorano. Di solito avvertono, ma non sempre questo succede. Un controllo di ~/.ssh ci deve dare:

# ls -al
<...cut...>
drwx------.  2 root root  4096 Jun 26 14:59 .ssh
<...cut...>

mentre il controllo di ~/.ssh/autorized_keys ci dà:

# ls -al .ssh/authorized_keys
-rw-------. 1 root root 1064 Jun 26 14:57 .ssh/authorized_keys

Se così non fosse, reimpostare i permessi.

Se abbiamo SELinux in funzione, è importante il comando restorecon, in caso contrario sshd potrebbe non accedere alle directoy e file predetti.

Ancora un suggerimento. In un paio di casi, mi è capitato di sudare per debuggare una situazione di ssh con chiavi rsa non funzionante, per scoprire che il file ~/.ssh/autorized_keys non aveva la chiave corretta.
Come mai? Perché la penultima chiave aggiunta nel file ~/.ssh/autorized_keys non aveva il new line impostato. Di conseguenza, appendendo una ulteriroe chiave, si allungava la chiave precedente, senza registrarne una nuova.
Risultato: la penultima chiave continuava a funzionare. L'ultima non veniva riconosciuta.
Ergo: prima di aggiungere una chiave in ~/.ssh/autorized_keys, contate il n.ro di righe:

# wc -l  `~/.ssh/autorized_keys`

e dopo avere aggiunto la nuova chiave, contate nuovamente le righe. Ce ne deve essere una in più.

Se tutto questo non funziona, o se siete curiosi e volete vedere cosa accare durante un collegamento con protocollo ssh, potete lanciare il client utilizzando l'opzione di debug -v (verbose):

$ ssh -v root@computer_a_cui_ci_colleghiamo

l'opzione -v può anche essere -vv o -vvv, aumentando via via il livello di debug.

Anche il servizio sshd ha una opzione di debug. Cerchiamo di evitarla, soprattuto se il server non è a portata di mano. Se proprio la dobbiamo utilizzare non chiudiamo per nessun motivo la sessione di lavoro. Se lo facessimo, molto probabilmente ci troveremo tagliati fuori dal sistema cui ci dobbiamo collegare.

Per vedere sshd al lavoro in debug mode, chiudiamo il servizio e lo facciamo ripartire in foreground con l'opzione di debug:

$ service sshd stop
$  /usr/sbin/sshd -d

in questa modalità sshd accetterà un solo collegamento (o mancato collegamento), terminando con esso1. Inoltre i messaggi di debug sono visualizzati a console.

Se proprio vogliamo far lavorare sshd in debug mode, è meno pericoloso attivare la scrittura dei messaggi di debug nei file di log. In tal caso modificare il file /etc/ssh/sshd_config mettendo LogLevel a DEBUG, DEBUG2, o DEBUG3. I relativi log di solito sono in /var/log/auth/*. Naturalmente sarà necessario riavviare il servizio:

$ service sshd restart

Riferimenti


  1. Ecco perché non dobbiamo chiudere il collegamento al server. Con questa modalità sshd termina e non riparte più.