par Benjamin | Fév 15, 2022 | Blog, Sécurité
Sommaire
Utiliser une Nitrokey Pro 2 comme clé SSH
Configurer GPG comme Agent SSH
Configurer gpg-agent pour ne pas demander le code PIN
Configurer ses crons pour utiliser l’agent GPG qui tourne
Chez Octopuce, nous effectuons nos sauvegardes depuis des baies de backup qui se connectent via SSH pour récupérer les données de tous les serveurs que nous hébergeons. Afin de garantir une bonne sécurité à ces machines critiques, nous avons décidé d’utiliser des clés Nitrokey Pro 2 pour stocker de manière sûre les paires de clé RSA permettant la connexion à tous nos serveurs.
La Nitrokey Pro 2 gère le standard OpenPGP, mais pas SSH. Cependant, il stocke des clés RSA et peut donc signer des demandes de sessions SSH avec la même paire de clé, à l’aide de l’agent GNUPG 2.
Pour configurer ces clés Nitrokey, c’est donc un petit peu plus compliqué que de juste faire
$ ssh-keygen -t rsa -b 3072
Cet article va vous guider sur l’utilisation d’une telle clé pour vos sauvegardes automatisées (donc sans demander le code PIN à l’utilisation de la clé)
On va d’abord changer le code PIN et le code Administrateur de la clé Nitrokey, puis la configurer pour que ses clés générées soient des RSA de 3072 bits. Plus sûr que les 2048 bits sans pour autant nécessiter trop de temps pour générer une signature si nous utilisions des clés de 4096 bits, nous avons fait ce choix intermédiaire.
Tout d’abord on installe sur notre Debian Bullseye les outils requis :
# apt install scdaemon libpam-systemd gnupg2
(SCDAemon est le SmartCard Daemon, un service système qui permet de gérer les cartes de ce type et leur lien avec GnuPG. LibPam-SystemD permet de s’assurer que l’on disposera d’un dossier /run spécifique à chaque utilisateur, ce qui permet de cloisonner les sockets de GPG-Agent. GnuPG2 est la dernière version du logiciel de gestion de clés OpenPGP.)
Ensuite, on lance gpg pour changer le code PIN et le code Administrateur : (en gras les commandes saisies)
$ gpg --change-pin
gpg: carte OpenPGP nº D27600012401030400050000AC490000 détectée
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Quel est votre choix ? 1
Entrez le code PIN par défaut (123456) puis 2 fois un nouveau code PIN (8 chiffres idéalement, conservez le au coffre)
Ensuite on change le code d’administration (qui permet de changer le code PIN si on le perd (pareil, à conserver au coffre)
PIN changed.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Quel est votre choix ? 3
PIN changed.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Quel est votre choix ? Q
$
Ensuite on lance gpg pour configurer la carte : (en gras les commandes saisies) Il vous demandera le code Administrateur à chaque changement de paramètre (3 fois). Si vous préférez utiliser une clé ECC, choisissez 2 lors de key-attr.
$ gpg --edit-card
Reader ...........: Nitrokey Nitrokey Pro (00000000000000000000AC49) 00 00
Application ID ...: D27600012401030400050000AC490000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: ZeitControl
Serial number ....: 0000AC49
Name of cardholder: [non positionné]
Language prefs ...: fr
Salutation .......:
URL of public key : [non positionné]
Login data .......: [non positionné]
Signature PIN ....: forcé
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 64 64 64
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
gpg/carte> admin
Les commandes d'administration sont permises
gpg/carte> key-attr
Changing card key attribute for: Signature key
Sélectionnez le type de clef désiré :
(1) RSA
(2) ECC
Quel est votre choix ? 1
Quelle taille de clef désirez-vous ? (2048) 3072
La carte sera maintenant reconfigurée pour générer une clef de 3072 bits
Changing card key attribute for: Encryption key
Sélectionnez le type de clef désiré :
(1) RSA
(2) ECC
Quel est votre choix ? 1
Quelle taille de clef désirez-vous ? (2048) 3072
La carte sera maintenant reconfigurée pour générer une clef de 3072 bits
Changing card key attribute for: Authentication key
Sélectionnez le type de clef désiré :
(1) RSA
(2) ECC
Quel est votre choix ? 1
Quelle taille de clef désirez-vous ? (2048) 3072
La carte sera maintenant reconfigurée pour générer une clef de 3072 bits
Étape suivante : générer les paires de clés RSA OpenPGP permettant de signer / chiffrer des messages. Pour cela on procède ainsi (il va vous demander le code Administrateur puis le code PIN) :
$ gpg --edit-card
Reader ...........: Nitrokey Nitrokey Pro (00000000000000000000AC49) 00 00
Application ID ...: D27600012401030400050000AC490000
...
Key attributes ...: rsa3072 rsa3072 rsa3072
...
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
gpg/carte> admin
Les commandes d'administration sont permises
gpg/carte> generate
Faut-il faire une sauvegarde hors carte de la clef de chiffrement ? (O/n) n
Veuillez noter que les configurations d'usine des codes personnels sont
code personnel = « 123456 » code personnel d'admin. = « 12345678 ».
Vous devriez les modifier avec la commande --change-pin
Veuillez indiquer le temps pendant lequel cette clef devrait être valable.
0 = la clef n'expire pas
<n> = la clef expire dans n jours
<n>w = la clef expire dans n semaines
<n>m = la clef expire dans n mois
<n>y = la clef expire dans n ans
Pendant combien de temps la clef est-elle valable ? (0) 0
La clef n'expire pas du tout
Est-ce correct ? (o/N) o
GnuPG doit construire une identité pour identifier la clef.
Nom réel :
Adresse électronique :
Commentaire : Octopuce BCK1
Vous avez sélectionné cette identité :
« (Octopuce BCK1) »
Changer le (N)om, le (C)ommentaire, l'(A)dresse électronique
ou (O)ui/(Q)uitter ? o
gpg: clef 0xC016D20D12B43E72 marquée de confiance ultime.
gpg: revocation certificate stored as '/home/benjamin/.gnupg/openpgp-revocs.d/04ECB2618BCF661DD5A839D1C016D20D12B43E72.rev'
les clefs publique et secrète ont été créées et signées.
gpg/carte> quit
pub rsa3072/0xC016D20D12B43E72 2022-02-15 [SC]
04ECB2618BCF661DD5A839D1C016D20D12B43E72
uid (Octopuce BCK1)
sub rsa3072/0x4BBE5BF7A0327063 2022-02-15 [A]
sub rsa3072/0x99AE0B5A3FA5CAB5 2022-02-15 [E]
À partir de maintenant on dispose de la capacité de chiffrer ou signer des messages via OpenPGP en utilisant cette carte. L’ID de clé a été affiché à la fin de la procédure (le 0xC016D…)
Pour exporter cette clé au format SSH, on procède ainsi :
$ gpg2 --export-ssh-key 0x04ECB2618BCF661DD5A839D1C016D20D12B43E72
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCtdsQQswOdxb8CqKIZMy9lyDBNdasDc+vqP7CkgZE73uDNwmJkF173VmBD3C5R0LdO3tMOnm6zV1WmipkQpDIRbbSRPDqe1rCDAVcfryGap1x7gmH7N26tLH04qB9zjFCypOFJsLQCiapJ8cS5p/SGqShl6oDSJ1f6+RCt7bhF6ImtdE9eaHfPZZhNpW5TB5SSLLUngX7BGgOYDVknElnVv3LaZLKLJ8twPu/lEcMZd6I4q3+VIoe8zi45y7WT12SBJHHmKAeiOpSTAYdPgi/8YX5woZ/h5Y9+7WfcHllKYPuRnnE0KOAQXBlHsLHhvfUIbdqO3d1pZo6Z/+YxUy4OGQ2eAZ7sm8bqYHEBjTJ+fyq78mlaPfPuJVkwQGEbRKPyjq5yLfjMbI256C+UXIYjtzKb9doL83D9x83jRBADCzpTaGDdHwFMc9Zcj55aC7e45ENNBlnx2poS96rDGmmPDaN/L6dRicu15/N9iAXPZpMJDKArCKS4QLSpr8HYJ1M= openpgp:0xA0327063
C’est cette clé RSA 3072 au format SSH que l’on pourra autoriser sur nos serveurs, dans le fichier ~/.ssh/authorized_keys
Comme nous souhaitons utiliser ces clés Nitrokey Pro 2 comme source de sécurité pour nos agents SSH, nous devont utiliser l’agent SSH de gpg-agent :
Tout d’abord, on configure l’agent gpg-agent pour qu’il fasse aussi agent ssh : (typiquement ces commandes seraient saisies sur le serveur de backup) et on teste qu’il marche bien :
$ echo "enable-ssh-support" >>~/.gnupg/gpg-agent.conf
$ gpg-agent
gpg-agent[148469]: gpg-agent running and available
# on dit à l'agent qu'il faut parler sur le TTY courant (pour nous demander le code PIN) :
$ gpg-connect-agent updatestartuptty /bye
$ export SSH_AUTH_SOCK=/run/user/0/gnupg/S.gpg-agent.ssh
$ ssh-add -L # doit afficher l'empreinte RSA 3072 de la clé
# Ensuite mettre la clé sur une machine distante, dans ~/.ssh/authorized_keys et s'y connecter :
$ ssh -v remote-server
# cela doit demander le code pin et afficher ensuite :
debug1: Offering public key: cardno:00050000AC49 RSA SHA256:xNLVQrzbpzX+yJmDLHQ765yb9zIaf+JgdHXLXCYTXVA agent
debug1: Server accepts key: cardno:00050000AC49 RSA SHA256:xNLVQrzbpzX+yJmDLHQ765yb9zIaf+JgdHXLXCYTXVA agent
debug1: Authentication succeeded (publickey).
Note: ces étapes ne sont pas nécessaires si vous souhaitez utiliser votre clé Nitrokey sur un poste de travail. Elle ne servent que pour une utilisation « sans présence humaine » des clés.
L’avant dernière étape consiste à dire à gpg-agent que l’on ne souhaite pas avoir à saisir le code PIN pour pouvoir utiliser la clé : cela nécessite en effet de pouvoir lancer nos sauvegardes sans la présence d’un humain pour saisir le code PIN !
Pour cela, on va demander à GPG-Agent, via la commande gpg-connect-agent, de se souvenir « en RAM » du code PIN de la carte.
Notez que cela doit donc être fait à chaque démarrage du serveur de sauvegarde. (et remplacez 123456 par votre code PIN bien entendu, et le D27blabla000 par le numéro de série de votre carte Nitrokey, voir plus haut la commande gpg –edit-card)
$ gpg-connect-agent
> OPTION pinentry-mode=loopback
> /definqfile PASSPHRASE 123456
> SCD CHECKPIN D27600012401030400050000AC490000
> /bye
$
Dernière étape : il faut modifier nos tâches planifiées de sauvegarde pour qu’elle utilisent l’agent GPG (en fait un agent SSH) qui tourne comme source de signature pour l’identification sur les serveurs distants.
pour cela, on ajoute la variable d’environnement suivante aux crontab :
SSH_AUTH_SOCK=/run/user/0/gnupg/S.gpg-agent.ssh
Ainsi, SSH utilisera l’agent GPG, qui en RAM a le code PIN pour accéder à la carte Nitrokey Pro 2 et demander la signature de session de connexion SSH, dont les clés privées resteront à l’intérieur de la clé, et donc non exfiltrables.