Login SSH con GPG-AGENT

From Carini MediaWiki
Revision as of 15:08, 21 October 2022 by Alessandro (talk | contribs) (Revisione iniziale (provata su openSUSE Leap 15.3))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Introduzione

Effettuare il login in una sessione SSH attraverso una coppia di chiavi, invece che tramite password, presenta alcuni vantaggi, primo fra tutti il fatto di essere immuni ad attacchi di password guessing e a vulnerabilità dovute all'uso di password deboli (potete approfondire l'argomento partendo da questa discussione su StackExchange)

Il metodo più diffuso è quello di mantenere la propria chiave privata nella directory ~/.ssh della workstation (propria è stato evidenziato per il motivo che scambiarsi le chiavi private all'interno dell'azienda o del gruppo di lavoro è una pessima idea) e distribuire la corrispondente chiave pubblica sui sistemi dove dovremo operare (manpage)

Questo metodo di lavoro comporta alcuni inconvenienti: Se il file con la chiave privata viene lasciato senza password (cosa assolutamente sconsigliabile) saremo esposti al rischio di furto della chiave privata, se teniamo il file chiave protetto saremo costretti a ridigitare la password ogni volta che eseguiamo un login

Una delle possibili alternative è quella di non avere la propria chiave privata sul disco ma di utilizzare un keyring GPG come repository e configurare gpg-agent per chiedere la password una sola volta (o poche volte per ogni sessione di lavoro), vediamo quindi come fare (gpg e gpg-agent sono presenti come pacchetto precompilato in tutte le principali distribuzioni Linux)

Aggiungiamo alla nostra chiave PGP una chiave RSA valida per l'autenticazione

Diamo per scontato che avete già la vostra chiave PGP e una sub-key

Per poter usare la nostra chiave PGP come chiave di login SSH occorre avere una sub-key con la capability Autentication che PGP, con le impostazioni di default, non crea.

Molto probabilmente le vostra chiave è simile a questa (Le lettere S,C e E fra parentesi quadre sono le capabilities di ogni chiave)

#> gpg --list-key 0000000000000000000000000000000000000000
pub   rsa4096 2019-12-01 [SC] [expires: 2025-01-31]
      0000000000000000000000000000000000000000
uid           [ultimate] Nome Cognome (Commento)
uid           [ultimate] Nome Cognome (Commento2)
sub   rsa2048 2019-12-01 [E] [expires: 2025-01-31]
Capabilities
Tag Capability
E Encrypt
S Sign
C Certify
A Authentication

Come prima cosa quindi creiamo una sub-key appropriata; ci serve una sub-key con capability Authentication che otteremo rimuovendo le capabilities S ed E e aggiungendo la capability A:

#> gpg --expert --edit-key 0000000000000000000000000000000000000000
gpg (GnuPG) 2.2.5; Copyright (C) 2018 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa4096/0000000000000000
     created: 2019-12-01  expires: 2025-01-31  usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/0000000000000000
     created: 2019-12-01  expires: 2025-01-31  usage: E   
[ultimate] (1). Nome Cognome (Commento) 
[ultimate] (2)  Nome Cognome (Commento2) 

gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Sign Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? S

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? E

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? A

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? Q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)enter per il default
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 20250131T235900
Key expires at Fri 31 Jan 2025 11:59:00 PM UTC
Is this correct? (y/N) y
Really create? (y/N) y

Se abbiamo fatto tutto correttamente otterremo un'ulteriore sub-key con la capability A:

#> gpg --list-key 0000000000000000000000000000000000000000
pub   rsa4096 2019-12-01 [SC] [expires: 2025-01-31]
      0000000000000000000000000000000000000000
uid           [ultimate] Nome Cognome (Commento) mail1@dominio
uid           [ultimate] Nome Cognome (Commento2) mail2@dominio
sub   rsa2048 2019-12-01 [E] [expires: 2025-01-31]
sub   rsa2048 2019-12-01 [A] [expires: 2025-01-31]

Prendiamo il keygrip e configuriamo il gpg-agent

Teoricamente, avere il keygrip potrebbe essere inutile se avete una sola sub-key con la capability A. In realtà al momento in cui la vostra chiave si approssimerà alla scadenza e voi genererete un'altra chiave ci sarà comunque un periodo in cui vi troverete a gestire più chiavi contemporaneamente ... perché voi avete generato una chiave CON una scadenza, VERO?

#> gpg --fingerprint --keyid-format SHORT --with-keygrip --list-key 0000000000000000000000000000000000000000
pub   rsa4096/AAAAAAAA 2019-12-01 [SC] [expires: 2025-01-31]
      Key fingerprint = xxxx xxxx xxxx xxxx xxxx  xxxx xxxx xxxx xxxx xxxx
      Keygrip = 1111111111111111111111111111111111111111
uid         [ultimate] Nome Cognome (Commento) mail1@dominio
uid         [ultimate] Nome Cognome (Commento2) mail2@dominio
sub   rsa2048/BBBBBBBB 2019-12-01 [E] [expires: 2025-01-31]
      Keygrip = 2222222222222222222222222222222222222222
sub   rsa2048/CCCCCCCC 2019-12-01 [A] [expires: 2025-01-31]
      Keygrip = 3333333333333333333333333333333333333333

Per configurare il gpg-agent faremo qualche modifica rispetto alla pur ottima guida di Brian "bex" Exelbierd:

File ~/.gnupg/gpg-agent.conf:

# Enable SSH support
enable-ssh-support
# GPG password expires after 4h, or 30 minutes idling
max-cache-ttl 14400
default-cache-ttl 1800
# SSH password expires after 4 hrs, or 15 minutes idling
max-cache-ttl-ssh 14400
default-cache-ttl-ssh 900

File ~/.gnupg/sshcontrol:

# sub   rsa2048/CCCCCCCC 2019-12-01 [A] [expires: 2025-01-31]
3333333333333333333333333333333333333333

Configuriamo lo startup di gpg-agent ad inizio sessione

Quasi tutti i manuali consigliano di modificare il ~/.bashrc locale. In realtà è meglio creare una configurazione globale

File /etc/profile.d/gpg-agent.sh:

#
# Start gpg-agent if configuration file is present
#

if test -f $HOME/.gnupg/gpg-agent.conf ; then
    # export GPG_TTY=$(tty)
    export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    gpgconf --launch gpg-agent
    gpg-connect-agent updatestartuptty /bye >/dev/null
fi

per eseguireChe lo startup dell'agent per tutti gli utenti che lo hanno configurato.

Se abbiamo fatto tutto correttamente, loggandoci sulla sessione di un utente con il gpg-agent configurato vedremo qualcosa del genere:

#> echo "SSH_AUTH_SOCK=${SSH_AUTH_SOCK} GPG_TTY=${GPG_TTY}"
SSH_AUTH_SOCK=/run/user/1001/gnupg/S.gpg-agent.ssh GPG_TTY=/dev/pts/0

#> ps -lF -C gpg-agent
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN    RSS PSR STIME TTY          TIME CMD
1 S $my-user  2082     1  0  80   0 - 41901 core_s   712   3 

Esportiamo la chiave pubblica

Per esportare la chiave pubblica con la capability A del nostro keyring basta usare

#> gpg --export-ssh-key 0xCCCCCCCC
ssh-rsa  AAA [...] chiave pubblica [...] BPjdKh openpgp:0xCCCCCCCC

(dove 0xCCCCCCCC è l'id della sub-key). La chiave la copieremo poi nel file ~/.ssh/authorized_keys del sistema target.

Usiamo le nostre chiavi

Se è andato tutto bene dovremmo essere in grado di eseguire il login con ssh user@host, la password del nostro keyring ci sarà chiesta solo la prima volta sino alla scadenza dei TTL impostati sopra.