StepCA Deployment

Okay, on va déployer une infra PKI. Sachant que mon plus gros besoin est de pouvoir faire du mTLS entre différents outils. Les premiers trucs qui me viennent en tête :

  • Réplication OpenLDAP
  • Limiter l’accès à un registry d’image de containeurs (Ouais il y a plein d’autres manières de faire ça évidemment)

Je suis plutôt à l’aise avec l’usage SSL/TLS, sans être cryptographe : en gros je sais utiliser OpenSSL dans ses bases. Mais l’idée est d’utiliser StepCA pour nous aider à gérer tout ça, histoire d’utiliser un système de renouvellement très court. Je ne veux pas m’embêter avec la gestion d’une CRL.

En écrivant ces lignes je me suis rendu compte, qu’il y a toujours beaucoup à apprendre. Et ça se vérifie avec la cryptographie.

Mode StepCA

Au début j’ai pensé utiliser la fonction de Registration Authority qui existe avec StepCA. J’ai réussi à l’utiliser, c’est assez marrant, mais ça ne correspondait pas vraiment à mon usage.
Je préfère un truc ou même si un serveur tombe, le reste de l’infra peut encore tourner. Et surtout, dans mon utilisation je devais exposer directement les service StepCA sur l’internet et ça je ne veux pas trop. Je pense qu’il y a moyen de faire ça proprement, mais je ne suis encore bien à l’aise avec l’outil.
De même en regardant l’option de Federated CA, mais ce n’est pas non plus vraiment aligné avec ce que je veux.
Mon usage va être simple : sur chaque zone, on déploie un StepCA avec un intermediate CA, signé par un root CA soigneusement conservé.

Plutôt que générer directement un CA racine avec des certificats avec OpenSSL, on va le faire avec StepCA, ça nous permettra de générer des ca.json (fichier de configuration de StepCA)

Okay, pour ne pas pourrir de machine avec des installations de paquets je vais beaucoup utiliser podman, avec des montages de dossier.

Génération du RootCA avec son premier intermédiaire

Mise en place

mkdir -p /opt/containers/tmp-stepca/
chown 1000:1000 /opt/containers/tmp-stepca/
podman run -it --rm -v /opt/containers/tmp-stepca/:/home/step docker.io/smallstep/step-ca:latest bash

On va se générer deux petits mot de passe pour protéger les clés privés. Un pour l’intermédiaire et l’autre pour la racine

mkdir passwords
cat /dev/urandom |tr -dc A-Za-z0-9 | head -c40 > passwords/intermediate_password
cat /dev/urandom |tr -dc A-Za-z0-9 | head -c60 > passwords/rootca_password

Tiens pour l’anecdote (et parce que la syntaxe est intéressante) dans l’entrypoint de l’image de StepCA ils font ça comme ça

function generate_password () {
    set +o pipefail
    < /dev/urandom tr -dc A-Za-z0-9 | head -c40
    echo
    set -o pipefail
}

Usage de step

Pour générer juste les certificats

step ca init --name "Nom Test StepCA 🍻" --pki --deployment-type=standalone --password-file=passwords/intermediate_password

On change de suite le mot de passe de la clé du root

step crypto change-pass secrets/root_ca_key --password-file=passwords/intermediate_password --new-password-file=passwords/rootca_password --force

On génère les certificats avec la configuration de StepCA. On doit enlever l’option --pki et en rajouter d’autres.
Le --dns qui permet de choisir les noms auxquels va répondre StepCA. (On peut le mettre plusieurs fois)
Le --address qui permet de choisir l’interface d’écoute de StepCA (Si vous êtes en CT, ajustez) On va créer un --provisioner, qui nous permettre de controler ce StepCA et on lie ce dernier avec un admin (--admin-name et --remote-management)

cat /dev/urandom |tr -dc A-Za-z0-9 | head -c40 >> passwords/main_provisioner_password
step ca init --name "Nom Test StepCA 🍻" --dns stepca.example.org --address :9000 --deployment-type=standalone --key-password-file=passwords/rootca_password --password-file=passwords/intermediate_password --provisioner=PROVISIONER_NAME --provisioner-password-file=passwords/main_provisioner_password --admin-name=ADMIN_NAME --remote-management

On change de suite le mot de passe de la clé du root

step crypto change-pass secrets/root_ca_key --password-file=passwords/intermediate_password --new-password-file=passwords/rootca_password --force

Donc là, on se retrouve avec un Certificat Racine et un intermédiaire. C’est un début 🥳.

Suivant la commande utilisée, vous avez peut être aussi un fichier de configuration pour StepCA Avec la configuration générée, on peut d’ores et déjà lancer le service

step-ca --password-file passwords/intermediate_password $(step path)/config/ca.json

On a comme config/ca.json

{
  "root": "/home/step/certs/root_ca.crt",
  "federatedRoots": null,
  "crt": "/home/step/certs/intermediate_ca.crt",
  "key": "/home/step/secrets/intermediate_ca_key",
  "address": ":9000",
  "insecureAddress": "",
  "dnsNames": ["stepca.example.org"],
  "logger": {
    "format": "text"
  },
  "db": {
    "type": "badgerv2",
    "dataSource": "/home/step/db",
    "badgerFileLoadingMode": ""
  },
  "authority": {
    "enableAdmin": true
  },
  "tls": {
    "cipherSuites": [
      "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
      "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
    ],
    "minVersion": 1.2,
    "maxVersion": 1.3,
    "renegotiation": false
  }
}

Et comme config/defaults.json

{
  "ca-url": "https://stepca.example.org:9000",
  "ca-config": "/home/step/config/ca.json",
  "fingerprint": "3bdb7b0fe1c84dcb3c4427715b67fb0f3c2c5ce469cb588352b6cc9d9734b4d3",
  "root": "/home/step/certs/root_ca.crt"
}

Pour information :

  • Le fichier defaults.json est là pour l’usage de l’outil “client” step. Pas pour le service
  • Il est possible d’inclure directement le provisioner dans le fichier de configuration.
  • Les certificats racine et intermédiaire de StepCA ont par défaut 10 ans de validité.

On va générer un autre intermédiaire en passant cette fois par un CSR.

cat /dev/urandom |tr -dc A-Za-z0-9 | head -c40 > passwords/other_intermediate_password
step certificate create "Autre Serveur StepCA" certs/other_intermediate.csr secrets/other_intermediate.key --password-file=passwords/other_intermediate_password --csr

On le signe avec le certificat Racine

step certificate sign certs/other_intermediate.csr certs/root_ca.crt secrets/root_ca_key --profile intermediate-ca --password-file=passwords/rootca_password > certs/other_intermediate.crt

Avec ce nouveau certificat on a pratiquement tout ce dont on a besoin pour un nouveau serveur.
Il manque juste l’ajout manuel d’un provisioner.
En premier on génère une JSON Web Key

cat /dev/urandom |tr -dc A-Za-z0-9 | head -c40 > passwords/new_provisioner_password
step crypto jwk create --password-file=passwords/new_provisioner_password public-jwk.json private-jwk.json

La partie dans le public-jkw.json c’est ce qu’il faudra copier brut dans la conf ca.json. Il faut générer une entrée encryptedKey

cat private-jwk.json| step crypto jose format

Au premier démarrage d’un step ca, celui ci lira la configuration de ca.json vis à vis du premier provisioner.

Par example

{
...
"authority": {
    "provisioners": [
    {
        "type": "JWK",
            "name": "demo-provisioner",
            "key": {
                "use": "sig",
                "kty": "EC",
                "kid": "o2_3CFVfarlq_ujt-e2jmKeI_zEnrbfkZ6q-6HLv6rQ",
                "crv": "P-256",
                "alg": "ES256",
                "x": "gBPeLDcfqs2dexY-4yqoJDAX4dyQMkj8jwqSihR4aFM",
                "y": "_SgZwgOnmMWKGzZcdAiQ0gUze0STzgMFHgXc4c4s1_A"
            },
            "encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjYwMDAwMCwicDJzIjoiNXFfWWt6aXRTeFkwcHhWZ2tFWWUzUSJ9.cLbi817wgVfoWwplIHz_hmEQP6r930N2UOramJAIbyALrahi7YTpRg.VL2BwOuydFraUTaq.pFL-07StosVVkaamD43pvv3tYTXun1c87adZlDGEfrZjjE7qMM8XWG-znwxXnxfHM2eoxIXciGxS02E2gaEDiIqeAhnxKwLTOPLWKZOPKpbBOnsYWR7YMTKkxUlLxhTiBEfCH2yVuOHn9mzvzpPno46tihaP6YsH3Z2nrhNLqSoacDIhKhJKyImNvhXoWCF-4IIqJHCGzSG8In3V7XD4Sa8_iFLTrWLh-_fbZPF3L4uHGR7zY6vv_-QazUOPmVy7fa8gmeBZX-s83vf05kwmJUODnCCYW_yCmWml60HvzoqQL_4-kNjgqX6BzY1q9IQrL15mWDzR-lr1kVjKgTo.c4MuzVmzfECtwo-El9h2hw",
            "options": {
                "x509": {},
                "ssh": {}
            }
    }
    ],
    "enableAdmin": true
},
...
}

Avec cette entrée dans votre ca.json au premier démarrage le provisioner sera créé, mais sauvegardé dans la BDD. Vous pouvez dès lors le retirer. StepCA créera aussi le premier Super Admin ‘step’.

Quelques conseils “qui vont de soit”:

  • Ne pas laisser la clé privé du certificat racine, trainer sur un serveur, même chiffrée on évite.
  • On évite de faire transiter les clés privé sur le réseau. Dans le cas d’une création de certificat/clé, on génère un CSR et la clé sur la cible directement et c’est le CSR puis le certificat qui transite.

Comment générer le provisionner

step crypto jwe decrypt < test-jwk.priv > decrypt.json

Références:

 

blog

Mon petit espace


Utilisation & réflexion basique de StepCA

By halletienne, 2025-12-06