Générer un certificat TLS pour sécuriser son réseau interne
Il arrive que l'on souhaite sécuriser les échanges entre les services de notre réseau interne. Pour cela, il faut générer deux certificats. Le premire devra être installer sur le poste du client et le second sur le serveur.
Dans cet article, vous découvrirez comment générer ces 2 certificats et comment les installer dans un conteneur LXC sous Debian 11 (Bullseye) avec Nginx. La génération des certificats est réalisée par OpenSSL.
Pré-requis
J'utilise Proxmox pour déployer mon conteneur que j'ai nommé nginx.poc.tls
. J'ai également installé curl
et nginx
.
Sous Proxmox, le host étant identique au nom du conteneur, j'ai exécuté la commande curl http://nginx.poc.tls
pour vérifier que Nginx est bien installé et exécuté.
Le retour de cette commande est la suivante :
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
C'est parfait, le service Nginx est fonctionnel. Relançons la même commande, avec https
au lieu de http
, voici le résultat :
curl: (7) Failed to connect to nginx.poc.tls port 443: Connection refused
Avant de modifier les fichiers de configuration de Nginx pour lui indiquer qu'il faut écouter sur le port 443. Nous allons créer le certificat.
Certificat TLS
Le certificat sera créé par OpenSSL. Je vous invite à lancer la commande openssl version
pour vérifier qu'OpenSSL est bien installé.
Lien vers la documentation de la commande OpenSSL.
Création de l'autorité de certification
Pour cette première partie, nous allons utiliser 2 commandes openssl genpkey
et openssl req
.
Commençons par générer la clé de notre certificat d'autorité en lançant la commande suivante. une passphrase vous sera demandé lors de l'exécution :
openssl genpkey -algorithm RSA -aes-256-cbc -out ca-key.pem
La commande openssl genpkey
remplace openssl genrsa
. Nous lui indiquons que nous souhaitons générer une clé privée RSA avec l'aide de l'algorithme de chiffrement symétrique AES-256-CBC. Notre clé sera enregistrée dans le fichier ca-key.pem.
Nous allons ensuite générer un certificat public en exécutant la commande :
<!-- openssl req -new -x509 -days 180 -sha512 -key ca-key.pem -out ca.pem -->
Cette commande est composée de plusieurs options, voici quelques précisions à leur sujet :
-new
précise que la commande est une nouvelle demande.-x509
génère un certificat autosigné au lieu d'une demande de certificat.-days
permet de préciser la durée de vie du certificat, dans notre cas 180 jours, par défaut la valeur est de 30 jours.-sha512
spécifie comment signer la demande-key ca-key.pem
indique à la commande la clé à utiliser, soit la clé précédemment générée-out ca.pem
indiquer le fichier de sortie
Une fois lancée, la passphrase vous sera demandée et quelques questions vous serons posées. Les réponses aux questions seront présentes dans le certicat généré.
Voici les liens vers la documentation des 2 commandes utilisées :
Création du certificat
Nous aurons besoin d'exécuter 4 commandes pour créer notre certificat en commençant par la génération d'une nouvelle clé en réutilisant la commande openssl genpkey
avec les mêmes paramètres sauf que le fichier de sortie est différent.
Les noms des fichiers de certificat sont génériques, je vous invite à les modifier.
openssl genpkey -algorithm RSA -aes-256-cbc -out certificat-key.pem
Puis, nous allons générer une demande de signature de certificat, généralement appelé CSR pour Certificate Signing Request.
openssl req -new -sha512 -subj "/CN=nginx-poc-tls" -key certificat-key.pem -out certificat.csr
La commande est quasiment identique à celle permettant de générer un certificat public. L'option -subj "/CN=nginx-poc-ssl"
définit le sujet de notre nouvelle demande. Vous êtes libre d'indiquer ce que vous souhaitez.
Nous allons désormais créer un fichier de configuration qui stockera les informations DNS ainsi que l'adresse IP de notre certificat. Avant de lancer la commande, je vous invite à récupérer l'adresse IP de votre conteneur Nginx, en utilisant la commande ip a
.
echo "subjectAltName=DNS:nginx.poc.tls,IP:10.255.89.139" >> config-file.conf
La dernière étape consiste à créer le certificat à partir des différents fichiers que nous avons générés précédemment :
openssl x509 -req -sha512 -days 180 -in certificat.csr -CA ca.pem -CAkey ca-key.pem -out certificat.pem -extfile config-file.conf -CAcreateserial
Voici quelques précisions sur les options la commande openssl x509
:
-req
est utilisée pour indiquer que l'on va faire une demande de certificat-sha512
précise que l'on souhaite utiliser sha512 pour signer le certificat, par défaut sha1 est utilisé-days 180
indique le nombre de jours pour la validité du certifcat, par défaut la valeur est 30 jours-in certificat.csr
spécifie le fichier d'entrée-CA ca.pem
précise l'autorité de certificat qui sera utilisé pour la signature-CAkey ca-key.pem
préciser la clé de l'autorité de certificat-out certificat.pem
indique le nom du fichier du certificat que l'on souhaite générer-extfile config-file.conf
spécifie le fichier de configuration contenant les extensions à utiliser-CAcreateserial
indique que le numéro de série du certificat doit être créé
Lien vers la documentation de la commande openssl x509
Configuration de Nginx
Maintenant que nos certificats sont créés, nous allons configurer Nginx. Mais avant, nous allons copier les fichiers du certificat dans le dossier etc\ssl\
:
cp certificat.pem /etc/ssl/.
cp certificat-key.pem /etc/ssl/.
Avant de modifier la configuration de Nginx, nous devons créer un fichier contenant la passphrase du certificat, vous pouvez créer le dossier /etc/keys
ains que le fichier certificat.keys
:
mkdir /etc/keys
echo "<ma-passphrase>" > /etc/keys/certificat.keys
Désormais, nous allons pouvoir modifier la configuration de Nginx pour lui indiquer d'écouter sur le port 443 et d'activer les certificats que nous avons créés. Pour ce faire, nous allons éditer le vhost default
, qui se trouve dans le dossier /etc/nginx/sites-available
.
Ce fichier comporte 1 directive server
que nous allons modifier :
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
Nous allons modifier cette instruction en commentant les 2 lignes ci-dessous :
listen 80 default_server;
listen [::]:80 default_server;
Puis, nous décommettons les 2 ci-dessous :
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
Pour terminer, nous devons ajouter les lignes :
ssl_certificate /etc/ssl/certificat.pem;
ssl_certificate_key /etc/ssl/certificat-key.pem;
ssl_password_file /etc/keys/certificat.keys;
Quittons nano, puis réalisons un test de configuration de Nginx :
/usr/sbin/nginx -t
Si la configuration à été vérifiée avec succès, vous pouvez relancer Nginx :
/etc/init.d/nginx restart
Nous pouvons tester que Nginx répond bien sur le port 443 avec le certificat que nous avons créé, en lançant la commande :
curl -k https://nginx.poc.tls
L'option -k
ou --insecure
permet de passer en mode non sécurisé. Cela indique à Curl de ne pas vérifier le certificat. Cependant, nous souhaitons rester en mode sécurisé. Pour ce faire, nous devons installer l'autorité de certificat sur chaque conteneur, machine physique… qui devra avoir accès à notre conteneur Nginx.
Installation de l'autorité de certificat
Afin de ne plus avoir d'erreur de vérification du certificat, nous devons installer notre autorité de certificat dans notre système.
Commençons par créer un dossier nommé mon-ca-certificat
dans le dossier /usr/local/share/ca-certificates
. Le dossier ca-certificates
permet de stocker les autorités de certificat. Une fois le fichier ca.crt
copié dans le dossier que nous avons créé, nous allons pouvoir lancer la mise à jour de notre base de certificats :
cp ca.pem /usr/local/share/ca-certificates/mon-ca-certificat/ca.crt
/usr/sbin/update-ca-certificates
Le résultat de la dernière commande doit indiquer qu'un nouveau certificat à été ajouté :
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
Relancer la commande curl https://nginx.poc.tls
Le retour de cette commande est la suivante :
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>