Introduction Link to heading
En mission chez un client depuis quelques années, j’installe régulièrement des services ou héberge des applications qui, la plupart du temps, seront ensuite exposées en interne en https avec des certificats auto-signés, par manque de CA interne ou de moyen facile de récupérer des certificats via ACME ou autre. Comme vous pouvez l’imaginer, gérer les périodes de validité (révocation ou expiration), déployer des bundles là où nécessaire, injecter les certificats dans les trust-stores, etc. est un vrai cauchemar et beaucoup de raccourcis peu sécurisés ont été pris dans les configurations de certains outils pour faciliter le travail de personnes gérant ces services.
Ça faisait quelque temps que j’ai envie de changer ça. Rapidement la situation est devenue ingérable pour quelques collègues et moi-même et finalement, nos voix ont gagné suffisamment d’attention pour que la situation change et que je puisse commencer à travailler à la mise en place d’une solution.
Le besoin de noter quelque part les choses que j’avais pu apprendre ainsi que celles que j’aurais aimées pouvoir trouver facilement sur internet en travaillant sur ce projet m’ont finalement poussé à écrire une série d’articles allant de la génération des CAs à leur hébergement : Self hosted PKI.
Les prochains billets de cette série couvriront :
- L’initialisation d’une CA root et d’une CA intermédiaire avec
cfssl
; - Hébergement des CA, CRL et des ocsp responders avec kubernetes ;
- Déploiement des chaînes CA sur linux avec ansible ;
- Hébergement d’une API de signature de certificat dans kubernetes ;
- Configuration de cert-manager, trust-manager et leur utilisation avec les Ingresses.
Où est-ce que ça va tourner Link to heading
Bien que j’aie finalement implémenté ce PKI dans le cadre du travail, j’ai fait mes premiers tests dans mon home-lab que j’utiliserai aussi pour tous les exemples techniques de cette série. J’implémenterai donc un nouveau PKI dans un environnement temporaire de mon home-lab afin d’éviter de divulguer des informations critiques. Ce home-lab consiste en quelques machines tournant sur archlinux/archlinux-arm : mes partages réseaux sont servis par deux machines armv7l, mon routeur & serveur dns/dhcp/ntp, etc. est une machine en amd64 et mon cluster kubernetes est composé de 5 machines en arm64.
Le PKI sera hébergé dans ce cluster kubernetes dont les Ingresses sont gérés avec Traefik. Les autres machines de mon réseau local devront intégrer dans leur ca-trust ces CA auto-hébergées et auto-signées.
Toolkit Link to heading
J’ai regardé quelles étaient mes options pour administrer le PKI et, si je me souviens correctement j’ai eu l’occasion de lire de la documentation et de jouer un peu avec :
-
OpenSSL
J’ai mis de côté openssl étant donné que j’avais besoin de fournir une API pour signer des certificats et n’avais pas envie de développer et de maintenir une nouvelle application pour le faire.
-
Let’s Encrypt Boulder: https://github.com/letsencrypt/boulder
Let’s Encrypt déconseille généralement l’utilisation de Boulder : cet outil est fait pour une organization dont la signature de certificat est le cœur de métier et est fait spécialement pour leurs besoins spécifiques. Aussi, l’entreprise dans laquelle je suis en mission n’est pas un fournisseur de certificats ou un hébergeur, etc. Utiliser Boulder serait donc probablement excessif.
-
HashiCorp Vault: https://www.hashicorp.com/products/vault/pki-with-vault
J’ai passé pas mal de temps à jouer avec Vault : je travaille déjà avec cet outil pour pas mal de choses : HMS pour le chiffrement des secrets de kubernetes dans etcd, stockage de configuration et fichiers sensibles, etc. Vault est bien pensé et très puissant et j’ai passé du temps à tester son moteur PKI, mais après mûre réflexion, j’ai cherché autre chose avec lequel mes collègues seraient plus à l’aise.
-
Cloudflare cfssl: https://github.com/cloudflare/cfssl
C’est l’outil que j’ai finalement choisi après avoir vu avec quelle facilité je pouvais initialiser une CA et exposer une API. J’ai vite regretté son manque de documentation en revanche, mais heureusement, son code source était très facile à lire et était suffisant pour comprendre quel format de configuration était attendu, comment fonctionnaient les APIs, ce que faisaient exactement les options et les paramètres, etc.
Conclusion Link to heading
Quand j’ai commencé à travailler sur ce projet, j’avais seulement des connaissances très basiques sur le fonctionnement d’une CA. J’ai donc appris beaucoup de choses en lisant du code, de la documentation, des RFCs, et depuis quelques discussions très enrichissantes avec des amis et collègues. Ainsi, si vous pensez que j’ai fait des erreurs, s’il vous plait n’hésitez pas à me contacter pour que je puisse les corriger et continuer à apprendre.