Protéger les clés privées SSL dans NGINX avec HashiCorp Vault

NGINX | 16 avril 2019

Dans le premier article de cette série, nous décrivons plusieurs approches permettant de renforcer la sécurité de vos clés privées SSL. L’article se termine par une démonstration d’un point de distribution de mots de passe (PDP) distant, utilisé pour partager de manière sécurisée les mots de passe de chiffrement avec les instances NGINX.

Les systèmes de gestion des secrets tels que HashiCorp Vault fonctionnent de manière similaire à cet exemple de PDP :

  • Ils utilisent un service de gestion des secrets centralisé (ou distribué et hautement disponible), accessible via HTTPS ou une autre API.
  • Les clients sont authentifiés à l’aide de jetons d’authentification ou par d’autres moyens
  • Les jetons peuvent être révoqués si nécessaire afin de contrôler l’accès au secret

Dans cet article, nous vous expliquons comment configurer HashiCorp Vault pour distribuer des mots de passe SSL. Pour renforcer encore davantage la sécurité, vous pouvez configurer un module matériel de sécurité externe (HSM).

Pour éliminer complètement le stockage sur disque des paires certificat-clé SSL, consultez le troisième article de cette série, « Utilisation du magasin clé-valeur de NGINX Plus pour sécuriser les clés SSL éphémères de HashiCorp Vault ». Il explique comment générer des clés SSL éphémères à partir de HashiCorp Vault et les stocker en mémoire dans le magasin clé-valeur de NGINX Plus.

Cet article s’applique à la fois à NGINX Open Source et à NGINX Plus. Pour faciliter la lecture, nous utiliserons le terme « NGINX » dans la suite de l’article.

Utiliser HashiCorp Vault pour protéger les clés privées SSL

Les instructions de cette section permettent de configurer un serveur PDP central utilisant Vault pour distribuer les mots de passe SSL. Elles s’appuient sur les instructions de DigitalOcean ; adaptez-les si nécessaire afin de respecter vos propres politiques Vault.

Dans notre exemple, chaque serveur web distant dispose d’un jeton d’authentification unique. Ces jetons permettent d’accéder aux secrets stockés dans le chemin secret/webservers/ de Vault, et nous stockons les mots de passe SSL dans secret/webservers/ssl_passwords.

Nous verrons comment sécuriser les jetons et comment révoquer individuellement les jetons d’authentification lorsque cela est nécessaire.

Télécharger, installer et initialiser HashiCorp Vault sur le serveur PDP

  1. Suivez les instructions de DigitalOcean pour télécharger et extraire Vault sur votre serveur PDP. Nous utilisons l’exemple de fichier /etc/vault.hcl suivant afin de rendre Vault accessible à distance et de désactiver TLS (pour faciliter les tests) :
backend "file" {    path = "/var/lib/vault"
}

listener "tcp" {
    address = "0.0.0.0:8200"
    tls_disable = 1
}
  1. Démarrez Vault à l’aide des scripts de démarrage (si vous les avez créés), ou manuellement :
user@pdp:~$ sudo /usr/local/bin/vault server -config=/etc/vault.hcl
  1. Initialisez Vault et obtenez le jeton racine initial :
user@pdp:~$ export VAULT_ADDR=http://localhost:8200
user@pdp:~$ vault init -key-shares=3 -key-threshold=2
user@pdp:~$ vault operator unseal
Initial Root Token: 86c5c2a4-8ab2-24dd-1816-48449c83114e
  1. Nous devons fournir le jeton racine initial dans bon nombre des commandes suivantes. Pour plus de commodité, nous l’affectons à la variable shell « root_token » :
user@pdp:~$ root_token=86c5c2a4-8ab2-24dd-1816-48449c83114e

Stocker les secrets

  1. Toujours sur le serveur PDP, créez un fichier temporaire nommé « /tmp/ssl_passwords.txt » contenant les mots de passe.
  2. Stockez ce fichier en tant que secret dans Vault, puis vérifiez que vous pouvez le récupérer :
user@pdp:~$ VAULT_TOKEN=$root_token vault kv put secret/webservers/ssl_passwords value=@/tmp/ssl_passwords.txt

user@pdp:~$ VAULT_TOKEN=$root_token vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...
  1. Pour des raisons de sécurité, supprimez /tmp/ssl_passwords.txt.
  2. Créez une spécification de politique dans un fichier nommé web.hcl avec le contenu suivant :
path "secret/webservers/*" {
    capabilities = ["read"]
}
  1. Chargez la politique dans Vault et nommez-la « web » :
user@pdp:~$ VAULT_TOKEN=$root_token vault policy write web web.hcl
  1. Créez un nouveau jeton d’authentification, associez-le à la politique web et, si vous le souhaitez, ajoutez le paramètre display-name afin de lui attribuer un nom convivial. Notez les valeurs de token et de token_accessor ; vous les utiliserez dans les commandes suivantes :
user@pdp:~$ VAULT_TOKEN=$root_token vault token create -policy=web -display-name=webserver1
Key                  Value
---                  -----
token                dcf75ffd-a245-860f-6960-dc9e834d3385
token_accessor       0c1d6181-7adf-7b42-27be-b70cfa264048
  1. Le serveur web NGINX utilise ce jeton pour récupérer les mots de passe SSL. La politique « web » empêche le serveur web de récupérer des secrets en dehors du chemin « secret/webservers/* ».

Vérifier que le serveur web peut récupérer le jeton

  1. Sur le serveur web NGINX, installez le binaire Vault.
  2. Déclarez l’emplacement du serveur Vault distant (ici, http://pdp:8200), puis vérifiez que la machine hébergeant le serveur web peut récupérer les mots de passe SSL à l’aide du jeton :
user@web1:~$ export VAULT_ADDR=http://pdp:8200user@web1:~$ VAULT_TOKEN=dcf75ffd-a245-860f-6960-dc9e834d3385 vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...

Configurer le connecteur Vault de NGINX sur le serveur web

  1. Dans le cadre de la configuration de l’exemple de PDP dans le premier article, nous avons créé un script shell nommé connector.sh sur l’hôte NGINX (la machine faisant office de serveur web). Nous allons maintenant le modifier pour qu’il utilise Vault :
#!/bin/sh
# Usage: connector_v.sh  

CONNECTOR=$1
CREDS=$2

[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR

mkfifo $CONNECTOR; chmod 600 $CONNECTOR

export VAULT_ADDR=http://pdp:8200
export VAULT_TOKEN=$CREDS

while true; do
    vault kv get -field=value secret/webservers/ssl_passwords > $CONNECTOR
    sleep 0.1 # race condition, ensures EOF
done
  1. Exécutez le script en tant que processus d’arrière-plan, comme suit :
root@web1:~# ./connector_v.sh /var/run/nginx/ssl_passwords \dcf75ffd-a245-860f-6960-dc9e834d3385 &
  1. Testez le connecteur en effectuant une lecture à partir du chemin du connecteur :
root@web1:~$ cat /var/run/nginx/ssl_passwordspassword1
password2
...
  1. Configurez NGINX pour qu’il lise le fichier ssl_passwords au démarrage et utilise son contenu comme mots de passe pour déchiffrer les clés privées chiffrées. Vous pouvez inclure la directive ssl_password_file soit dans un bloc server (comme celui créé pour la configuration standard dans le premier article), soit dans le contexte http afin de l’appliquer à plusieurs serveurs virtuels :
ssl_password_file /var/run/nginx/ssl_passwords;
  1. Vérifiez que NGINX peut lire le mot de passe et déchiffrer les clés SSL :
root@web1:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Révocation du jeton d’authentification d’un serveur web

Vous pouvez facilement révoquer l’accès si le serveur web est compromis ou lorsqu’il est mis hors service. Pour ce faire, vous pouvez révoquer directement le jeton d’authentification utilisé par le serveur web :

user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke dcf75ffd-a245-860f-6960-dc9e834d3385

Les jetons Vault sont des données sensibles, et de nombreux workflows Vault ne conservent aucune copie des jetons délivrés à un client authentifié. Si la copie d’un jeton est divulguée, un attaquant peut usurper l’identité du client.

À la place, il est courant de gérer un jeton actif à l’aide de son accesseur, qui confère des droits limités sur le jeton et ne permet pas d’en récupérer la valeur. Plutôt que de stocker les jetons lorsqu’ils sont émis, stockez l’accesseur correspondant.

Si vous devez déterminer l’accesseur du jeton d’authentification d’un serveur web, exécutez la commande vault list pour récupérer la liste des accesseurs, puis la commande vault token lookup sur chaque accesseur afin de trouver celui qui possède le nom d’affichage et la politique appropriés :

user@pdp:~$ VAULT_TOKEN=$root_token vault list /auth/token/accessors
Keys
----
83be5a73-9025-1221-cb70-4b0e8a3ba8df
0c1d6181-7adf-7b42-27be-b70cfa264048
f043b145-7a63-01db-ea85-9f22f413c55e

user@pdp:~$ VAULT_TOKEN=$root_token vault token lookup -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048
Key                 Value
---                 -----
...
display-name        webserver1       
...
policy              web
...

Vous pouvez ensuite révoquer le jeton à l’aide de son accesseur :

user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048

Implications en matière de sécurité

L’utilisation de Vault présente un profil de sécurité similaire à celui de l’exemple de PDP décrit dans le premier article. Les clés privées SSL ne peuvent être obtenues que si le mot de passe correspondant l’est également. Pour cela, un attaquant doit connaître la valeur d’un jeton d’authentification en cours de validité.

Le principal avantage de Vault est de permettre l’automatisation et la mise à l’échelle du stockage des secrets.

Utilisation d’un HSM externe pour gérer les clés privées

Aucune des solutions que nous avons présentées jusqu’à présent dans cette série ne protège la clé privée lorsqu’un attaquant obtient un accès root au serveur NGINX. Si un attaquant peut accéder à la mémoire d’exécution de NGINX ou générer un vidage mémoire, il existe des techniques bien connues permettant d’analyser la mémoire du processus et d’y localiser les données de la clé privée.

Les modules matériels de sécurité (HSM) externes résolvent ce problème en stockant les clés privées SSL dans un matériel externe inviolable. Ils fournissent un service de déchiffrement auquel NGINX accède chaque fois qu’il doit effectuer une opération SSL nécessitant la clé.

Le serveur NGINX n’a jamais accès aux données de la clé privée SSL. Un attaquant qui obtient un accès root au serveur ne peut pas récupérer la clé privée SSL, mais peut déchiffrer des données à la demande en accédant au service de déchiffrement du HSM à l’aide des identifiants NGINX.

Configuration de NGINX pour accéder à un HSM

NGINX délègue toutes les opérations liées aux clés privées SSL à une bibliothèque cryptographique appelée OpenSSL. Les périphériques HSM tiers peuvent être mis à la disposition de NGINX à l’aide du moteur OpenSSL du fournisseur du HSM.

La configuration de NGINX est propre au HSM de chaque fournisseur, mais suit généralement une procédure simple :

  • Configurez NGINX pour utiliser le moteur OpenSSL du fournisseur plutôt que le moteur logiciel par défaut :
ssl_certificate_key engine:vendor-hsm-engine:...;
  • Au lieu d’utiliser la véritable clé privée, configurez NGINX pour qu’il utilise la « fausse » clé fournie par le fournisseur. Cette clé contient un identifiant permettant de retrouver la véritable clé sur le périphérique HSM :
ssl_certificate_key ssl/vendor.private.key;
  • La clé peut également contenir les identifiants permettant d’accéder au périphérique HSM, ou ceux-ci peuvent être fournis au moyen d’une configuration supplémentaire propre au fournisseur.
  • (Facultatif) Appliquez les réglages souhaités, par exemple en augmentant le nombre de processus de travail NGINX, afin d’optimiser les performances de NGINX et du HSM.

Pour un exemple de configuration d’un HSM, consultez la documentation CloudHSM d’Amazon.

Implications en matière de sécurité

Les HSM externes constituent une méthode hautement sécurisée pour stocker les clés privées SSL. Un attaquant disposant d’un accès root au serveur NGINX peut utiliser les identifiants NGINX pour déchiffrer des données arbitraires à l’aide du HSM, mais ne peut pas obtenir la clé privée non chiffrée. Un HSM complique considérablement la tâche d’un attaquant qui chercherait à usurper l’identité d’un site web ou à déchiffrer hors ligne des données arbitraires.

Conclusion

Il est essentiel de veiller à ce que les données confidentielles, telles que la clé privée SSL, soient entièrement protégées, car les conséquences de leur divulgation sont très graves.

Pour de nombreuses organisations disposant de processus de sécurité appropriés, il suffit de stocker la clé privée sur les répartiteurs de charge frontaux, puis de restreindre et d’auditer tous les accès à ces serveurs (la « configuration standard » décrite dans le premier article).

Pour les organisations qui doivent déployer fréquemment la configuration de NGINX, les mesures présentées dans cet article et dans le premier article peuvent être utilisées pour limiter le nombre d’utilisateurs ou d’entités ayant accès aux données de la clé privée.

Dans le troisième article de cette série, « Utilisation du magasin clé-valeur de NGINX Plus pour sécuriser les clés SSL éphémères provenant de HashiCorp Vault », nous expliquons comment automatiser le provisionnement des clés et des certificats depuis Vault vers le magasin clé-valeur de NGINX Plus à l’aide de l’API NGINX Plus.

Rappelons qu’aucune de ces méthodes ne dispense de sécuriser pleinement les instances NGINX en cours d’exécution contre les accès à distance ou toute modification de leur configuration.

Essayez NGINX Plus par vous-même : commencez votre essai gratuit de 30 jours dès aujourd’hui ou contactez-nous pour discuter de vos cas d’utilisation.


Partager
Mots-clés : Security, SSL/TLS, F5 NGINX, Tech, 2019

À propos de l’auteur

Owen Garrett
Owen GarrettDirecteur senior de la gestion des produits

Autres articles de Owen Garrett

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
NGINX | 13/10/2025

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA

Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
NGINX | 03/11/2023

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?

Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
NGINX | 11/03/2020

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX

Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
NGINX | 11/06/2019

Un testeur d’expressions régulières pour NGINX et NGINX Plus

Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.

Caches partagés avec les clusters de cache NGINX Plus, partie 1
NGINX | 24/01/2017

Caches partagés avec les clusters de cache NGINX Plus, partie 1

Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.

Introduction aux microservices
NGINX | 19/05/2015

Introduction aux microservices

Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.