Développement local en HTTPS avec nginx et Docker

Dans certains cas, il peut être nécessaire d’utiliser une connexion https même lors du développement pour pouvoir utiliser certaines librairies ou standards (U2F, plateformes de paiement, etc.).

Cet article est donc un petit aide mémoire sur les opérations à mettre en œuvre pour générer une autorité de certification locale, un certificat et les utiliser ensuite localement lors du développement.

Créer les nouveaux répertoires

Dans le répertoire principal de l’app, créer deux nouveaux répertoires :

  • certs/ (qui contiendra l’autorité de certification locale et le certificat générés)
  • nginx/ (qui contiendra la nouvelle configuration nginx)

Générer le certificat auto-signé

Le script bash ci-dessous va nous permettre de générer une autorité de certification locale et un certificat issu de cette autorité de certification.

#!/usr/bin/env bash
set -eu
org=localhost-ca
domain=monapp.local

openssl genpkey -algorithm RSA -out ca.key
openssl req -sha256 -new -x509 -key ca.key -out ca.crt \
    -days 3650 -subj "/CN=$org/O=$org"

openssl genpkey -algorithm RSA -out "$domain".key
openssl req -sha256 -new -key "$domain".key -out "$domain".csr \
    -subj "/CN=$domain/O=$org"

openssl x509 -sha256 -req -in "$domain".csr -days 365 -out "$domain".crt \
    -CA ca.crt -CAkey ca.key -CAcreateserial \
    -extfile <(cat <<END
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName = DNS:$domain
END
    )

Vous pouvez l’enregistrer dans le répertoire certs/ créé précédemment et l’utiliser pour générer votre autorité de certification locale et le certificat.

N’oubliez pas de changer la variable domain par le nom de domaine local que vous souhaitez utiliser.

Créer la nouvelle configuration nginx.conf

Dans le répertoire nginx/ que nous avons créé précédemment, nous allons créer le fichier nginx.conf suivant qui servira à remplacer la configuration initale de l’image docker.

server {
    listen   443 ssl;

    root /var/www/html/webroot;
    index index.php index.html;

    ssl on;
    ssl_certificate     /etc/nginx/ssl/monapp.local.crt;
    ssl_certificate_key /etc/nginx/ssl/monapp.local.key;

    sendfile off;
    client_max_body_size 10M;

    charset utf-8;

    location ~* ^/_config {
        deny all;
        return 404;
    }

    location ~ (\.yml) {
        return 404;
    }

    location / {
        try_files $uri /index.php?$args;
    }

    error_page 500 502 503 504 /index.php;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SERVER_NAME $host;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ /\.ht {
        deny all;
    }
}

Prêtez attention à bien renseigner le nom de fichier correct pour le certificat et la clé privée car ils correspondent au nom de domaine que vous avez choisi lors de la génération de votre certificat (variable domain).

Ici, on écoute donc désormais sur le port 443 au lieu du 80.

On ajoute bien évidemment le certificat et la clé privée à la config et on active SSL.

Modifier le fichier docker-compose.yml

On modifie le service nginx dans notre fichier docker-compose.yml

Voilà à quoi ressemblait le fichier à l’origine pour mon service nginx :

version: '3'

services:
  nginx:
    image: opencomp/nginx
    ports:
      - "80:80"
    depends_on:
      - php
    volumes:
      - ./:/var/www/html:delegated

Désormais,

version: '3'

services:
  nginx:
    image: opencomp/nginx
    ports:
      - "443:443"
    depends_on:
      - php
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./certs:/etc/nginx/ssl
      - ./:/var/www/html:delegated

Nous ajoutons donc deux volumes Docker pour brancher dans notre container notre nouvelle configuration nginx et le certificat généré précédemment.

On change également le port mapping de « 80:80 » vers « 443:443« .

Ajouter l’autorité de certification générée comme autorité de certification de confiance dans son navigateur.

Firefox

  • Ouvrez les préférences de Firefox (Édition > Préférences)
  • Cliquez sur Vie privée & sécurité, dans la colonne de gauche.
  • Défilez jusqu’à la sous rubrique Certificats de la rubrique Sécurité.
  • Cliquez sur le bouton Afficher les certificats…
  • Dans la boîte de dialogue Gestionnaire de certificats, sélectionnez l’onglet Autorités.
L’onglet Autorités du gestionnaire de certificats de Firefox
  • Cliquez sur le bouton Importer…
  • Choisissez le fichier ca.crt généré dans le répertoire certs/
Confirmez l’autorité de certification pour identifier les sites web.

Chromium/Chrome

  • Depuis le menu trois points, cliquez sur Paramètres.
  • Cliquez sur Paramètres avancés (en bas de la page).
  • Dans la rubrique Confidentialité et sécurité, cliquez sur Gérer les certificats.
  • Sélectionnez l’onglet Autorités.
L’onglet Autorités dans le gestionnaire de Chromium/Chrome
  • Cliquez sur Importer.
  • Choisissez le fichier ca.crt généré dans le répertoire certs/
Confirmez l’autorité de certification pour identifier les sites web.

Alternativement, utilisez le magasin d’autorités de certification de confiance de votre système.

L’intérêt de cette méthode, c’est que l’ensemble des navigateurs de votre machine reconnaîtront automatiquement l’autorité de certification locale sans avoir besoin de l’ajouter manuellement dans le gestionnaire de certificats de chaque navigateur.


Par exemple, sous Archlinux :

sudo trust anchor ca.crt 
sudo trust extract-compat
sudo update-ca-trust

Ceci va avoir pour effet d’ajouter notre autorité de certification à la base de confiance du système. N’oubliez pas de redémarrer vos navigateurs pour prendre en compte les modifications.

Sous macOS, le certificat ca.crt est à ajouter au trousseau Système en utilisant l’application Trousseau d’accès.

Ajouter le nom de domaine au fichier /etc/hosts

Éditez le fichier /etc/hosts et ajoutez-y la ligne

127.0.0.1     monapp.local

(Re)démarrer les conteneurs Docker et le navigateur

Si votre pile docker était démarrée, n’oubliez pas de la redémarrer (docker-compose stop suivi d’un docker-compose up) pour prendre en compte la nouvelle configuration.

Si vous avez tout suivi correctement, si vous essayez d’accéder à https://monapp.local, vous ne devriez pas rencontrer d’avertissement lié au certificat et il sera marqué comme étant vérifié par localhost-ca.

A propos Jean Traullé

Passionné par l'informatique et les nouvelles technos, miagiste, papa de opencomp.fr, #sysadm, #ProxmoxVE, #Docker, #TYPO3, #CakePHP enthousiaste 😊
Ce contenu a été publié dans Non classé, avec comme mot(s)-clé(s) , , , , , , . Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *