Login SSH con GPG-AGENT
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]
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?SPossible 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?EPossible 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.