gege_go

Les certificats Wildcard avec Let's Encrypt sont très récents, donc c'est un peu comme de la BETA. Une utilisation professionnelle d'un certificat Wildcard avec Let's Encrypt n'est pas forcément recommandé même si ça fonctionne. Pour du personnel, aucun problème.

J'utilise un certificat Wildcard avec LE, pas besoin d'intervenir tout les X temps pour renouveler ça se fait tout seul à condition d'avoir son registry géré par acme.sh.
En l'occurrence, j'utilise OVH et c'est niquel https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api

D'accord, donc le certificat wildcard reste le plus facile d'utilisation.
Mais sans intervention tous les X temps, comment fait ton pour régénérer automatiquement le certificat sans passer par le cas si-dessous?

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.mondomain.fr with the following value:

RnV4KvuoD2sLPqnmo879B6GlVlM7tLfuX8eipajVo4g

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue

Personnellement j'utilise acme.sh , c'est un script github qui permet d'avoir un renouvellement automatiquement de ton certificat wildcard en poussant un champ txt vers un serveur DNS. Il est même compatible avec les api de OVH et gandi.

Bref depuis je n'utilise plus letsencrypt, et tout fonctionne sans root et sans dépendances 😎

oki, merci pour votre aide.
Juste une dernière question 😋
Serait-il possible d'avoir un petit tuto car j'utilise let's Encrypt et je voudrais rester dessus 😅

    gege_go

    Non, ce n'est pas possible de te faire un tuto.
    Je connais que le client acme.sh pour générer/renouveler automatiquement un certificat Wildcard.

    Ton nom de domaine est géré par quel registry ?

      Let's Encrypt (abrégé LE) est une autorité de certification.

      Tu as ensuite plusieurs clients ACME, certbot (le plus connu) ne gère pas les Wildcards en "automatique".
      D'autres comme acme.sh le font, grâce aux API des fournisseurs de domaines.

      Rathorian
      Mon domaine est géré par OVH

      ok, j'utilise certbot, c'est pour cela que ça ne fonctionne pas.
      Je vais donc passer sur acme.sh, mais y aurai-t-il possibilité de me renvoyer sur un tuto svp?

      En exécutant l'installation d'une wildcard pour mon serveur, un message d'erreur s'affiche et je ne trouve pas de réponse sur internet:

      [root@ns372331 xadmin]# acme.sh --renew -d mondomain.fr -d *.mondomain.fr  --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please
      [ven. juin 15 16:02:14 CEST 2018] Renew: 'mondomain.fr'
      [ven. juin 15 16:02:14 CEST 2018] Multi domain='DNS:mondomain.fr,DNS:*.mondomain.fr'
      [ven. juin 15 16:02:14 CEST 2018] Getting domain auth token for each domain
      [ven. juin 15 16:02:14 CEST 2018] Verifying:mondomain.fr
      [ven. juin 15 16:02:15 CEST 2018] mondomain.fr:Challenge error: {"type":"urn:ietf:params:acme:error:malformed","detail":"Unable to update challenge :: The challenge is not pending.","status": 400}
      [ven. juin 15 16:02:15 CEST 2018] Please add '--debug' or '--log' to check more details.
      [ven. juin 15 16:02:15 CEST 2018] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
      [ven. juin 15 16:02:16 CEST 2018] The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
      

      Je n'arrive pas a trouver de réponse ni même d'ou vient l'erreur,
      Puis-je avoir une petite aide? 😅

      Plop, pour les détails :

      [ven. juin 15 16:02:15 CEST 2018] Please add '--debug' or '--log' to check more details.

      😉

        [root@ns372331 xadmin]# acme.sh --renew -d mondomain.fr -d *.mondomain.fr  --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please --debug
        [lun. juin 18 10:06:41 CEST 2018] Lets find script dir.
        [lun. juin 18 10:06:41 CEST 2018] _SCRIPT_='/root/.acme.sh/acme.sh'
        [lun. juin 18 10:06:41 CEST 2018] _script='/root/.acme.sh/acme.sh'
        [lun. juin 18 10:06:41 CEST 2018] _script_home='/root/.acme.sh'
        [lun. juin 18 10:06:41 CEST 2018] Using config home:/root/.acme.sh
        https://github.com/Neilpang/acme.sh
        v2.7.9
        [lun. juin 18 10:06:41 CEST 2018] Using config home:/root/.acme.sh
        [lun. juin 18 10:06:41 CEST 2018] ACME_DIRECTORY='https://acme-v02.api.letsencrypt.org/directory'
        [lun. juin 18 10:06:41 CEST 2018] DOMAIN_PATH='/root/.acme.sh/mondomain.fr'
        [lun. juin 18 10:06:41 CEST 2018] Renew: 'mondomain.fr'
        [lun. juin 18 10:06:41 CEST 2018] Le_API='https://acme-v02.api.letsencrypt.org/directory'
        [lun. juin 18 10:06:41 CEST 2018] Using config home:/root/.acme.sh
        [lun. juin 18 10:06:41 CEST 2018] ACME_DIRECTORY='https://acme-v02.api.letsencrypt.org/directory'
        [lun. juin 18 10:06:41 CEST 2018] _main_domain='mondomain.fr'
        [lun. juin 18 10:06:41 CEST 2018] _alt_domains='*.mondomain.fr'
        [lun. juin 18 10:06:41 CEST 2018] Using ACME_DIRECTORY: https://acme-v02.api.letsencrypt.org/directory
        [lun. juin 18 10:06:41 CEST 2018] _init api for server: https://acme-v02.api.letsencrypt.org/directory
        [lun. juin 18 10:06:41 CEST 2018] GET
        [lun. juin 18 10:06:41 CEST 2018] url='https://acme-v02.api.letsencrypt.org/directory'
        [lun. juin 18 10:06:41 CEST 2018] timeout=
        [lun. juin 18 10:06:41 CEST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
        [lun. juin 18 10:06:42 CEST 2018] ret='0'
        [lun. juin 18 10:06:42 CEST 2018] ACME_KEY_CHANGE='https://acme-v02.api.letsencrypt.org/acme/key-change'
        [lun. juin 18 10:06:42 CEST 2018] ACME_NEW_AUTHZ
        [lun. juin 18 10:06:42 CEST 2018] ACME_NEW_ORDER='https://acme-v02.api.letsencrypt.org/acme/new-order'
        [lun. juin 18 10:06:42 CEST 2018] ACME_NEW_ACCOUNT='https://acme-v02.api.letsencrypt.org/acme/new-acct'
        [lun. juin 18 10:06:42 CEST 2018] ACME_REVOKE_CERT='https://acme-v02.api.letsencrypt.org/acme/revoke-cert'
        [lun. juin 18 10:06:42 CEST 2018] ACME_AGREEMENT='https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf'
        [lun. juin 18 10:06:42 CEST 2018] ACME_NEW_NONCE='https://acme-v02.api.letsencrypt.org/acme/new-nonce'
        [lun. juin 18 10:06:42 CEST 2018] ACME_VERSION='2'
        [lun. juin 18 10:06:42 CEST 2018] Le_NextRenewTime
        [lun. juin 18 10:06:42 CEST 2018] _on_before_issue
        [lun. juin 18 10:06:42 CEST 2018] _chk_main_domain='mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] _chk_alt_domains='*.mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] Le_LocalAddress
        [lun. juin 18 10:06:42 CEST 2018] d='mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] Check for domain='mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] _currentRoot='dns'
        [lun. juin 18 10:06:42 CEST 2018] d='*.mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] Check for domain='*.mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] _currentRoot='dns'
        [lun. juin 18 10:06:42 CEST 2018] d
        [lun. juin 18 10:06:42 CEST 2018] _saved_account_key_hash is not changed, skip register account.
        [lun. juin 18 10:06:42 CEST 2018] Read key length:
        [lun. juin 18 10:06:42 CEST 2018] _createcsr
        [lun. juin 18 10:06:42 CEST 2018] Multi domain='DNS:mondomain.fr,DNS:*.mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] Getting domain auth token for each domain
        [lun. juin 18 10:06:42 CEST 2018] ok, let's start to verify
        [lun. juin 18 10:06:42 CEST 2018] Verifying:mondomain.fr
        [lun. juin 18 10:06:42 CEST 2018] d='mondomain.fr'
        [lun. juin 18 10:06:42 CEST 2018] keyauthorization='w2X4L7vL4bk_W9c65FHYJD0fZGoQe3O8WFOh6cdaR24.agumNnwu76rYDLM8vzlwZ8usRfIYHvBzCBV1hGE0xMw'
        [lun. juin 18 10:06:42 CEST 2018] uri='https://acme-v02.api.letsencrypt.org/acme/challenge/EIX7ocQ9aI8qOf5I22TMj76_UXCj4fEKKXB5NuJ9fY8/5130426156'
        [lun. juin 18 10:06:42 CEST 2018] _currentRoot='dns'
        [lun. juin 18 10:06:42 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/EIX7ocQ9aI8qOf5I22TMj76_UXCj4fEKKXB5NuJ9fY8/5130426156'
        [lun. juin 18 10:06:42 CEST 2018] payload='{"keyAuthorization": "w2X4L7vL4bk_W9c65FHYJD0fZGoQe3O8WFOh6cdaR24.agumNnwu76rYDLM8vzlwZ8usRfIYHvBzCBV1hGE0xMw"}'
        [lun. juin 18 10:06:42 CEST 2018] RSA key
        [lun. juin 18 10:06:42 CEST 2018] HEAD
        [lun. juin 18 10:06:42 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/new-nonce'
        [lun. juin 18 10:06:42 CEST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
        [lun. juin 18 10:06:42 CEST 2018] _ret='0'
        [lun. juin 18 10:06:42 CEST 2018] POST
        [lun. juin 18 10:06:42 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/challenge/EIX7ocQ9aI8qOf5I22TMj76_UXCj4fEKKXB5NuJ9fY8/5130426156'
        [lun. juin 18 10:06:42 CEST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
        [lun. juin 18 10:06:43 CEST 2018] _ret='0'
        [lun. juin 18 10:06:43 CEST 2018] code='400'
        [lun. juin 18 10:06:43 CEST 2018] mondomain.fr:Challenge error: {"type":"urn:ietf:params:acme:error:malformed","detail":"Unable to update challenge :: The challenge is not pending.","status": 400}
        [lun. juin 18 10:06:43 CEST 2018] Skip for removelevel:
        [lun. juin 18 10:06:43 CEST 2018] pid
        [lun. juin 18 10:06:43 CEST 2018] No need to restore nginx, skip.
        [lun. juin 18 10:06:43 CEST 2018] _clearupdns
        [lun. juin 18 10:06:43 CEST 2018] skip dns.
        [lun. juin 18 10:06:43 CEST 2018] _on_issue_err
        [lun. juin 18 10:06:43 CEST 2018] Please add '--debug' or '--log' to check more details.
        [lun. juin 18 10:06:43 CEST 2018] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
        [lun. juin 18 10:06:43 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/EIX7ocQ9aI8qOf5I22TMj76_UXCj4fEKKXB5NuJ9fY8/5130426156'
        [lun. juin 18 10:06:43 CEST 2018] payload='{"keyAuthorization": "w2X4L7vL4bk_W9c65FHYJD0fZGoQe3O8WFOh6cdaR24.agumNnwu76rYDLM8vzlwZ8usRfIYHvBzCBV1hGE0xMw"}'
        [lun. juin 18 10:06:43 CEST 2018] POST
        [lun. juin 18 10:06:43 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/challenge/EIX7ocQ9aI8qOf5I22TMj76_UXCj4fEKKXB5NuJ9fY8/5130426156'
        [lun. juin 18 10:06:43 CEST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
        [lun. juin 18 10:06:43 CEST 2018] _ret='0'
        [lun. juin 18 10:06:43 CEST 2018] code='400'
        [lun. juin 18 10:06:43 CEST 2018] url='https://acme-v02.api.letsencrypt.org/acme/challenge/0jcPh5_Rse3dIJpGThObvtZ3QQUOgbTpvxrBDBZRvXQ/5130426154'
        [lun. juin 18 10:06:43 CEST 2018] payload='{"keyAuthorization": "Hh77xu0KTwdt74LvGebjJU5U_TMecZ0y9jap4_3gURE.agumNnwu76rYDLM8vzlwZ8usRfIYHvBzCBV1hGE0xMw"}'
        [lun. juin 18 10:06:43 CEST 2018] POST
        [lun. juin 18 10:06:43 CEST 2018] _post_url='https://acme-v02.api.letsencrypt.org/acme/challenge/0jcPh5_Rse3dIJpGThObvtZ3QQUOgbTpvxrBDBZRvXQ/5130426154'
        [lun. juin 18 10:06:43 CEST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header  -g '
        [lun. juin 18 10:06:43 CEST 2018] _ret='0'
        [lun. juin 18 10:06:43 CEST 2018] code='400'
        [lun. juin 18 10:06:43 CEST 2018] The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
        

        voila, désoler du retard Aerya 😅

          Bonjour à tous

          J'utilise le serveur DNS autoritaire avec NSD/DNSSEC via Docker de Hardware, et dans le fichier de zone figure mes enregistrement DANE/TLSA.

          Mes certificats arrivant à expiration je me pose les questions suivantes. Bien que mon registrar soit Gandi, mon fichier zone est en local sur mon serveur, du coup, me semble t-il je ne peux pas utiliser l'api Gandi pour l'insertion de l'enregistrement TXT, enfin je crois 😟

          Dans ces conditions est ce que l'implantation du wildcard en renouvellement est possible ? Par ailleurs et j'en profite pour vous demander si avez vous un script pour renouveler les enregistrement TLSA lorsque les certificats letsencrypt sont renouvelés et enfin @Hardware parle dans son github de mettre en place un cron pour incrémenter le numéro de série du fichier de zone et pour la signature DNSSEC qui doit être effectuées tous les mois. Quelle commande cron pourrait être adaptée ?

          https://github.com/hardware/nsd-dnssec

          Merci

            laster13 Pour le script je dois avoir ça sous la main mais c'est dans un de mes anciens backups...

            Après c'est pas compliqué à faire .
            Pour ce qui est d'incrémenter le numéro de série c'est à coups de sed et compagnie une fois que t'as extrait le numéro de la zone. Ensuite tu script pour faire en sorte de récupérer l'empreinte du certificat et tu remplaces l'ancien enregistrement (moi je me cassais pas la tête je récupérais l'empreinte de l'ancien certificat puis je faisais un bon vieux sed). En tous cas je l'avais bricolé comme ça et ça fonctionnait, maintenant que j'utilise traefik qui gère aussi mes certificats je dois un peu modifier mon truc.

            L'entrée cron était sur l'hôte, de toute façon la seule commande Docker à faire était le signzone à la fin. Je pourrais songer à PR (ou laisser faire Hardware) pour que ce soit intégré mais en tout cas c'est faisable comme cela.

              10 jours plus tard

              laster13

              Pour mondedie.fr, j'ai organisé le renouvellement de la manière suivante (à noter que dans notre cas, le serveur web et le serveur mail ne sont pas hébergés sur la même machine, donc j'ai du utiliser rsync et ssh) :

              acme.sh \
               --issue \
               -w /mnt/docker/nginx/www/acme \
               -k 4096 \
               -d mondedie.fr \
               -d www.mondedie.fr \
               ...
              
              acme.sh \
               --install-cert   -d mondedie.fr \
               --cert-file      /mnt/docker/nginx/ssl/live/mondedie.fr/cert.pem \
               --key-file       /mnt/docker/nginx/ssl/live/mondedie.fr/privkey.pem \
               --ca-file        /mnt/docker/nginx/ssl/live/mondedie.fr/chain.pem \
               --fullchain-file /mnt/docker/nginx/ssl/live/mondedie.fr/fullchain.pem \
               --reloadcmd      "docker-compose -f /docker/docker-compose.yml restart nginx && /usr/local/bin/update-mail-tlsa"
              #!/bin/bash
              # /usr/local/bin/update-mail-tlsa sur mondedie-web
              
              DOMAIN="mondedie.fr"
              LETS_ENCRYPT_LIVE_PATH="/mnt/docker/nginx/ssl/live/${DOMAIN}"
              SLACK_HOOK=https://hooks.slack.com/services/xxxxxxxx/xxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxx
              
              # Empreinte du certificat récupérée lors du renouvellement
              # par acme.sh à partir de mondedie-web
              fingerprint=$(openssl x509 -noout -in "${LETS_ENCRYPT_LIVE_PATH}/cert.pem" -fingerprint -sha256 | cut -c 20- | sed s/://g)
              
              # Mise à jour des certificats du serveur mail
              # Seul l'@IP de mondedie-web est autorisée à se connecter avec une clé SSH via l'utilisateur root sur mondedie-mail
              rsync -Lvr "${LETS_ENCRYPT_LIVE_PATH}/" root@mondedie-mail.lan:"/mnt/docker/ssl/letsencrypt/live/mail.${DOMAIN}"
              
              # Redémarrage du serveur mail suite au renouvellement des certificats
              ssh root@mondedie-mail.lan docker-compose -f /docker/docker-compose.yml restart mailserver
              
              # Mise à jour de l'enregistrement TLSA
              ssh root@mondedie-mail.lan update-tlsa ${fingerprint,,}
              
              curl --silent -X POST --data-urlencode 'payload={"channel":"#mondedie-flarum", "username":"acme-bot","text":"Le certificat SSL a été renouvelé sur mondedie-web et mondedie-mail. Les conteneurs nginx et mailserver ont été redémarrés automatiquement.","icon_emoji":":infomation_source:"}' $SLACK_HOOK >/dev/null 2>&1
              #!/bin/bash
              # /usr/local/bin/update-tlsa sur mondedie-mail
              
              SLACK_HOOK=https://hooks.slack.com/services/xxxxxxxx/xxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxx
              
              # Empreinte du certificat récupérée lors du renouvellement
              # par acme.sh à partir de mondedie-web
              fingerprint=$1
              
              domain="mondedie.fr"
              zonename="db.${domain}"
              zonefile="/mnt/docker/nsd/zones/${zonename}"
              serial=$(date -d "+1 day" +'%Y%m%d%H')
              tlsa_line_number=$(grep -n TLSA $zonefile | cut -d : -f 1)
              tlsa_dns_record="_dane IN TLSA 3 0 1 ${fingerprint}"
              expiration_date=$(date -d "+6 months" +'%Y%m%d%H%M%S')
              
              # Mise à jour de la zone DNS avec un nouveau
              # serial et un nouvel enregistrement TLSA
              sed -i -e "s/20[0-9][0-9]\{7\} ; Serial/${serial} ; Serial/g" \
                     -e "${tlsa_line_number}s/.*/${tlsa_dns_record}/" $zonefile
              
              # On vérifie que la zone est valide avant de la signer
              if docker exec nsd nsd-checkzone "$domain" /zones/"$zonename" | grep -q 'zone mondedie.fr is ok'; then
                echo "Execution de la commande : docker exec nsd signzone ${domain} ${expiration_date}"
                docker exec nsd signzone "$domain" "$expiration_date"
                curl --silent -X POST --data-urlencode 'payload={"channel":"#mondedie-flarum", "username":"acme-bot","text":"La zone DNS a été mise à jour et signée avec DNSSEC. Merci de vérifier la conformité 10 minutes après la notification avec : http://dnsviz.net/d/mondedie.fr/analyze/ et https://dnssec-debugger.verisignlabs.com/mondedie.fr","icon_emoji":":infomation_source:"}' $SLACK_HOOK >/dev/null 2>&1
                curl --silent -X POST --data-urlencode 'payload={"channel":"#mondedie-flarum", "username":"acme-bot","text":"'"zonefile=$zonefile, expiration_date=$expiration_date, serial=$serial, tlsa_dns_record=$tlsa_dns_record, tlsa_line_number=$tlsa_line_number"'","icon_emoji":":infomation_source:"}' $SLACK_HOOK >/dev/null 2>&1
              else
                echo "La zone ${zonefile} n'est pas valide !"
                curl --silent -X POST --data-urlencode 'payload={"channel":"#mondedie-flarum", "username":"acme-bot","text":"Une erreur est survenue pendant la mise à jour de la zone DNS. Merci de vérifier la conformité avec la commande suivante : docker exec nsd nsd-checkzone '"$domain"' /zones/'"$zonename"'","icon_emoji":":rotating_light:"}' $SLACK_HOOK >/dev/null 2>&1
              fi

              Et ne pas oublier de mettre ceci dans chaque vhost nginx ayant un sous-domaine renouvelé automatiquement :

              location ~ /\.well-known/acme-challenge {
                root /nginx/www/acme; # à modifier selon votre configuration
                allow all;
              }

              Je l'avais pas posté avant sur le forum parce que je l'avais pas suffisamment testé, j'étais sûr de moi à 95% 😃 Mais aujourd'hui le renouvellement a eu lieu et il n'y a eu aucun problème.

                A noter que j'ai mis le serial de la zone DNS à J+1 serial=$(date -d "+1 day" +'%Y%m%d%H') lors du renouvellement pour éviter un décrémentation invonlontaire si quelqu'un modifie la zone au même moment. Normalement ça devrait pas arriver parce que j'ai mis l'heure au format 24 heures dans le serial, mais bon, on est jamais trop prudent 😃

                laster13 tient moi au courant 😉