42 commentaires

Certbot: challenge DNS OVH & wildcard

Certbot est l’outil de l’EFF qui permet d’automatiser la génération de certificats TLS Letsencrypt. L’outil dispose de plusieurs méthodes – appellées challenges – permettant de valider que vous contrôlez bien le domaine. Cependant, seule la méthode DNS permet de générer des certificats wildcard. Voyons comment la mettre en place avec OVH.

Il existait déjà quelques plugins alternatifs permettant d’automatiser les modifications nécessaires aux DNS OVH en passant par leur API, mais c’est aujourd’hui le plugin officiel qui nous intéresse. Une fois en place, il vous permettra d’automatiquement générer et renouveller des certificats wildcard ou non, même si le DNS dudit domaine pointe pas sur un autre serveur.

Nous nous concentrons ici sur le plugin OVH, mais il en existe d’autres (CloudFlare, DigitalOcean, Linode, AWS…).

Installation des outils

Comme ces plugins nécessitent une des dernières versions de Certbot et qu’ils ne sont pas inclus par défaut, commençons par installer nos dépendances. Nous utiliserons pip afin de s’assurer d’obtenir une version récente, car les gestionaires de paquets des distributions livrent la plupart du temps des versions un peu datées…

Si vous avez déjà une version installée par votre ppa préféré et que vous souhaitez la supprimer avant d’installer la version pip, assurez-vous de faire un petit backup de /etc/letsencrypt. En effet apt purge certbot effacera ce répertoire et vos certificats avec.

# on s'assure d'avoir pip
apt install python3-pip

# puis on installe certbot et le plugin ovh
pip install certbot
pip install certbot-dns-ovh

Nous installons pip de python3. C’est en effet la version de python la plus récente et elle est installée par défaut sur la plupart des systèmes. En outre, l’installation via python2.x pose des problèmes au niveau des dépendances.

Dernier point de cette étape d’installation, la gestion des logs. Certbot log le résultat de chaque commande dans /var/log/letsencrypt. Cependant, pip ne configure aucune politique de rotation des logs. Afin que ces derniers ne s’ammassent pas indéfiniement, on va configurer logrotate pour qu’il les compresse puis qu’il les efface après 6 mois – comme un certificat a une durée de validité de 3 mois, ça semble être un bon compromis.

On place donc un nouveau fichier de config /etc/logrotate.d/certbot avec le contenu suivant :

/var/log/letsencrypt/*.log {
    monthly
    rotate 6
    compress
    delaycompress
    notifempty
    missingok
    create 640 root adm
}

Création des accès à l’API OVH

Deuxième étape, nous allons créer un accès à l’API d’OVH afin que le plugin puisse modifier des enregistrements pour vérifier que le domaine est bien à nous. Pour cela, rendez-vous sur la page de création de Token API.

Assurez-vous de bien définir le token avec une validité illimitée et renseignez les droits comme ceci :

Comme le signale Veovis dans les commentaires, ces droits sont un peu larges. Aussi, pour limiter cela à un seul domaine, vous pouvez définir les droits comme ceci :

Remplacez bien {domain.ext} par votre nom de domaine. Attention, il s’agit toujours du nom de domaine racine sans sous-domaine.

Après validation, il va falloir créer un fichier de configuration pour que Certbot puisse accéder aux identifiants de l’API. Vous pouvez enregistrer ce fichier où bon vous semble et le nommer comme il vous plaît. Pour ma part, c’est /root/.ovhapi et voici son contenu.

dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = xxx
dns_ovh_application_secret = xxx
dns_ovh_consumer_key = xxx

Vous remplacez évidemment les xxx par les informations obtenues lors de la création du token. Enfin, assurez-vous de paramétrer les droits d’accès de ce fichier en 600, sans quoi Certbot émettra des warnings. chmod 600 /root/.ovhapi.

Génération des certificats

Une fois tout cela en place, nous pouvons générer nos certificats. Nous allons prendre buzut.fr en exemple, mais bien entendu, seulement les domaines gérés sur votre compte OVH pourront fonctionner.

# génération du certificat pour buzut.fr et *.buzut.fr
# ce sont deux certificats distincts mais ils seront groupés en un seul fichier
certbot certonly --dns-ovh --dns-ovh-credentials ~/.ovhapi -d buzut.fr -d *.buzut.fr

# alternativement, si on exécute les lignes de commande en deux étapes (donc sans -d *.buzut.fr pour la précédente)
# nous obtenons un fichier par certificat
certbot certonly --dns-ovh --dns-ovh-credentials ~/.ovhapi -d *.buzut.fr

# si vous souhaitez scripter la génération
# il faut préciser à la commande de ne pas être interactive
certbot certonly --dns-ovh --dns-ovh-credentials ~/.ovhapi --non-interactive --agree-tos --email mon@email.fr -d buzut.fr -d *.buzut.fr

La commande renew de Certbot n’est pour l’heure pas compatible avec les plugins DNS. Il faudra donc renouveller l’ensemble des commandes utilisées pour créer les certificats de temps à autre – au moins une fois tous les 90 jours – afin de ne pas laisser les certificats périmer. Un petit script de renouvellement est tout indiqué.

# ce script trouve parfaitement sa place dans /usr/local/sbin/renewCerts.sh
#!/bin/bash

/usr/local/bin/certbot certonly --dns-ovh --dns-ovh-credentials /root/.ovhapi --non-interactive --agree-tos --email mon@email.fr -d buzut.fr
/usr/local/bin/certbot certonly --dns-ovh --dns-ovh-credentials /root/.ovhapi --non-interactive --agree-tos --email mon@email.fr -d *.buzut.fr

Vous pouvez ensuite l’appeler une fois par mois avec une crontab et vous aurez l’assurance d’avoir des certificats toujours à jour.

22 4 5 * * /usr/local/sbin/renewCerts.sh > /dev/null 2>&1

Et voilà, vous avez maintenant une validation par DNS avec renouvellement automatique, laquelle vous permet d’obtenir des certificats wildcard et de générer des certificats même si les DNS du domaine pointent vers une autre ip. Ça peut être utile en cas de load balancing par DNS par exemple.

Commentaires

berturion dit –

Excellent ce guide, pour une fois qu'un guide français est plus complet et mieux écrit qu'un contenu en anglais, ça fait plaisir, surtout la partie pour renouveler automatiquement le certificat :) Je vais tester ça cette semaine en remplacement de mon certificat "webroot". Merci !

Buzut dit –

Merci pour ton commentaire ! Content que tu aies trouvé ton bonheur

Thomas dit –

Putain ! C'est génial ! Je ne connaissais pas ce plugin, ça me révolutionne ma vie de DevOps ! Je cherchais justement à faire du wildcard, je croyais que c'était impossible avec letsencrypt et OVH ne le permet pas dans l'interface du loadbalancer.

Juste un retour pour le script shell : c'est potentiellement dangereux de surcharger la variable d'environnement PATH et elle ne sert à rien vu que tu appelles le path absolu vers certbot.

Buzut dit –

Hello! Content que ça puisse t'aider. Et oui, je confirme, c'est révolutionnaire !!

Merci pour ton retour. En effet, le path ne sert ici à rien (je l'ai bêtement gardé d'un autre script qui lui, en a vraiment besoin). Je corrige ça tout de suite.

A dit –

Super Merci ! C'est possible de faire qu'un seul certificat pour gérer exemple.com et *.exemple.com ?

Buzut dit –

Non ce n'est malheureusement pas possible !

Thomas dit –

certbot certonly --dns-ovh --dns-ovh-credentials /root/.ovhapi --non-interactive -d toutpoursortir.fr -d *.toutpoursortir.fr

Buzut dit –

C'est un one-liner mais il me semble que tu génères deux certificats quand même. Je n'ai plus toutes les options en tête.

Buzut dit –

J'ai testé avec la dernière version de Certbot, on obtient bien un seul fichier pour les deux certificats. J'ai donc mis à jour l'article.

Thomas dit –

Ah, j'oubliais... Le script que tu as fait c'est pour générer. Pour renouveler les certificats il y a beaucoup plus simple : certbot renew. On peut y ajouter les options --quiet --post-hook "systemctl reload apache2"

Buzut dit –

À moins qu'il y ait eu un changement récent, la commande renew ne fonctionne pas avec les plugins externes. Donc ça ne marchera pas.

Veovis dit –

Merci. Avant j'utilisais acme-client, mais le dev ne le maintient plus. J'ai donc du chercher une alternative non-intrusive (je veux JUSTE un certificat, je ne veux pas que le certbot touche à ma conf). Et c'est ce que fait certbot certonly.

Par contre, les droits requis sur l'api ovh sont totalement délirant, même si c'est ce qu'indique la doc du plugin. Après revue du code source, voici les droits minimums:


# GET /domain/zone/
# GET /domain/zone/{ta_zone}/status
# GET /domain/zone/{ta_zone}r/record
# GET /domain/zone/{ta_zone}/record/*
# POST /domain/zone/{ta_zone}r/record
# POST /domain/zone/{ta_zone}/refresh
# DELETE /domain/zone/{ta_zone}/record/*

Mrik dit –

Merci, c'est beaucoup plus propre comme ça. Je trouvais aussi que le script en demandait trop

Buzut dit –

Ah yes, c'est vraiment cool d'avoir investigué un peu. Je mettrai ça à jour dans l'article :)

Lucas dit –

Bonjour! Merci pour le tuto! J'avais pris un VPS chez OVH pour apprendre plus sur la configuration des serveurs et pour heberger mon blog. J'ai installé un CMS, j'ai acheté un nom de domain et maintenant j'essaye de configurer le certificat SSL. J'ai suivi ton tuto jusqu'au point de créer le token, mais je n'arrive pas. J'ai essayé les configurations que vous avez suggéré et aussi ces config:


# GET /domain/zone/
# GET /domain/zone/{ta_zone}/status
# GET /domain/zone/{ta_zone}r/record
# GET /domain/zone/{ta_zone}/record/*
# POST /domain/zone/{ta_zone}r/record
# POST /domain/zone/{ta_zone}/refresh
# DELETE /domain/zone/{ta_zone}/record/*

Mais ça donne un erreur: Error: Could not create credential

Comment je peux régler ça? Merci par avance!

Patrice dit –

Attention, il y deux "r" en trop :

GET /domain/zone/{ta_zone}/record # au lieu de GET /domain/zone/{ta_zone}r/record # et POST /domain/zone/{ta_zone}/record # au lieu de POST /domain/zone/{ta_zone}r/record

{ta_zone} aurait pu être écrit {ton-nom-de.domaine}...

Et pour finir, sur mes Debian 9, j'ai du utiliser pip3 au lieu de pip

pip3 install certbot pip3 install certbot-dns-ovh

Merci pour cette doc très utile.

boit dit –

Merci pour l'article !

Buzut, peux tu corriger les deux "r" en trop sur la création du Token OVH, ca simplifiera la lecture :)

Buzut dit –

C'est fait ! J'avais zappé, merci pour le rappel 👍

moby59 dit –

Petite erreur sur la section pour logrotate à priori : il ne faut pas oublier de mettre l'emplacement et le nom du fichier log au début du fichier dans /etc/logrotate.d/certbot

/var/log/letsencrypt/letsencrypt.log { monthly... }

Buzut dit –

C'est corrigé !

Merci 👍

jeff dit –

Bonjour et merci pour le tuto. J'ai cette erreur dont je n'arrive pas a me sortir :


certbot certonly --dns-ovh --dns-ovh-credentials ~/.ovhapi -d jeff.xxx.xxx.eu -d "*.jeff.xxx.xxx.eu"
Unable to determine zone identifier for jeff.xxx.xxx.eu using zone names: ['jeff.xxx.xxx.eu', 'xxx.xxx.eu', 'xxx.eu', 'eu']
Une idée du pourquoi du comment ? au niveau de la conf de la clé dans /domain/zone on remplace pas domain par son domaine xxx ?

tatayet dit –

Bonjour, Merci pour ce tuto. Je rencontre cependant un problème de création de token, dans l'interface ovh j'obtient: Could not create credential J'ai bien l’autorisation car dans la console: https://api.ovh.com/console/#/ je peux récupérer la valeur des champs

petit détail pour spip3 la commande est: pip3 install certbot

Merci pour votre aide.

zatchbell68 dit –

Jai le meme problème que toi :s si vous avez une solution je suis preneur.

zatchbell68 dit –

Bonjour,

Moi ca ne fonctionne pas ce je fais pip3 install certbot j'ai ce message d'erreur : Could not find a version that satisfies the requirement certbot (from versions: ) No matching distribution found for certbot

Vous avez des solution svp tout comme pour le token j'ai supprimé les 2 r mais cela ne fonctionne pas

Buzut dit –

T'es sur quelle distribution et quelle version ?

niko2 dit –

le renew fonctionne maintenant (au moins avec le plugin dns-ovh)

Herbs dit –

Merci pour l'info,

un simple /usr/local/bin/certbot renew suffit ?

ou faut il ajouter --dns-ovh --dns-ovh-credentials /root/.ovhapi ?

niko2 dit –

normalement le renew suffit. Tout est dans le fichier de configuration du domaine (le chemin du fichier de conf dépend de ton installation)

ghifou dit –

Bonjour, Très bon tuto, cependant j'ai un erreur : Error adding TXT record: 403 Client Error: Forbidden for url: https://eu.api.ovh.com/1.0/domain/zone/{mondomain.fr}/record?fieldType=TXT&subDomain=_acme-challenge Je ne m'en sort pas, une idée ?

orblazer dit –

Voici les routes exacte à mettre pour l'api :

- GET: /domain/zone/

- GET: /domain/zone/{zoneName}/

- GET: /domain/zone/{zoneName}/status

- GET: /domain/zone/{zoneName}/record

- GET: /domain/zone/{zoneName}/record/*

- POST: /domain/zone/{zoneName}/record

- POST: /domain/zone/{zoneName}/refresh

- DELETE: /domain/zone/{zoneName}/record/*

Ou plus rapide directement dans le lien :


https://api.ovh.com/createToken/index.cgi?duration=unlimited&GET=/domain/zone/&GET=/domain/zone/{zoneName}/&GET=/domain/zone/{zoneName}/status&GET=/domain/zone/{zoneName}/record&GET=/domain/zone/{zoneName}/record/&POST=/domain/zone/{zoneName}/record&POST=/domain/zone/{zoneName}/refresh&DELETE=/domain/zone/{zoneName}/record/

zura dit –

Bonjour, les * dans l'url tout faite ne sont pas pris en compte pour les lignes ligne DELETE=/domain/zone/{mondomaine.fr}/record/* GET=/domain/zone/{mondomaine.fr}/record/*

donc ne pas oublier de les ajouter :) je me suis tiré les cheveux perso XD

tatayet dit –

Bonjour, J'ai essayé de très nombreuses fois de faire usage de cerbot en m'inspirant de ce tuto, tant sur un raspbery que sur une distrib Ubuntu. (problème de version de Python je pense et ou de dépendance) Sans pour autant remettre en cause la procédure j'en propose une qui a fonctionné du premier coup avec acme.sh sources: https://github.com/Neilpang/acme.sh/wiki/How-to-use-OVH-domain-api

PREREQUIS: récupérer l'archive sur github

https://github.com/Neilpang/acme.sh

curl https://get.acme.sh | sh Or: wget -O - https://get.acme.sh | sh

Or, Install from git

Clone this project and launch installation:

git clone https://github.com/Neilpang/acme.sh.git cd ./acme.sh ./acme.sh --install

1° creation apikey and app_secret https://eu.api.ovh.com/createApp/ renseigner un nom et une description

2° déclarer les variables


	export OVH_AK="zzzzzzzzzzzzzzz"
	export OVH_AS="qqqqqqqqqqqqqqqqqqqq"
	export OVH_END_POINT="ovh-eu"

3° lancer une première foi le script

sh acme.sh --issue  -d test.mondomaine.fr --dns dns_ovh
ouvrir le lien #ou kimsufi-eu 4° lancer une deuxième foi le script
sh acme.sh --issue  -d test.mondomaine.fr --dns dns_ovh
l'enregistrement DNS va être réalisé, vérifié puis effacé

5° reste à copier les certificats présent dans .acme.sh modifier default-ssl.conf SSLCertificateFile /etc/letsencrypt/live/test.mondomaine.fr/test.mondomaine.fr.cer SSLCertificateChainFile /etc/letsencrypt/live/test.mondomaine.frr/fullchain.cer SSLCertificateKeyFile /etc/letsencrypt/live/test.mondomaine.fr/test.mondomaine.fr.key

6° renouvellement (pas vérifié)

sh acme.sh --renew  -d test.mondomaine.fr

ps: les permissions pour delete et put sont limitées à record et refresh

azallis dit –

Merci beaucoup ! You saved my day !!!

Et marche très bien sous Ubuntu 18.04, seulement il faut utiliser:


pip3 install certbot
pip3 install certbot-dns-ovh

k10Ack dit –

Merci pour le tuto! Juste une question par rapport aux droits sur l'API OVH: si je veux créer un certificat pour a.mondomaine.fr, le {zoneName} c'est "a" ou "a.mondomaine.fr"? Il y a quelque chose à créer dans les entrées DNS? J'ai toujours une erreur d'authentification. Merci d'avance

Buzut dit –

C'est le nom de domaine sans le sous-domaine. Exemple : GET /domain/zone/buzut.net/status.

k10Ack dit –

En effet, ça fonctionne mieux comme ça! Merci

Sty dit –

Un grand merci pour ce tuto de grande qualité :-)

Pour ma part, j'ai eu deux erreurs pendant l'installation sur Ubuntu 18.04 LTS que j'ai résolu de cette manière :

1/ L'installation de pip3


apt install python3-pip
pip3 install certbot
pip3 install certbot-dns-ovh
2/ Mise à jour de cryptography

pip3 install cryptography --upgrade

En espérant que ça puisse aider ;-)

Ichbinrodolf dit –

Merci pour ce super tuto; combiné à l'installation de opkg sur mon synology ça fonctionne parfaitement.

Marcel dit –

Bonjour, J'ai été obligé de rajouter le droit


GET: /domain/zone/{domain.name}/
Ceci était déjà dans le post de orblazer mais manque dans le corps principal du tutoriel. Merci pour ce tutoriel très bien fait.

sinsedrix dit –

Salut, j'avais gardé ce tuto bien utile en lien. La méthode marchait bien jusqu'à ce que je doive refaire toute la config. J'ai désormais cette erreur :

> Certbot can obtain and install HTTPS/TLS/SSL certificates. By default, > it will attempt to use a webserver both for obtaining and installing the > certificate. > certbot: error: unrecognized arguments: --dns-ovh-credentials /root/.ovhapi

Le plugin est pourtant bien installé, une idée de ce qui peut clocher ?

yboujraf dit –

Bonjour,

Merci pour avoir indiqué comment générer nos certificats en utilisant OVH.

Serait-il possible d'avoir la méthode pour l'installation de apache2 ET nginx et intégration des certificats ?

Ce serait le top.

Bien à vous,

DLer dit –

2023 et ce guide est toujours utile. Merci beaucoup!

Rejoignez la discussion !

Vous pouvez utiliser Markdown pour les liens [ancre de lien](url), la mise en *italique* et en **gras**. Enfin pour le code, vous pouvez utiliser la syntaxe `inline` et la syntaxe bloc

```
ceci est un bloc
de code
```