{"id":1692,"date":"2026-06-10T14:37:35","date_gmt":"2026-06-10T12:37:35","guid":{"rendered":"https:\/\/serer.fr\/?p=1692"},"modified":"2026-07-18T19:38:37","modified_gmt":"2026-07-18T17:38:37","slug":"obtenir-un-certificat-ssl-lets-encrypt","status":"publish","type":"post","link":"https:\/\/serer.fr\/?p=1692","title":{"rendered":"Lab &#8211; Linux : Obtenir un certificat SSL Let&rsquo;s Encrypt"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Pour obtenir un certificat pour votre service web, nous allons nous appuyer sur la solution certbot sous Linux. Toutes les m\u00e9thodes ne seront pas d\u00e9taill\u00e9es ici, nous nous concentrerons sur Apache et HAProxy. Toutefois, il existe d&rsquo;autre solution cl\u00e9 en main comme <em>traefik<\/em> qui int\u00e8gre un proxy invers\u00e9 et la gestion du protocole ACME pour les certificats.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"text-decoration: underline;\">Attention <\/span>: Tous les certificats produit sous l&rsquo;\u00e9tiquette Let&rsquo;s Encrypt sont g\u00e9n\u00e9r\u00e9s par des soci\u00e9t\u00e9s am\u00e9ricaines et sont donc soumis aux r\u00e8gles d&#8217;embargo am\u00e9ricain. En cas d&rsquo;h\u00e9bergement de service (localisation g\u00e9ographique) dans un pays soumis \u00e0 un embargo. Les certificats d&rsquo;un m\u00eame propri\u00e9taire peuvent \u00eatre r\u00e9voqu\u00e9e sans appel m\u00eame si les autres services sont h\u00e9berg\u00e9s ailleurs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pr\u00e9-requis d&rsquo;installation <\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Le port 80 doit \u00eatre accessible avec un challenge HTTP<\/li>\n\n\n\n<li>L&rsquo;acc\u00e8s \u00e0 la d\u00e9claration des DNS est obligatoire pour le challenge DNS<\/li>\n\n\n\n<li>Les droits root sur le serveur pour installer certbot<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Sur Debian\/Ubuntu r\u00e9cents, Certbot est disponible dans les d\u00e9p\u00f4ts standards.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update<br>sudo apt install certbot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">V\u00e9rifiez ensuite la bonne installation de la version<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>certbot --version\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Cr\u00e9ation du premier certificat<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Pour un premier certificat simple sur&nbsp;<code>example.com<\/code>&nbsp;en mode manuel + challenge DNS (<strong>DNS-01<\/strong>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour obtenir, le challenge DNS, il faudra cr\u00e9er des enregistrements TXT sur le domaine.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot certonly \\<br>--manual \\<br>--preferred-challenges dns \\<br>-d example.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Au cour de la cr\u00e9ation du certificat, un message affichera la valeur \u00e0 cr\u00e9er comme ci dessous.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Please deploy a DNS TXT record under the name\n_acme-challenge.example.com with the following value:\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n <\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">V\u00e9rification de l&rsquo;enregistrement DNS avant de poursuivre la g\u00e9n\u00e9ration.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig TXT _acme-challenge.example.com +short<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Explications des options<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>certonly<\/code>&nbsp;: obtient le certificat sans modifier la configuration du serveur web.<\/li>\n\n\n\n<li><code>--manual<\/code>&nbsp;: vous g\u00e9rez vous\u2011m\u00eame la validation (ici via DNS).<\/li>\n\n\n\n<li><code>--preferred-challenges dns<\/code>&nbsp;: demande sp\u00e9cifiquement le challenge DNS\u201101.<\/li>\n\n\n\n<li><code>-d example.com<\/code>&nbsp;: nom de domaine \u00e0 certifier. Pour un certificat wildcard, on peut sp\u00e9cifi\u00e9 -d &lsquo;*.example.com&rsquo;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Les certificats sont g\u00e9n\u00e9r\u00e9s \u00e0 cet endroit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Chemin du certificat :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>\/etc\/letsencrypt\/live\/example.com\/fullchain.pem<\/code><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Chemin de la cl\u00e9 priv\u00e9e :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>\/etc\/letsencrypt\/live\/example.com\/privkey.pem<\/code><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration avec arr\u00eat de service et utilisation du port 80<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># service apache2 stop\n# ou \nservice haproxy stop\n\nsudo certbot certonly --standalone\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration sans arr\u00eat de service et utilisation de l&rsquo;instance apache<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot certonly --webroot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Les instances apaches sont d\u00e9tect\u00e9e automatiquement \u00e0 partir du moment ou la configuration est stock\u00e9 dans \/etc\/apache\/<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">O\u00f9 trouver les certificats ?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tous les certificats sont g\u00e9n\u00e9r\u00e9s par d\u00e9faut dans \/etc\/letsencrypt\/live\/. Un sous r\u00e9pertoire est cr\u00e9\u00e9 pour chaque FQDN avec son nom.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Renouvellement manuel des certificats<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot renew<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Automatisation du renouvellement de certificat<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les certificats g\u00e9n\u00e9r\u00e9s sont valables 3 mois \u00e0 partir de la date de g\u00e9n\u00e9ration. Toutefois, la dur\u00e9e maximale des certificats publics a beaucoup diminu\u00e9 : elle est pass\u00e9e \u00e0 398 jours \u00e0 200 jours en mars 2026, puis elle passera \u00e0 100 jours en mars 2027, et 47 jours en mars 2029.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Script de renouvellement \u00ab\u00a0cert-renew.sh\u00a0\u00bb :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#service haproxy stop\nservice apache2 stop\n\n# renouvellemnt des certificats Let's Encrypt (si besoin) :)\ncertbot renew\n\n#recreation des certificat PEM pour haproxy\nfor site in `ls --directory \/etc\/letsencrypt\/live\/*.fr` ; do\n     echo \"concatenation des certificat ${site}\/fullchain.pem ${site}\/privkey.pem dans ${site}.pem\"\n     `cat ${site}\/fullchain.pem ${site}\/privkey.pem &gt; ${site}.pem `\ndone\n\n#service haproxy start\nservice apache2 start\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Utilisation de la crontab pour le renouveler tous les mois en cr\u00e9ant un lien symbolique de votre script dans \/etc\/cron.monthly<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ln -s \/path_root\/cert-renew.sh \/etc\/cron.monthly\/cert-renew.sh\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pour plus de personnalisation, on peut ajouter la ligne \u00e0 \/etc\/crontab (non recommand\u00e9). Exemple d&rsquo;un lancement tous les 1er du mois \u00e0 4:52 du matin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/crontab: system-wide crontab\n# Unlike any other crontab you don't have to run the `crontab'\n# command to install the new version when you edit this file\n# and files in \/etc\/cron.d. These files also have username fields,\n# that none of the other crontabs do.\n\nSHELL=\/bin\/sh\nPATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/sbin:\/bin:\/usr\/sbin:\/usr\/bin\n\n# Example of job definition:\n# .---------------- minute (0 - 59)\n# |  .------------- hour (0 - 23)\n# |  |  .---------- day of month (1 - 31)\n# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...\n# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat\n# |  |  |  |  |\n# *  *  *  *  * user-name command to be executed\n17 *    * * *   root    cd \/ &amp;&amp; run-parts --report \/etc\/cron.hourly\n25 6    * * *   root    test -x \/usr\/sbin\/anacron || ( cd \/ &amp;&amp; run-parts --report \/etc\/cron.daily )\n47 6    * * 7   root    test -x \/usr\/sbin\/anacron || ( cd \/ &amp;&amp; run-parts --report \/etc\/cron.weekly )\n52 6    1 * *   root    test -x \/usr\/sbin\/anacron || ( cd \/ &amp;&amp; run-parts --report \/etc\/cron.monthly )\n#\n52 4    1 * *   root    \/root\/cert-renew.sh\n#\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Exemple d&rsquo;int\u00e9gration pour Apache :<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Activez les modules SSL et red\u00e9marrez Apache.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo a2enmod ssl headers rewrite<br>sudo systemctl restart apache2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">V\u00e9rifiez avec&nbsp;<code>apache2ctl -M | grep ssl<\/code>&nbsp;: vous devez voir&nbsp;<code>ssl_module<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dans le VirtualHost, int\u00e9grer les lignes suivantes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SSLEngine on<br>SSLCertificateFile \/etc\/letsencrypt\/live\/example.com\/fullchain.pem<br>SSLCertificateKeyFile \/etc\/letsencrypt\/live\/example.com\/privkey.pem<br>Include \/etc\/letsencrypt\/options-ssl-apache.conf # Options s\u00e9curis\u00e9es auto-inclues par Certbot<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Exemple d&rsquo;int\u00e9gration pour Nginx <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple d&rsquo;impl\u00e9mentation dans un bloc\u00a0<code>server<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssl_certificate \/etc\/letsencrypt\/live\/example.com\/fullchain.pem;<br>ssl_certificate_key \/etc\/letsencrypt\/live\/example.com\/privkey.pem;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Rechargez la configuration<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl reload nginx<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Exemple d&rsquo;int\u00e9gration pour HAProxy :<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Exemple d&rsquo;impl\u00e9mentation, le fichier haproxy.cfg<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>front https\n   # ecoute sur le port 80 et 443\n   bind 0.0.0.0:80\n   bind :::80\n\n   bind 0.0.0.0:443 ssl crt \/etc\/letsencrypt\/live\/exemple.com.pem\n   bind :::443 ssl crt \/etc\/letsencrypt\/live\/exemple.com.pem<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Pour HAProxy, le format de certificat doit \u00eatre au format pem full chaine.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#recreation des certificat PEM pour haproxy\nfor site in <code>ls --directory \/etc\/letsencrypt\/live\/*.<span style=\"background-color: initial; font-family: inherit; font-size: inherit; text-align: initial; color: initial;\">example.com ; do<\/span><\/code>  echo \"cat ${site}\/fullchain.pem ${site}\/privkey.pem > ${site}.pem\"\n<code>cat ${site}\/fullchain.pem ${site}\/privkey.pem > ${site}.pem<\/code>done\nservice haproxy restart\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Pour obtenir un certificat pour votre service web, nous allons nous appuyer sur la solution certbot sous Linux. Toutes les m\u00e9thodes ne seront pas d\u00e9taill\u00e9es ici, nous nous concentrerons sur Apache et HAProxy. Toutefois, il existe d&rsquo;autre solution cl\u00e9 en main comme traefik qui int\u00e8gre un proxy invers\u00e9 et la gestion du protocole ACME pour [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,86,8,103,23,46],"tags":[61],"class_list":["post-1692","post","type-post","status-publish","format-standard","hentry","category-le-laboratoire","category-os","category-linux","category-cahier-technique","category-securite","category-les-solutions-open-source-libre","tag-certbot"],"_links":{"self":[{"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/posts\/1692","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/serer.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1692"}],"version-history":[{"count":8,"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/posts\/1692\/revisions"}],"predecessor-version":[{"id":2141,"href":"https:\/\/serer.fr\/index.php?rest_route=\/wp\/v2\/posts\/1692\/revisions\/2141"}],"wp:attachment":[{"href":"https:\/\/serer.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1692"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/serer.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1692"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/serer.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1692"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}