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 😉

                  Hardware Je te tiens au courant, par contre je vois que tu utilises du SAN plutôt que du Wildcard. Une raison particulière pour ce choix ?

                  Je m'étais pas penché sur la méthode de renouvellement d'un certificat wildcard avec mon conteneur NSD, donc c'est pour ça que je suis resté sur un SAN. Ensuite j'ai vu ton tuto ^^

                  Pour le moment, je laisse comme ça, j'ai pas vraiment d'utilité à mettre un wildcard sur mondedie.fr.

                  Pas mal le script.
                  Moi j'utilisais ça, mais pas avec acme.sh :

                  f_check_certs() {
                      cd /etc/letsencrypt/live
                  
                      for domain in `find * -type d`; do
                          FULLCHAINFILE=/etc/letsencrypt/live/${domain}/fullchain.pem
                          openssl x509 -checkend 864000 -noout -in "${FULLCHAINFILE}" &>/dev/null
                  
                          if [ $? == 0 ]; then
                              f_log INF "Certificate for ${domain} is good for another 10 days!"
                          else
                              f_log INF "Time to renew ${domain}!"
                  
                              f_log INF "Downloading cerbot image..."
                              docker pull certbot/certbot &>/dev/null
                  
                              f_log INF "Stopping nginx..."
                              service nginx stop &>/dev/null
                  
                              f_log INF "Renewing ${domain}..."
                              old_fingerprint=$(openssl x509 -noout -in "${FULLCHAINFILE}" -fingerprint -sha256 | cut -c 20- | sed s/://g | awk '{print tolower($0)}')
                  
                              cd ${domain}
                              cp cert.pem old_cert.pem && cp chain.pem old_chain.pem && cp fullchain.pem old_fullchain.pem
                  
                              docker run -ti --rm -p 80:80 -p 443:443 -v /etc/letsencrypt:/etc/letsencrypt certbot/certbot \
                                  certonly --standalone --agree-tos -m wonderfall@targaryen.house \
                                  --csr /etc/letsencrypt/live/${domain}/csr.der \
                                  --cert-path /etc/letsencrypt/live/${domain}/cert.pem \
                                  --chain-path /etc/letsencrypt/live/${domain}/chain.pem \
                                  --fullchain-path /etc/letsencrypt/live/${domain}/fullchain.pem
                  
                              new_fingerprint=$(openssl x509 -noout -in "${FULLCHAINFILE}" -fingerprint -sha256 | cut -c 20- | sed s/://g | awk '{print tolower($0)}')
                  
                              f_log INF "Certificate renewed for ${domain}."
                  
                              f_log INF "Starting nginx..."
                              service nginx start &>/dev/null
                  
                              f_log INF "Updating TLSA records..."
                              sed -i "s/${old_fingerprint}/${new_fingerprint}/g" /home/docker/nsd/zones/db.${domain}
                              dns_update.sh ${domain}
                  
                              f_log INF "Done!"
                          fi
                      done
                  }
                  domain=$1
                  f_log INF "Domain set to ${domain}."
                  old_serial=$(grep "Serial" /home/docker/nsd/zones/db.${domain} | grep -o '[0-9]\+')
                  new_serial=${old_serial} && let new_serial++
                  sed -i -e "s/${old_serial}/${new_serial}/g" /home/docker/nsd/zones/db.${domain}
                  f_log INF "Incremented serial."
                  f_log INF "Signing DNS zone..."
                  docker exec nsd signzone ${domain} &>/dev/null
                  f_log INF "Done."

                  C'est moins propre mais ça faisait le boulot. Si tu fais ton truc pars plutôt ce qu'a fait Hardware je pense. Perso faut je revois ça pour traefik et comment dump les certs de acme.json d'abord...

                  Au passage, je ne suis pas fan du wildcard, pourquoi ? C'est bien si l'utilises sur un seul serveur, mais sinon c'est une mauvaise pratique que d'éparpiller des clés privées à d'autres serveurs dont la compromission de l'un peut mener à la compromission de l'ensemble du domaine. Tous les sous-domaines sont à risque quand tu fais un wildcard (SPOF). Je ne dis pas qu'il faut éviter, je dis juste qu'il faut être prudent...