Le principe est de gérer un seul certificat SSL pouvant être présenté par le reverse proxy pour l'ensemble des web services tournant localement. C'est ce que permet de faire le certificat SAN contenant un champ Subject Alternate Name pouvant contenir une liste de FQDN utilisée à la place du champ Common Name voir le wiki
Après plusieurs essais il ressort que:
De ce que j'ai pu déduire le caractère générique (étoile ou wilcard) ne peut s'appliquer que sur un FQDN pour désigner les serveurs ou les sous-domaines mais pas les domaines et les TLDs.
Pour rappel le FQDN est formaté ainsi: server.subdomain.domain.tld.
Notons également que c'est en général une mauvaise idée de travailler directement avec .localhost ou avec un TLD:
http://localhost
les services peuvent alors produire des erreurs ou se comporter différemment en local;Ci-dessous pour rappel les manipulations faites avec un certificat de test
# Affiche la valeur du champ SAN (Subject Alternate Name) openssl x509 -noout -text -in service.localhost.crt | grep -i -A 1 "Subject Alternative Name" X509v3 Subject Alternative Name: IP Address:127.0.0.1, DNS:localhost, DNS:service.localhost, DNS:*.service.localhost, DNS:any, DNS:*.any
Comme on peut le voir ci-dessus, le champ SAN contient une adresse IP 127.0.0.1, si on contacte le serveur qui a cette même IP tout se passe bien:
curl -v --cacert ca-chain.cert.pem https://127.0.0.1 ... * subjectAltName: host "127.0.0.1" matched cert's IP address!
Le champ SAN contient deux noms localhost et any, ici encore tout se passe bien:
curl -v --cacert ca-chain.cert.pem https://localhost ... * subjectAltName: host "localhost" matched cert's "localhost"
C'est pour les valeurs *.any et *.localhost du certificat que le résultat obtenu est différent de celui attendu. Le caractère générique devrait nous permettre d'utiliser un nom de la forme traefik.any ou traefik.localhost. Cependant on obtient une erreur:
curl -v --cacert ca-chain.cert.pem https://traefik.any ... * subjectAltName does not match traefik.any * SSL: no alternative certificate subject name matches target host name 'traefik.any' * Closing connection 0 * TLSv1.3 (OUT), TLS alert, close notify (256): curl: (60) SSL: no alternative certificate subject name matches target host name 'traefik.any' More details here: https://curl.haxx.se/docs/sslcerts.html
Cette erreur ne se manifeste plus au niveau inférieur avec *.service.localhost
curl -v --cacert ca-chain.cert.pem https://traefik.service.localhost ... * subjectAltName: host "traefik.service.localhost" matched cert's "*.service.localhost"
Pour ces raisons, il est préférable de générer un certificat SAN avec des FQDN ( c'est à dire des noms de domaine de troisième niveau comme *.something.tld
.
En utilisant .localhost en TLD on évite tout risque collision (La RFC 2606 le définit comme l'un des quatre domaines de premier niveau réservé). Aucun sous-domaines réels dans le système de nom de domaine (Domain Name System) d'Internet ne peut être construit en dessous. Un nom d'un domaine de premier niveau réservé n'est pas inclus dans les serveurs racines du DNS.
Pour que le nom de domaine évoque bien que l'hébergement de services locaux j'ai fait le choix d'utiliser *.services.localhost
# Depuis le répertoire de l'autorité de certification intermédiaire cd intermediate_ca/ export dn=localhost # Création de la clé privée openssl genrsa -out private/$dn.key 2048 chmod 400 private/$dn.key # Création de la CSR openssl req -new -config CSR.cnf -key private/$dn.key -out csr/$dn.csr
Préparer le fichier des extensions X509 en complétant la section [alt_names]
avec les FQDN
# Création du certificat openssl x509 -req -extfile build_cert_with_SAN.ext -days 30 -in csr/$dn.csr -CA certs/intermediate_ca.cert.pem -CAkey private/intermediate_ca.key -CAcreateserial -out certs_x509/$dn.crt # effacer la variable unset $dn
# via cURL curl --verbose --cacert ca-chain.cert.pem https://server.domain # via openssl true | openssl s_client -showcerts -CAfile ca-chain.cert.pem traefik.labinfo.mairie.local:443 2>/dev/null | openssl x509 -noout -text
Dans l' exemple ci-dessus le certificat de l'autorité de confiance n'est pas installé sur le système, les options --cacert pour curl et -CAfile pour openssl permettent de fournir les certificats des autorités de confiance afin de valider la chaîne de certification dans sa globalité.
Voir le wiki installer le certificat racine d'une autorité de confiance.