Traefik 2.0 VS wildcard certificates

Let’s encrypt permet de délivrer des certificats suivant différentes méthodes, la plus intéressante (mais aussi la plus “complexe”) est la méthode dns-01 car elle permet d’obtenir des certificats wildcard.

L’objectif est de construire une architecture qui permette d’intercepter toutes les requêtes de la forme *.monsite.fr et de les rediriger vers un serveur, le schéma de principe est le suivant :

alt text

Dans mon cas, l’hébergeur de la zone est OVH (qui fournit une API pour effectuer différentes actions d’administration).

Création d’une clé d’API sous OVH (https://eu.api.ovh.com/createApp/)

alt text

On obtient en retour un tuple Application Key / Application Secret

alt text

On peut valider sur https://api.ovh.com/console/

alt text

A noter que pour révoquer le token d’une application on pourra utiliser cette console avec la méthode : https://api.ovh.com/console/#/me/api/application/%7BapplicationId%7D#DELETE

alt text

On donne les droits nécessaires à notre application pour intervenir sur la zone DNS.

curl -XPOST -H "X-Ovh-Application: {ApplicationKey}" -H "Content-type: application/json" \
https://eu.api.ovh.com/1.0/auth/credential \
-d '{ "accessRules":[{"method":"POST","path":"/domain/zone/{Domain}/record"}, \
{"method":"POST","path":"/domain/zone/{Domain}/refresh"}, \
{"method":"DELETE","path":"/domain/zone/{Domain}/record/*"} ], \
"redirection": "https://www.{Domain}.fr" }'

La page de redirection est arbitraire, c’est la page vers laquelle nous serons redirigés après validation. En retour on obtient une URL pour valider la demande :

{"consumerKey":"xXxXxXxXxXxXxXxX","state":"pendingValidation", \
"validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=xXxXxXxXxXxXxXxXxXxX"}

Normalement on doit pouvoir utiliser l’email ou l’id ovh (xx00000-ovh) pour ma part avec l’email j’ai reçu une erreur …

alt text

On est ensuite redirigé vers la page déclarée dans la demande.

Dans le docker-compose on déclare les paramètres d’identification de notre clé API

        environment:
            - "OVH_ENDPOINT=ovh-eu"
            - "OVH_APPLICATION_KEY=xXxXxXxXxXxXxXxXxXxXxXxX"
            - "OVH_APPLICATION_SECRET=xXxXxXxXxXxXxXxXxXxXxXxX"
            - "OVH_CONSUMER_KEY=xXxXxXxXxXxXxXxXxXxXxXxX"

On définit la méthode de challenge dans le fichier de configuration de traefik :

certificatesResolvers:
  http:
    acme:
      email: contact@redteams.fr
      storage: /acme.json
      dnsChallenge:
        provider : ovh
        delayBeforeCheck : 10

Le catch-all est défini dans les labels afin de renvoyer au bon service

      labels:
            - "traefik.enable=true"
            - "traefik.http.routers.catchAll.entrypoints=http"
            - "traefik.http.routers.catchAll.rule=HostRegexp(`{any:.*}`)"
            - "traefik.http.routers.catchAll.priority=1"
            - "traefik.http.routers.catchAll.middlewares=SecuredChain@file"
            - "traefik.http.routers.catchAll-secure.entrypoints=https"
            - "traefik.http.routers.catchAll-secure.middlewares=SecuredChain@file"
            - "traefik.http.routers.catchAll-secure.tls=true"
            - "traefik.http.routers.catchAll-secure.tls.options=hardening@file"
            - "traefik.http.routers.catchAll-secure.tls.certresolver=http"
            - "traefik.http.services.catchAll.loadbalancer.server.port=80"
            - "traefik.http.routers.catchAll-secure.rule=HostRegexp(`{any:.*}`)"
            - "traefik.http.routers.catchAll-secure.priority=1"
            - "traefik.http.routers.catchAll-secure.tls.domains[0].main=redteams.fr"
            - "traefik.http.routers.catchAll-secure.tls.domains[0].sans=*.redteams.fr"

A la consultation d’un sous-domaine de reteams.fr, le navigateur nous confirme qu’il s’agit d’un certificat wildcard:

alt text

Une nouvelle entrée TXT a été créée dans la zone :

alt text

Le type CAA une mesure de sécurité supplémentaire qui permet de déclarer l’autorité qui a le droit de délivrer des certificats pour ce domaine.

Pour aller plus loin sur les différents types de challenge pris en charge par lets encrypt : https://letsencrypt.org/fr/docs/challenge-types

Related