Table des matières
2023/03/12 (maintenance ispng)
Heure de début : 10h
Présences :
- HgO
- Tharyrok
- Célo
- Channel
Météo
Moment informel durant lequel on exprime en peu de mots comment on se sent et si on a une attente forte pour la réunion. Ce n'est pas un moment de discussion mais d'expression individuelle et ce n'est pas obligatoire
Attente(s) forte(s)
Si l'une ou l'autre personne exprime une attente forte, merci de vous en occuper en priorité ou de la noter dans le hub ou dans un point approprié.
STOP midi apres PKI.
PKI · IGC · ICP
C'est quoiiiii ?
PKI : Public Key Infrastructure Gérer des certificats avec un CA.
On parle de PKI ou ICP (Infrastructure à Clé Publique) ou IGC (Infrastructure de Gestion de Clé). C'est soit un logiciel soit un matériel qui permet de gérer le cycle de vie d'un certificat. C'est-à-dire sa création, sa mise à jour, sa révocation…
A partir de ça il y a plein de techniques. On a des techniques avec des certificats cross-signés : il faut 2 certificats ou plus pour signer un autre certificat. Ca peut se matérialiser par plusieurs cartes à puces qu'on met dans un HSM (Hardware Security Module) qui permettent de signer un nouveau certificat.
Le CA : Certificat Authority, c'est juste un certificat particulier qui a comme seul rôle de signer d'autres certificats. On verra que c'est des flags qu'on met dans la génération des certificats qui peuvent désigner le rôle duu certificat. On a par ex. le rôle serveur, le rôle client, etc.
easy-rsa
https://easy-rsa.readthedocs.io/en/latest/
L'outil qu'on va utiliser est easy-rsa. Il est déjà utilisé dans la VM actuelle d'ISPng (vpn).
Mais on va travailler sur une autre VM, et on ne va pas l'utiliser de la même manière que sur la VM vpn. Easy-rsa est un ensemble de scripts qui permettent la gestion d'une PKI.
C'est un vieil outil, mais qui est toujours maintenu et mis à jour. Il est beaucoup utilisé pour générer des certificats.
CA
Pour avoir des infos sur un certificat dans un format lisible par les humain·e·s (par exemple ici le certificat du site de Neutrinet) :
- snippet.bash
openssl x509 -in neutrinet-be.pem -noout -text
Pour récupérer depuis un site web, il y aussi une commande pour ça :
- snippet.bash
echo | openssl s_client -connect neutrinet.be:443 | openssl x509 -noout -text
Lorsqu'on affiche un certificat dans ce format, on trouve dans “X509v3 extensions” des informations sur l'usage du CA. Ici, on a par exemple :
509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication
Si on lance la commande openssl sur le CA, le plus important c'est le sujet. On voit que le certificat est auto-signé. L'issuer va se retrouver dans la signature du certificat de neutrinet.be.
On peut observer que le certificat racine (root CA) signe le sous-CA qui lui-même signe le certificat de Neutrinet. Dans le certificat de Neutrinet on retrouve le hash du certificat signé par le sous-ca. Dans la signature se trouve le hash de la clé publique de Neutrinet, le issuer, le suject.
Par exemple, le Root CA de Let's encrypt est cross-signé par celui de Digital Trust, qui est beaucoup plus ancien. Cela permet au CA de Let's encrypt d'être reconnu par les anciens navigateurs. Voir : https://letsencrypt.org/certificates/
Cependant, c'est assez casse gueule à mettre en place, et on va préférer des sub CA, plus simple à gérer.
Sub CA
On va générer un CA en courbe élliptique (c'est un type d'algorithme). On va le générer pour une vingtaine d'années. Il va nous servir pour les différents sous-CA. Et chaque sous-CA aura un usage particulier. Du coup les sous-CA auront une durée de 5 ans ce qui nous permettra de renouveler tous les 2 ans. Le but c'est de ne pas oublier la procédure car si on le fait tout les 10 ans c'est un réapprentissage a chaque fois (et compliqué de retrouver les gens qui l'ont fait).
À terme, on aimerait avoir une durée de 2.5 et le renouveler tous les ans lors de l'AG.
La sous-CA pour le VPN serait en RSA pour garder la compatibilité. Cela ne pose pas de problème d'avoir le certificat racine en élliptique, même si c'est contre-intuitif.
On met ouuuu ?
On va générer des certificat. Mais on les mets où ?
On pourrait les mettre dans un repo git (public mais risqué, ou privé). Dans le password store, le problème c'est qu'il faut mettre tout le dossier easy-rsa.
Le risque, si quelqu'un s'en empare, c'est de pouvoir générer des certificats au nom de Neutrinet. L'attaquant pourrait aussi déchiffrer le trafic du VPN et faire un MitM (Man in the Middle) sans trop de difficulté.
La question c'est aussi de savoir en combien de temps on serait capable de regénérer le certificat en cas de compromission ? Et est-ce qu'on serait capable de détecter cela ?
La vraie bonne place, ce serait dans un HSM, ce qui coûte une centaine d'euros (frais de port compris). Mais ce serait mieux d'en avoir deux.
Ce qui va déterminer si on prend un HSM ou pas, c'est l'algorithme qu'on va utiliser.
Un HSM, cela se présente comme une petite clé usb, comme une Yubikey.
Une autre solution encore, c'est deux clés USB (chiffrées avec cryptsetup mais des clés normales), avec le mot de passe.
http://point-at-infinity.org/ssss/
C'est une technique pour avoir un secret partagé, chaqu'un a une partie du secret et on sait faire en sorte que si 5 personnes ont le secret, on sait le reveler a partir de 2 personnes.
Au moment du renouvellement, on devra amener les deux clés.
On pourrait avoir 4 clés, 2 utilisées, 2 qui seraient un backup, mais qui seraient aussi utilisées pour renouveler le certitificat et devenir le nouveau certificat.
On pourrait aussi avoir des clés où on ne peut que écrire et pas lire, mais là ça devient un peu trop brain fuck.
Ca se fait avec les HSM : on peut le dire de renouveler le certificat mais sans jamais fournir la clé privée. Celle-ci a été écrite 1 fois dans le HSM et n'est jamais réaffichée après. On se contente de dire au HSM de renouveler.
Avec les 4 clés, on pourrait dire qu'on fait le renouvellement en AG, tous les deux ans. (On peut même le faire chaque année ou chaque semaine si on veut mais pas obligé, on doit juste générer le certificat avant la moitié du temps de la fin du certificat (genre 5 ans, ça donne 2 ans et demi)).
Avoir 4 clés, cela demande surtout une bonne organisation lors de l'AG, car il faut penser à amener toutes les clés.
Que faire si lors d'une des AG, une des deux clés ne peut être amenée car la personne n'est pas venue (injoignable, etc.) ? D'où l'importance de l'avoir dans un lieu avec plusieurs humain·es. On propose une au Caldarium et une à la Maison de la Paix, car plusieurs d'entre-nous y ont accès facilement.
La backup, c'est pas pour les mettre encore ailleurs, mais au cas où une clé casse, etc.
Il faudra déjà mettre les fichiers sur une clé temporairement en attendant d'avoir les autres… On peut aussi déjà générer un mot de passe pour les différentes personnes du CA.
Il faut réfléchir à combien de personnes seraient impliquées, à quand c'est représentatif. Mais il faut aussi être sûr de pouvoir renouveler si certaines personnes sont absentes. Actuellement, pour les docs administratifs, le hub admin est en train de se dire qu'il faut deux personnes.
Ca pose aussi d'autres questions : À partir de combien de personnes qui quittent Neutrinet faudra-t-il changer les mots de passe ? Parce qui si on dit « il faut deux personnes pour déchiffrer la clé », alors dès que deux personnes quitte le CA on a une faille de sécurité, car potentiellement elles pourraient prendre le contrôle du certificat racine.
On peut aussi se poser la question : est-ce qu'à ce moment-là c'est important d'impliquer le CA ?
On pourrait dire trois personnes. On peut partir là-dessus et voir à l'usage. C'est quelque chose qu'on peut revoir par la suite, puisqu'on renouvelle tous les 2 ans.
Est-ce que secret serait gardé par les membres du CA ou par les membres du hub-infra ? Sachant qu'aujourd'hui tous les membres du hub infra actif sont dans le CA.
Il faut aussi tenir compte qu'à l'heure actuelle, le certificat racine est sur la machine du VPN, donc pas du tout sécurisé. Avoir juste une clé non-chiffrée, hors-ligne, serait déjà un grand pas en avant.
C'est vraiment la question du modèle de menace qui se pose :
- Stockage : sur un repo git vs sur une clé usb (hors-ligne)
- Chiffrement :
- repo git chiffré vs juste privé
- clé usb chiffrée vs en clair
- Partage du secret : secret unique dans le password store vs secret partagé avec 3 personnes
À noter que pour le chiffrement, on peut choisir de juste chiffrer la clé privée du CA. Cela revient un peu à avoir un secret unique dans le password store (même si techniquement c'est plus simple).
On décide de faire un tour de table :
- Stockage → clé usb:
- Impression que toutes les options sont valables au final. Avec la clé usb on se réapproprie symboliquement la technique, car on arriverait avec cette clé usb à l'AG. Mais en même temps, il n'y a pas forcément un intérêt particulier d'un point de vue technique.
- Il y a le coté symbolique, on pourrait apporter les clés sur un petit coussin. Ou dresser Channel pour apporter la Clé. Il y a un petit cérémoniale un peu sectaire. Cependant, le stockage hors ligne reste intéressant techniquement pour avoir une sécurité hors ligne. Même si c'est pas une Yubikey ou un HSM, ça rejoint l'idée. C'est interessant à tester.
- Si on devait appliquer la règle du KISS, avoir le CA sur un repo git et la clé privée dans le password store, cela serait suffisant en terme de modèle de menace. Sauf que dans le hub infra, on a plutôt une démarche de faire les choses proprement (aka se casser la tête). Donc on aime l'idée d'impliquer le plus de personnes possibles dans Neutrinet pour sensibiliser sur la gestion d'un PKI. Ce serait plus une visée éducative que pour la sécurité.
- Miaaaaw ! (traduction : Clé USB !)
- Chiffrement sur la clé USB → chiffrement sur la clé:
- Comme on a parlé de mettre la clé dans un lieu commun (pas forcément public mais avec du passage), ça semble important de la chiffrer. Mais question : est-ce qu'on chiffre la clé ou le CA ? Comme on est hors ligne, ça a moins d'impact. Ca pose plus la question du point suivant : secret partagé ou pas. Ce serait juste un point technique, parce que dans tous les cas on chiffre : soit la clé usb, soit le CA
- En fait, la différence entre la clé et le CA, c'est que chiffrer la clé fait qu'on chiffre aussi tous les sous-ca et les configs. Du coup, c'est intéressant de chiffrer la clé car on peut aussi mettre des tours de manivelles (en gros dire combien de fois on rejoue l'algorithme).
- Maow !! èwé
- Pas grand chose à rajouter, c'est vrai que si on chiffre la clé cela a des avantages techniques.
- Partage du secret :
- De manière KISS, on mettrait le mot de passe dans le password store. Cela laisse la responsabilité au hub infra. Si on est dans l'angle éducation, c'est intéressant de faire un secret partagé à chaque usage. On montre physiquement qu'on a besoin de plusieurs humains pour partager un secret.
- Il y a une attirance sur le côté éducation et du coup sur le partage de secret. Il faut aussi etre vigilent de ne pas mettre une solution trop contraignante. Garder en tête la praticité.
- C'est flou pour l'instant. Les deux sont possibles. Soit on a quelque chose de simple, qu'on connait bien. Soit on se complique plus la vie, mais on teste aussi une autre manière de gérer les mots de passes. C'est éducatif pour d'autres membres de Neutrinet mais aussi aute-éducatif pour nous. Mais clé USB chifffrée avec un mot de passe, c'est déjà un gros pas, et techniquement c'est plus que suffisant. Mais le secret partagé répond à la question des éventuels conflits qui pourraient survenir dans Neutrinet, c'est le gros avantage que je vois. Mais ce n'est pas un argument qui me ferait pencher en faveur du secret partagé.
- lapp' lapp'
Il y a une crainte de vouloir faire un truc trop compliqué, mais en même temps on a tous envie de tester le secret partagé.
On peut tester et voir dans 2 ans si c'est trop compliqué.
Dans crypt-setup, on peut définir deux manière de déverouiller un setup. Donc on pourrait permettre de déverouiller entre plusieurs personnes et en même temps avoir, en backup, un mot de passe dans le password store. Cela permet de ne pas se retrouver bloqué car on aurait le “backup” du mot de passe dans le password store.
On mettrait en avant le côté éducatif, mais si on n'y arrive pas, ce n'est pas bloquant. Et on est clairs sur le fait que c'est un outil éducatif, pas un besoin en termes de sécurité.
TODO: Commander 4 clés USB → Tharyrok
Génération du CA
On branche une clé USB qu'on va utiliser pour aujourd'hui en attendant les autres.
On crée une partition non chiffrée que l'on formatte en exfat, pour avoir le truc le plus rétrocompatible possible:
mkfs.exfat /dev/sda1
On a une clé qu'on peut monter.
On crée un README.md avec toutes les instructions pour déchiffrer la clé usb, càd pour monter la partition chiffrée.
On va utiliser qemu pour créer un disque virtuel:
- snippet.bash
qemu-img create -f qcow2 neutrinet.qcow2 1G
Cela permettra de copier ce disque virtuel sur tous les supports que l'on veut.
Dans le readme, on note les commandes qu'il faut :
- snippet.bash
sudo modprobe nbd max_part=16
nbd est un driver qui permet de monter des images comme si c'était un vrai disque.
sudo qemu-nbd --connect=/dev/nbd0 -f qcow2 neutrinet.qcow2
permet de dire qu'on monte l'image neutrinet dans le nbd0. On sait que c'est le nbd0 car il n'y a pas d'autre disque monté.
A priori il n'y a pas moyen de savoir la liste des nbd présents.
Après s'être connecté au nbd, on peut aussi voir le nbd monté en faisant un lsblk –fs.
L'avantage du format qcow2, c'est qu'il n'utilise que l'espace disque réellement utilisé. C'est le même principe utilisé sur les VMs dans Proxmox avec l'option discard.
Après ça, on chiffre le disque virtuel avec cryptsetup:
sudo cryptsetup --type luks2 --cipher aes-xts-plain64 --hash sha512 --iter-time 50000 --key-size 512 --pbkdf argon2id --use-urandom --verify-passphrase luksFormat /dev/nbd0
Détails de la commande : https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#Encryption_options_with_dm-crypt
(Cette commande est tapée depuis la clé USB.)
pbkdf : détermine l'alorithme utilisé pour générer son mot de passe. Avec argon2id, on peut définir le temps entre chaque itération.
On va lui demander de faire 50 000 itérations (ce sont les tours de manivelles dont on parlait). C'est pas l'entropie, c'est le temps qu'il va prendre pour chaque itération. Plus itertime est gros, plus cela prend du temps pour déverouiller la clé. Cela évite les brute force.
On va avoir besoin de générer un mot de passe fort de 64 caractères avec des caractères spéciaux. On le fait depuis gopass.
- snippet.bash
gopass generate -s
On va lui donner le nom alpha, comme ça on le distinguera d'un second jeu de clé beta. Le premier jeu servira pour le premier certificat N et le second pour certificat N-1, qu'on utilisera pour le renouvellement et qui deviendra le certificat N par la suite. Là on a tout généré et tout mis dans le password store de Neutrinet.
Quand on exécute la commande, cela demande si on veut bien écraser ndb0 et le long mot de passe qu'on a généré.
La commande qui chiffre le disque prend du temps, c'est normal.
Maintenant, on peut faire (qui prend également du temps) :
sudo cryptsetup open /dev/nbd0 usb-crypt-alpha
Pour la première fois, on va faire plutôt :
sudo cryptsetup open --perf-no_write_workqueue --perf-no_read_workqueue --allow-discards --persistent /dev/nbd0 usb-crypt-alpha
On désactive les performances (perf-nowriteworkeue et perf-noreadworkqueue) car ce ne sont pas des disques plateaux. Ce n'est à faire qu'une seule car ensuite les options sont gardées en mémoire par ce brave cryptsetup. En fait, cryptsetup va sauvegarder tout ça dans les métadonnées du disque, donc la prochaine fois qu'on voudra l'ouvrir cela se fera automagiquement.
Maintenant que c'est ouvert, si on fait un petit lsblk –fs, on voit que le volume est monté.
On va formatter ce volume, l'important est d'avoir un système de fichier qui supporte le discard (fstrim). On n'est pas sûr que ext2 supporte le discard par contre…
sudo mkfs.ext2 /dev/mapper/usb-crypt-alpha
Et cela supporte bien le discard, on le sait en utilisant lsblk -D qui permet de montrer le discard. Quand toutes les colonnes sont à 0, c'est pas compatible. Si des colonnes sont remplies, c'est compatible. Le discard, c'est ce qui premet que le fichier ne prenne pas toute la place allouée.
On va monter le volume :
sudo mkdir /mnt/usb-crypt-alpha sudo mount /dev/mapper/usb-crypt-alpha /mnt/usb-crypt-alpha
En dernier, on forcera le disque à faire un discard:
fstrim /mnt/usb-crypt-alpha
On se rend dans le volume qu'on a monté. On va générer les certificats en root car c'est un utilisateur qu'on trouvera sur tous les linux. En terme de sécurité, c'est moins bien, mais mieux en termes d'accessibilité.
On va également faire un umask spécifique, ce qui permet de dire au terminal qu'à partir de maintenant tous les fichiers créés vont avoir comme permission lecture / écriture par root et personne d'autre.
sudo -i umask 0077
Cela marche comme pour un masque réseau : on fait la différence (XOR) pour savoir ce que sera la permission en sortie. Donc ici, le XOR entre 0077 et 7777 donne bien 7700.
Pour la suite, on doit posséder le paquet easy-rsa.
On va créer plusieurs PKI : un CA racine, et un sous CA spécifique pour les VPN. Plus tard, on pourra aussi en générer pour les autres serveurs de Neutrinet. On parle de plusieurs PKI car on peut considérer chaque CA comme une PKI en soi.
Tharyrok consulte son PKopion
Easy-rsa a la propriété de gérer plusieurs environnements. Ici, on va initaliser une PKI dans le dossier root.
Chaque distribution a sa façon de gérer easy-rsa, sur debian cela se trouve dans /usr/share/easy-rsa (pas super intuitif).
EASYRSA_PKI=root /usr/share/easy-rsa/easyrsa init-pki
Avec un tree, on voit qu'il acréer un dossier root, avec différents fichiers de config, un dossier private pour les clés privées, et un dossier reqs pour les CSR (cert signature request). Easy-rsa est un wrapper d'openssl. Lorsqu'on l'utilise, ça va faire des commandes openssl derrière.
On va modifier le fichier vars
Cela permet de modifier toutes les varables qui vont être utilisées. En premier lieu, on va modifier pour faire des courbes elliptiques.
set_var EASYRSA_DIGEST "sha512"
Le CA a le plus gros niveau de sécurté, donc on utilise les options les plus sécurisées. Ce CA dure longtemps (20 ans !!), donc avec l'évolution des méthodes de chiffrement, au moment où il expirera, il algorithmes les plus faibles, donc important de choisir les meilleures au moment de sa création.
On se rend sur la machine VPN pour récupérer le certificat actuel.
- snippet.bash
openssl x509 -in ca.crt -noout -subject
Il contient beaucoup d'infos, du style common name, country, email, etc, aujourd'hui, on en utilise moins. Aujourd'hui, on n'a plus que country, organization et common name.
On revient sur easy-rsa. Il n'y a pas besoin du support netscape extensions, que les moins de 20 ans ne peuvent pas connaître.
Pour la courbe, on choisit de manière assez arbitraire et autoritaire ed25519
. On choisit 20 ans de durée de vie, donc 7300 jours au pif.
On ne va jamais générer de nouveaux certificats avec la root CA, on va juste en signer. La différence étant
Pour les certificats signés par le root CA, on va mettre 5 ans (1825 jours)
On définit le pays et le nom de l'organisation.
Il faut aussi définir le type de CA : nous on va être en org mode, et pas en cn_only (par défaut).
Au final le fichier donne (sans les commentaires) :
- snippet.bash
# grep -E -v '^(#|$|;)' root/vars set_var EASYRSA_DN "org" set_var EASYRSA_REQ_COUNTRY "BE" set_var EASYRSA_REQ_PROVINCE "" set_var EASYRSA_REQ_CITY "" set_var EASYRSA_REQ_ORG "Neutrinet VZW/ASBL" set_var EASYRSA_REQ_EMAIL "" set_var EASYRSA_REQ_OU "" set_var EASYRSA_ALGO ed set_var EASYRSA_CURVE ed25519 set_var EASYRSA_CA_EXPIRE 7300 set_var EASYRSA_CERT_EXPIRE 1825 set_var EASYRSA_CRL_DAYS 1825 set_var EASYRSA_CERT_RENEW 1825 set_var EASYRSA_NS_SUPPORT "no" set_var EASYRSA_DIGEST "sha512"
Pour le moment, on a juste initié la PKI. On va maintenant générer notre CA.
- snippet.bash
EASYRSA_PKI=root /usr/share/easy-rsa/easyrsa build-ca nopass
Il demande toutes les infos liées au certificat mais en faisant Enter, il ne les prend pas.
On va l'appeler Neutrinet Root CA.
Dans le certificat, issues est le même que le sujet, donc c'est un certificat auto-signé. Dans les usages, on voit qu'il ne peut que signer des certificats (Certificate Sign) et des requests (CRL Sign).
On va maintenant générer notre sous-CA.
On fait un dossier VPN dans lequel on initalise la PKI. On copie notre fichier vars mais on va modifier certaines choses : on va mettre 5 ans pour ce sous-certificat, et puis l'algorithme de chiffrement.
Pour le VPN, on fait un certificat en RSA car ISPNG ne peut probablement pas signer autre chose (trop vieux). En tout cas on ne veut pas prendre le risque.
Pour le certificat du serveur VPN, on mettra 5 ans aussi pour simplifier les choses. Lors des AG, on fera le renouvellement des deux en même temps
Pour le VPN, le fichier vars ressemble a :
- snippet.bash
set_var EASYRSA_DN "org" set_var EASYRSA_REQ_COUNTRY "BE" set_var EASYRSA_REQ_PROVINCE "" set_var EASYRSA_REQ_CITY "" set_var EASYRSA_REQ_ORG "Neutrinet VZW/ASBL" set_var EASYRSA_REQ_EMAIL "" set_var EASYRSA_REQ_OU "" set_var EASYRSA_KEY_SIZE 8192 set_var EASYRSA_ALGO rsa set_var EASYRSA_CA_EXPIRE 1825 set_var EASYRSA_CERT_EXPIRE 1825 set_var EASYRSA_CRL_DAYS 1825 set_var EASYRSA_CERT_RENEW 1825 set_var EASYRSA_NS_SUPPORT "no" set_var EASYRSA_DIGEST "sha512"
La commande pour générer le PKI est :
- snippet.bash
EASYRSA_PKI=vpn /usr/share/easy-rsa/easyrsa init-pki
Pour générer le certificat, la commande change un peu parce qu'on spécifie que c'est sub CA. On va l'appeler “Neutrinet VPN CA”.
- snippet.bash
EASYRSA_PKI=vpn /usr/share/easy-rsa/easyrsa build-ca nopass subca
Si on fait un tree, on voit que là où on avait root CA pour le CA, on a dans le dossier VPN ca.req (tree selectif ci-dessous ).
. ├── root │ ├── ca.crt │ ├── private │ │ └── ca.key │ ├── reqs │ └── vars ├── vars └── vpn ├── private │ └── ca.key ├── reqs │ └── ca.req └── vars
On va utiliser cette requête pour importer le CA du VPN dans le dossier du root CA (en lui donnant un nom avec l'année) pour pouvoir le signer avec le root CA. On utilisera cette requête lors du renouvellement.
En fait, c'est ce qu'on fait avec le VPN quand on doit copier le CSR.
- snippet.bash
EASYRSA_PKI=root /usr/share/easy-rsa/easyrsa import-req vpn/reqs/ca.req vpn-2023
En refaisant un tree, on voit qu'on a bien une requête vpn-2023 qui est apparu dans le root CA.
Ensuite, on va signer la requête VPN 2023, en disant que c'est une requête de type CA.
- snippet.bash
EASYRSA_PKI=root /usr/share/easy-rsa/easyrsa sign-req ca vpn-2023
En fait, les requêtes sont là pour nous faciliter la vie lors des renouvellement : on définit tout une fois, puis les prochaines années on devra juste appuyer sur un bouton pour renouveler le certificat du sub CA.
Quand on affiche le certificat, on voit que le issuer est le root CA et le sujet le CA du VPN.
On voit qu'on a deux nouvelles entrées : un certificat par numéro de série, et un certificat “issued”. Ces deux fichiers sont le même certificat !
On a la possibilité de révoquer un certificat. On le fait en utilisant la requête du VPN 2023, ce qui va générer un certificat qui représente la révocation.
Maintenant, il nous manque encore le certificat du serveur VPN ! Générons-le :
- snippet.bash
EASYRSA_PKI=vpn /usr/share/easy-rsa/easyrsa gen-req openvpn-server nopass
Pour le moment, on ne pourra pas encore l'utiliser car les briques ne connaissent pas le nouveau certificat serveur. Mais on peut déjà le générer comme ça c'est fait (sinon on devra rassembler les clés).
On le signe :
- snippet.bash
EASYRSA_PKI=vpn /usr/share/easy-rsa/easyrsa sign-req server openvpn-server
On va copier / coller les certificats qu'il nous faut.
Renouvellement
On va expérimenter le renouvellement pour pouvoir mettre les commandes dans le ReadME. Donc le CA, le sous-CA du VPN et le certificat serveur.
On commence par le serveur vpn. La commande très compliquée :
- snippet.bash
EASYRSA_PKI=vpn /usr/share/easy-rsa/easyrsa renew openvpn-server nopass
Ensuite, on fait le sous CA du VPN. C'est la même commande que pour générer le CA, car on reprend la requête.
- snippet.bash
EASYRSA_PKI=root /usr/share/easy-rsa/easyrsa sign-req ca vpn-2023
Dans 10 ans, on devra regénérer la nouvelle root CA. Tous les sous-CA à partir de ce moment-là se feront signer par la nouvelle root CA, et petit à petit les clients prendront connaissance de celle-ci.
Convention de nommage
Là notre CA s'appelle juste CA. Comme on devra le renouveler dans 10 ans, c'est pas futé. On va donc refaire les choses bien avec une convention de nommage.
Pour la convention de nommage, on va un peu se calquer sur Let's Encrypt:
- X1 = niveau le plus élevé dans la hiérarchie
- R1 = sous CA de type RSA
- E1 = sous CA de type courbe elliptique
On changera le numéro à chaque renouvellement.
Donc au final, cela donne:
- Neutrinet Root CA X1
- Neutrinet VPN CA R1 → sous CA du VPN
- Neutrinet VPN Server → certificat du VPN
- Neutrinet HOST CA E1 → sous CA hypothétique inter-serveurs
Pour le certificat du serveur, on n'a pas besoin de lui attribuer une lettre et un nombre car il dépend de la sous-ca juste au dessus, et celle-ci sera nommée de manière unique.
Ça y est on a généré tous nos certificats !!
Migration d'ISPng vers buster
Modification à faire sur la machine VPN
Il faut maintenant injecter la sous-CA du VPN dans ISPng et OpenVPN.
Il faut également reconfigurer le réseau du nouveau VPN.
Il faut copier les données du VPN, c'est-à-dire la base de données et le ldap.
Ensuite, on testera avec la brique raoul un renouvellement du certificat.
Enfin, on basculera l'IP du VPN vers la nouvelle machine.
Après tout ça, il faudra créer le logrotate pour ispng, vérifier celui de openvpn. On doit en effet garder les logs pendant un an à cause de la surveillance d'État.
Et il faudra également copier les scripts de nettoyage du VPN (libération ip, etc)
En fait le réseau est déjà configuré, ça fait un truc en moins \o/
injecter la sous-CA du VPN dans ISPng et OpenVPN
Sur la machine du VPN, on retrouve le CA du VPN dans le fichier ca/ca.jks
, un keystore.
On a un alias qui s'appelle ca qui contient le certificat
En tout cas, dans le config.properties
on voit que le ca.crt
est utilisé, le ca/ca.jks
est aussi utilisé.
Mais il y a un ca.p12 aussi, qui est un autre format. Il est probablement utilisé quelque part parce qu'il contient les certificats BeID
Il faut voir, une fois qu'il a chargé la config depuis le key store java, comment la clé du CA est sélectionnée. On voit dans le dépot git qu'il va chercher la clé via l'alias.
Dans le code, ca est hardcodé donc on va être obligé d'appeler le fichier “ca” pour la clé privée et le certificat, dans le keystore.
Pour gérer des keystore, il faut l'outil keytool qui se retrouve livré avec java.
Cette commande permet de générer le P12 (qui est donc un fomat de fichier contenant des certificats):
- snippet.bash
openssl pkcs12 -export -inkey vpn-r1/private/ca.key -in vpn-r1/ca.crt -out /tmp/tmp.OMacaRubju/ca.p12 -name "ca"
Elle demmande de mettre un mot de passe pour le p12.
On doit maintenant le convertir en keystore pour que java soit content:
keytool -importkeystore -srckeystore ca.p12 -srcstoretype pkcs12 -destkeystore ca.jks -deststoretype jks
Pareil, il demande le mot de passe du p12 pour le déchiffrer, puis un autre mot de passe pour chiffrer le keystore.
On copie ces deux fichiers sur la nouvelle machine du VPN, dans le dossier ca. On copie également le ca.crt à la racine d'ISPng. On ne sait pas trop pourquoi c'est à cet endroit-là, mais on ne va rien bouger par peur de provoquer Murphy.
OpenVPN aura l'ancien CA et le nouveau, donc les anciennes
Après avoir inséré les fichiers dans ispng, on va un peu nettoyer des vieux trucs dans /etc/openvpn/keys qui servent à rien et puis on va redémarrer.
On copie notre fichier ca-vpn-r1.crt. Et on va insérer le contenu dans ca.crt.
On redémarre openvpn et ispng.
Ca semble ok.
Rapatriement des backups
On va rapatrier la base de donnée et le ldap.
La marche à suivre est décrite dans : https://gitlab.domainepublic.net/Neutrinet/infra-ansible/-/issues/148
Pour les manips, on arrête le service ispng.
Pour postgresql :
- On crée un dump de la base de donnée d'ISPng:
bash sudo -u postgres pg_dump ispng > /tmp/ispng.sql
- On copie les fichiers vers la nouvelle machine :
bash scp -3 vpn.louise.neutri.net:/tmp/ispng.sql ispng.patata.louise.neutri.net:/tmp/
- On crée la base de données et on restore le dump:
bash sudo -u postgres createdb ispng sudo -u postgres psql ispng < /tmp/ispng.sql
Pour le ldap:
- On fait un dump du ldap. Il y a deux parties : la config et les données. On obtient deux fichiers .ldif
slapcat -n 0 -l config.ldif slap`at -n 1 -l data.ldif
- On stoppe le ldap, puis on restaure les fichiers ldif (cf. le ticket dans gitlab: https://gitlab.domainepublic.net/Neutrinet/infra-ansible/-/issues/148#note_11164)
Ensuite il faut redémarrer ldap (slapd.service) et zookeeper.
Configuration du HAProxy
On utilise un HAProxy devant api.neutrinet.be, cela permet de gérer les certificats en bypassant le keystore de IPSng.
Test avec Raoul
On se connecte en local à la brique de test:
ssh admin@172.16.3.55
On modifie /etc/hosts
pour réécrire les noms de domaine vpn.neutrinet.be et api.neutrinet.be pour pointer vers l'IP 80.67.181.132
On installe l'app Neutrinet pour Yunohost (puisqu'elle n'était pas installée):
yunohost app install neutrinet
Le script de renouvellement des certificats se trouve sur /opt/neutrinet/renew_cert
. Là, il y a un script bash pour le cron, et il va copier tous les certificats au bon endroit.
Pour simuler le renouvellement, on a effacé :
rm /etc/openvpn/keys/
Puis on lance le script dans :
/opt/neutrinet/renew_cert/renew_cert_cron.sh
Il faut redémarrer happroxy en mettant l'adresse 127.0.0.1 plutôt que son équivalent IPv6.
Là on a un souci d'accès à la db. La db ispng a postgresql comme owner, ça doit être ispng.
/usr/lib/jvm/temurin-8-jdk-amd64/bin/java
Prochaine réunion
Prochaine réunion : MM/JJ à HH:MM
Lieu : Jitsi ? Caldarium ? Autre ?
Météo de fin
Moment informel durant lequel on exprime en peu de mots comment, à titre personnel, la réunion a été vécue que ce soit positif ou négatif. Si une ou plusieurs tension est née durant la réunion, il est peut-être nécessaire d'envisager l'une ou l'autre réunion pour y remédier.