Gardez votre CA racine VPN hors ligne et émettez quand même des certificats
Gardez la clé racine hors du réseau, signez les certificats feuilles avec une CA intermédiaire, publiez une CRL à temps et testez la chaîne avant que le premier client ne se connecte.
Votre VPN répond aux connexions à 3 heures du matin alors que la machine qui signe ses certificats est éteinte dans un tiroir. Un client qui valide le certificat du serveur ne contacte jamais votre CA, donc la CA n’a pas besoin d’être joignable pour une connexion. La partie qui demande de la planification, c’est le jour où un certificat doit être émis, renouvelé ou révoqué pendant que la clé racine reste sous clé.
Ce qu’une connexion valide réellement
Quand le client OpenVPN se connecte, il parcourt la chaîne de signatures du certificat feuille du serveur jusqu’à un certificat de CA auquel il fait déjà confiance, vérifie la fenêtre de validité et, si le profil le prévoit, consulte une liste de révocation. Il ne recherche jamais votre CA racine. Le serveur fait l’image miroir pour les certificats clients. Au moment de la connexion, seuls le feuille, l’intermédiaire et le paquet de confiance distribué plus tôt sont présents.
Ce qui échoue réellement est l’une de trois choses : la clé de signature est indisponible à l’émission, une liste de révocation est devenue obsolète, ou le paquet de confiance du client est plus ancien que la chaîne présentée par le serveur. La première est un problème de processus ; les deux autres sont des problèmes de distribution. Aucune n’exige que la clé racine soit en ligne, et un service VPN géré qui exige un certificat privé pour l’authentification du tunnel ne fait que déplacer l’autorité de signature vers le fournisseur. Azure point à site fonctionne à l’inverse : vous téléversez un certificat racine et les certificats signés en dessous sont approuvés, alors demandez qui signe, qui valide et comment un certificat est retiré plus tôt.
Construisez la racine sur un hôte qui ne reçoit jamais d’adresse
Une racine hors ligne sert rarement : à signer le certificat de la CA intermédiaire, puis à le renouveler ou le révoquer. Tout le reste se passe un niveau plus bas. Faites le travail de la racine sur une machine tenue hors du réseau, si possible depuis un système live, et consignez qui était dans la salle. Les commandes supposent OpenSSL 1.1.1 ou plus récent, car -addext n’existe pas dans les anciennes compilations.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
-subj "/CN=Example VPN Root CA" -out root.crt \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
Créez l’intermédiaire sur l’hôte de signature et ne portez que sa demande vers la machine hors ligne. La racine signe cette demande avec une longueur de chemin nulle, si bien que la CA intermédiaire peut signer des certificats de point final mais ne peut pas créer une autre CA en dessous. Cette seule extension empêche un hôte de signature compromis de fabriquer une autorité équivalente à la racine. N’utilisez ECDSA que si chaque client exécute OpenVPN 2.4 ou plus récent ; sinon, générez des clés RSA et gardez le flux identique.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt
intermediate.ext contient basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign et authorityKeyIdentifier=keyid:always. Remettez la clé racine dans son coffre avant de reconnecter l’hôte de signature. Si la racine doit pouvoir révoquer l’intermédiaire, signez-le avec openssl ca -config root.cnf -extensions intermediate_ca contre un index.txt de niveau racine au lieu de openssl x509 -req, afin que le numéro de série soit enregistré ; puis livrez la liste racine obtenue dans le profil client, où un crl-verify basé sur fichier la lit au démarrage. Fournissez aux clients un paquet contenant les deux certificats de CA ; un feuille seul ne se validera pas contre la racine.
Émettez des feuilles depuis l’intermédiaire, avec une base de données
Signer avec openssl x509 -req fonctionne jusqu’à ce qu’il faille révoquer, car rien n’enregistre le numéro de série. Utilisez openssl ca dès le premier certificat pour que le numéro de série, l’expiration et l’état de révocation vivent dans une seule base de données. Créez les fichiers de la base une fois, puis pointez la configuration dessus :
mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com
La ligne d’usage de clé suppose une clé ECDSA ; ajoutez keyEncipherment pour RSA. Donnez à chaque client son propre nom commun, car OpenVPN identifie une connexion par ce champ, et deux portables qui partagent CN=vpn-client ne peuvent être distingués dans les journaux, dans les règles client-config-dir ni dans aucun envoi par utilisateur, et vous perdez l’attribution qui rend une décision de révocation défendable. Émettez et validez un feuille ainsi :
openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt
Gardez la clé de signature derrière une frontière de politique au lieu de la copier sur l’hôte VPN : un petit service qui authentifie la demande, vérifie le nom commun contre une liste d’autorisation et ne renvoie que le certificat. Journalisez chaque numéro de série ; le journal est le seul lien entre un certificat et la personne qui l’a demandé.
Publiez la révocation sans réveiller la racine
Les certificats clients sont révoqués par l’intermédiaire, jamais par la racine. La liste racine ne compte que lorsqu’un intermédiaire est brûlé. Pointez le serveur vers la liste intermédiaire avec crl-verify. Une CRL basée sur fichier est chargée au démarrage du service, alors rechargez après chaque régénération ; la forme répertoire lit l’état au moment de la connexion et coûte un fichier par numéro de série.
Révoquez et régénérez avec deux commandes de la même base de données :
openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem
Surveillez ensuite l’horloge. Une CRL porte un champ de prochaine mise à jour, et une fois cette date passée, un pair qui valide rejette la liste au lieu de l’ignorer. Une régénération mensuelle avec default_crl_days = 30 laisse de la marge ; annuelle non. Des durées de vie de feuille plus courtes sont le contrôle le plus fiable, car la révocation ne s’applique que là où la liste est consultée.
Testez la chaîne, puis écrivez la cérémonie
Reproduisez quatre échecs avant de faire confiance à la conception. Validez la chaîne avec openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt. Connectez-vous avec un certificat client expiré et confirmez que le serveur le refuse. Révoquez un client de test, rechargez et confirmez que la liste prend effet. Avancez l’horloge d’un hôte d’un jour, car une horloge fausse peut émettre et refuser des certificats qui semblent valides ailleurs.
Une racine hors ligne n’est un contrôle que si la paperasse existe : deux personnes nommées pour la cérémonie, un registre de chaque numéro de série signé, une sauvegarde chiffrée conservée à l’écart de la machine et un test de restauration sur un hôte isolé. Signez un intermédiaire de secours pendant la même cérémonie pour qu’un hôte de signature mort ne vous oblige pas à déverrouiller la racine à minuit.
Avant de le déclarer terminé, confirmez cinq choses : la clé racine n’est pas sur un hôte en réseau, la clé intermédiaire ne vit que sur l’hôte de signature, le paquet client porte les deux certificats de CA, la CRL a une prochaine mise à jour future et quelqu’un possède une entrée d’agenda pour chaque expiration de la chaîne. S’il en manque une, la configuration qui semble hors ligne n’est simplement pas documentée.