[Tuto] Certificat TLS avec Certbot pour BookMyName (FreeBSD)

  • Vague de SPAM

    Suite à une vague de spam sur le forum, les inscriptions sont temporairement limitées.

    Après votre inscription, un membre de l'équipe devra valider votre compte avant qu'il ne soit activé. Nous sommes désolés pour la gêne occasionnée et vous remercions de votre patience.

cooper

Chevalier Jedi
Membre Confirmé
28 Octobre 2022
171
47
78
47
Ile-De-France
Professionnel
Non
Hello all,

Petit tutoriel sur la gestion (création/renouvellement) avec certbot d'un certificat TLS de letsencrypt.org chez le registrar BookMyName ayant le bon goût d'utiliser un BSD pour son Nas (ici FreeBSD) 😜

1. Objectif

Obtenir et renouveler automatiquement un certificat Let's Encrypt wildcard (*.example.net) + racine (example.net) en utilisant :
  • la méthode DNS-01 challenge,
  • les scripts adaptés pour BookMyName (bmn-auth.sh, bmn-cleanup.sh),
  • et l’infrastructure FreeBSD (periodic).

2. Installation et préparation

a. Installer Certbot et ses dépendances​

Bash:
pkg install py311-certbot

b. Installer les scripts suivants pour BookMyName​

1. Authentification puis enregistrement DNS TXT de l'empreinte :

Bash:
vi bmn-auth.sh
Bash:
#!/bin/sh
# bmn-auth.sh — ajout TXT BookMyName pour wildcard + domaine racine
# Vérification sur plusieurs DNS publics pour accélérer propagation
# Anti-warning : jamais exit 1

# ───────────────────────────────
# CONFIGURATION
# ───────────────────────────────
DNSSERVERS="8.8.8.8 1.1.1.1 9.9.9.9"  # Google, Cloudflare, Quad9
CURL_TIMEOUT=10

BMN_USER="USER" # Inclure les identifiants chez le registrar
BMN_PASS="PASS"

# ───────────────────────────────
# RACINE DOMAINE
# ───────────────────────────────
DOMAIN=$CERTBOT_DOMAIN
if [ "$(echo "$CERTBOT_DOMAIN" | awk -F. '{print NF}')" -gt 2 ]; then
    DOMAIN=$(echo "$CERTBOT_DOMAIN" | awk -F. '{print $(NF-1)"."$NF}')
fi

echo "──────────────────────────────────────────────"
echo "Auth hook for BookMyName"
echo "Domain: $CERTBOT_DOMAIN"
echo "Root:   $DOMAIN"
echo "Value:  $CERTBOT_VALIDATION"
echo "──────────────────────────────────────────────"

# ───────────────────────────────
# AJOUT DU TXT
# ───────────────────────────────
curl -s --max-time $CURL_TIMEOUT -u "$BMN_USER:$BMN_PASS" \
  "https://www.bookmyname.com/dyndns/?hostname=_acme-challenge.$DOMAIN&type=txt&ttl=300&do=add&value=\"$CERTBOT_VALIDATION\"" \
  | grep -q "good" && echo "TXT record creation requested" || echo "BookMyName update may have failed"

# ───────────────────────────────
# BUFFER INITIAL
# ───────────────────────────────
echo "Waiting 60s for initial propagation..."
sleep 60

# ───────────────────────────────
# VÉRIFICATION MULTI-DNS
# ───────────────────────────────
MAX_ATTEMPTS=60    # ~15 min
SLEEP_BETWEEN=15

attempt=0
record_visible=0

while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
    attempt=$((attempt + 1))
    echo "Checking attempt $attempt/$MAX_ATTEMPTS..."

    for ns in $DNSSERVERS; do
        public_val=$(drill _acme-challenge.$DOMAIN TXT @$ns 2>/dev/null | grep _acme | grep -v ";;" | awk '{print $5}' | tr -d '"')
        if [ "$public_val" = "$CERTBOT_VALIDATION" ]; then
            echo "Record visible on $ns after $((attempt * SLEEP_BETWEEN))s"
            record_visible=1
            break 2  # quitte les deux boucles
        fi
    done

    echo "Record not visible yet on any DNS"
    sleep "$SLEEP_BETWEEN"
done

if [ "$record_visible" -ne 1 ]; then
    echo "TXT record still not visible after $((MAX_ATTEMPTS * SLEEP_BETWEEN / 60)) minutes."
    echo "Let’s Encrypt can still validate the challenge if propagation occurs immediately afterward."
fi

# Ne jamais exit 1 pour éviter l’erreur dans Certbot
exit 0

2. Nettoyage des enregistrements DNS TXT:

Bash:
#!/bin/sh
# bmn-cleanup.sh — suppression automatique du TXT _acme-challenge pour BookMyName

BMN_USER="USER" # Inclure les identifiants chez le registrar
BMN_PASS="PASS"

DOMAIN=$CERTBOT_DOMAIN
if [ "$(echo "$CERTBOT_DOMAIN" | awk -F. '{print NF}')" -gt 2 ]; then
    DOMAIN=$(echo "$CERTBOT_DOMAIN" | awk -F. '{print $(NF-1)"."$NF}')
fi

echo "Removing TXT record for $CERTBOT_DOMAIN"
curl -s -u "$BMN_USER:$BMN_PASS" \
  "https://www.bookmyname.com/dyndns/?hostname=_acme-challenge.$DOMAIN&type=txt&ttl=300&do=remove&value=\"$CERTBOT_VALIDATION\"" \
  | grep -q "good" && echo "Cleanup done" || echo "Cleanup may have failed"
exit 0

Les placer dans /opt/local/bin/ (ou autre emplacement de son choix) :
Bash:
mv bmn-auth.sh /opt/local/bin/
mv bmn-cleanup.sh /opt/local/bin/
chmod 750 /opt/local/bin/bmn-*.sh

NB. Adaptation des scripts pour FreeBSD :
  • être compatible POSIX via #!/bin/sh
  • remplacer dig +short par une version compatible drill :
    drill _acme-challenge.$DOMAIN TXT @$DNSSERVER | grep _acme | grep -v ";;" | awk '{print $5}' | tr -d '"'

3. Première émission du certificat

Commande initiale (manuelle, une seule fois et remplacer example.net par son nom de domaine) :
Bash:
certbot certonly \
  --manual \
  --preferred-challenges=dns \
  --manual-auth-hook /opt/local/bin/bmn-auth.sh \
  --manual-cleanup-hook /opt/local/bin/bmn-cleanup.sh \
  -d '*.example.net' -d example.net \
  --agree-tos --email cert@example.net

Les fichiers générés :
Code:
/usr/local/etc/letsencrypt/live/example.net/
  ├── cert.pem
  ├── chain.pem
  ├── fullchain.pem
  └── privkey.pem

NB. Un seul certificat est créé pour les deux domaines (*.example.net + example.net).


4. Renouvellement automatique via periodic

FreeBSD fournit déjà un script :

/usr/local/etc/periodic/weekly/500.certbot-3.11

Il suffit de l’activer et de lui passer les bons arguments.

Configuration dans /etc/periodic.conf :​

Bash:
weekly_certbot_enable="YES"
weekly_certbot_custom_args="--no-random-sleep-on-renew --quiet"

# Redémarrage des services afin d'utiliser le nouveau certificat.
# Par exemple ici apache et unbound.
weekly_certbot_post_hook="service apache24 restart && service unbound restart"


NB. Option utile :
--no-random-sleep-on-renew
→ Désactive le délai aléatoire (jusqu’à 8h) inséré par défaut avant le renouvellement.

Comme periodic planifie déjà les exécutions (grâce à anticongestion de rc dans /usr/local/etc/periodic/weekly/500.certbot-3.11), c’est sûr de le désactiver.

Le renouvellement s'effectue par periodic et les paramètres de certbot renew sont enregistrés dans la configuration /usr/local/etc/letsencrypt/renewal/example.net.conf dont le contenu est le suivant :

Bash:
cat /usr/local/etc/letsencrypt/renewal/example.net.conf

version = 4.2.0
archive_dir = /usr/local/etc/letsencrypt/archive/example.net
cert = /usr/local/etc/letsencrypt/live/example.net/cert.pem
privkey = /usr/local/etc/letsencrypt/live/example.net/privkey.pem
chain = /usr/local/etc/letsencrypt/live/example.net/chain.pem
fullchain = /usr/local/etc/letsencrypt/live/example.net/fullchain.pem

# Options used in the renewal process
[renewalparams]
account = XXXXXXXXXXXXXXX
pref_challs = dns-01,
authenticator = manual
manual_auth_hook = /opt/local/bin/bmn-auth.sh
manual_cleanup_hook = /opt/local/bin/bmn-cleanup.sh
server = https://acme-v02.api.letsencrypt.org/directory
key_type = ecdsa


5. Vérification / Debug

Forcer un test de renouvellement :​

Bash:
certbot renew --dry-run


Historique :​

/var/log/letsencrypt/letsencrypt.log




6. Points clés

  • Les scripts bmn-*.sh gèrent l’ajout et la suppression des enregistrements DNS _acme-challenge chez BookMyName.
  • Le certificat couvre à la fois example.net et *.example.net.
  • Le renouvellement se fait automatiquement chaque semaine par periodic.
  • Après chaque renouvellement, Apache et Unbound sont redémarrés pour recharger le nouveau certificat.
  • Le paramètre --no-random-sleep-on-renew est désactivé pour un comportement déterministe.

NB. Les demandes de certificat(s) et de renouvellement via l'échange DNS-01 challenge prennent du temps eu égard à la propagation sur les serveurs DNS ; la durée de propagation varie suivant les registrars. Pour BookMyName, une fourchette entre 5 et 10 minutes pour que l'échange DNS-01 soit fait.


En résumé rapide

Elément​
Emplacement​
Commande​
Certificats/usr/local/etc/letsencrypt/live/example.net/
Script shell pour création/reno. du DNS TXT/opt/local/bin/bmn-auth.sh
Script shell pour nettoyage du DNS TXT/opt/local/bin/bmn-cleanup.sh
Configuration du renouvellement/usr/local/etc/letsencrypt/renewal/example.net.conf
Automatisation/usr/local/etc/periodic/weekly/500.certbot-3.11
Configuration periodic/etc/periodic.conf
Historique/var/log/letsencrypt/letsencrypt.log
Test manuelcertbot renew --dry-run

Commandes utilisées

 
Dernière édition:
  • J'adore
Réactions: EVO