De plus en plus de navigateurs avertissent quand on utilise des sites sans protocole de sécurité, reconnaissable au https://
au début de l’adresse internet. Ici est décrit le passage en https pour un site sur un serveur Ubuntu/Apache avec accès root. On utilise un certificat libre de Let’s Encrypt avec le logiciel certbot qui gère l’obtention des certificats, de leurs mises à jour etc. Certbot s’occupe aussi de prendre le certificat, il n’y a donc pas besoin de s’occuper de Let’s Encrypt.
Installer certbot
Vu les modification à apporter sous /etc/
, il est nécessaire d’exécuter toutes ces commandes sous root (sudo).
La méthode sûre est d’appeler toutes ces commandes à la suite, souvent elles ne sont pas toutes nécessaires quand on dispose d’un système déjà en fonction.
$> apt-get update $> apt-get install software-properties-common $> add-apt-repository universe $> add-apt-repository ppa:certbot/certbot $> apt-get update
Lancer certbot et les changements apportés
Avec cette commande, on obtient une version courte des paramètres pour certbot:
$> certbot --help
Avec la commande ci-bas, on passe un site, par exemple andre.carto.net
, en mode https. On peut et il est utile d’ajouter tous les alias à la requête, car sinon il faudra plusieurs certificats. Il est donc judicieux de limiter les chaînes à un (sous-)domaine avec ou sans “www” devant par exemple.
$> certbot -d andre.carto.net -d www.andre.carto.net --apache
Attention avec plusieurs alias à certifier en chaîne: Si on efface plus tard un alias de cette chaîne au niveau DNS, le renouvellement du certificat ne peut plus se faire et tous les alias et/ou domaines de la chaîne seront en erreur. Concrètement, cela arrive lors de la fin de durée du certificat et au moment du renouvellement, donc pas au moment de l’effacement au niveau DNS ou sur le serveur. Les messages d’erreurs sont malicieux, cela commence par un email de Let’s Encrypt signifiant que le renouvellement a échoué et c’est le même message quand on fait $> certbot renew
. Rien ne dit cependant quel alias de domaine est concerné par le problème. Quand on rétablit un alias au niveau DNS, il faut un certain temps que la réplication se face.
Concernant les noms de domaines internationalisés: dans données de configuration apache sous /etc/apache/sites-available/
, il faut à rédiger les noms en code IDN (Internationalized Domain Names, RFC3492) et on doit les appeler tels quels sous certbot, donc par exemple xn--htel-vqa.com
pour hôtel.com
.
Le dialogue qui suit la commande demande plusieurs détails sans importance sauf le dernier, où il s’agit d’introduire une redirection de http vers https. Vu que l’on veut que les vieux liens soit tous automatiquement traduits par les nouveaux, cela s’impose.
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Les changements les plus importants pour le site se trouvent dans la définition des vhosts sous /etc/apache/sites-available/
. À la définition andre.carto.net.conf
est automatiquement rajouté la redirection suivante. Le code permanent
correspond à 301
, que l’on trouve dans les anciennes documentations. S’il y a plusieurs alias
(sous-domaine), il y aura une ligne additionelle pour chacun.
RewriteCond %{SERVER_NAME} =www.andre.carto.net [OR] RewriteCond %{SERVER_NAME} =andre.carto.net RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
Cependant ce code n’effectue chez moi pas de redirection quand on appelle la page sous http. Je l’ai donc changé contre celui ci-bas, ainsi une page quelconque appelée en http est immédiatement chargé en https.
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L]
Il y a aussi une nouvelle entrée sous andre.carto.net-le-ssl.conf
. Il s’agit pour le début de la copie de andre.carto.net.conf
. À la place des redirections se trouvent les lignes relatives aux certificats:
Include [LOCAL PATH]/options-ssl-apache.conf SSLCertificateFile [LOCAL PATH]/fullchain.pem SSLCertificateKeyFile [LOCAL PATH]/privkey.pem
Sous les références indiqués se trouvent effectivement les clés des certificats.
Certbot rajoute pour les deux sites aussi les liens sous sites-enabled/
.
Par contre certbot ne fait pas le redémarrage d’Apache, il faut le faire manuellement à la fin des changements:
$> /etc/init.d/apache2 restart
Pour éviter le dédoublement des fichiers *.conf
, il est possible de les garder en un seul comme décrit ici. Un fichier *.conf
ressemble alors par exemple à ceci:
<VirtualHost *:80> # SHORT DEFINITION ServerName andre.carto.net ServerAlias www.andre.carto.net ServerAdmin [XXXXXXX@XXX.XXX] # REDIRECT RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [NE,R=301,L] </VirtualHost> <IfModule mod_ssl.c> <VirtualHost *:443> # FULL DEFINITION DocumentRoot [LOCAL PATH] ServerName andre.carto.net ServerAlias www.andre.carto.net ServerAdmin [XXXXXXX@XXX.XXX] AddDefaultCharset utf-8 ErrorLog [LOCAL PATH] CustomLog [LOCAL PATH] combined # SSL Include [LOCAL PATH]/options-ssl-apache.conf SSLCertificateFile [LOCAL PATH]/fullchain.pem SSLCertificateKeyFile [LOCAL PATH]/privkey.pem </VirtualHost> </IfModule>
Durée par défaut
Le certificat est valable durant 90 jours par défaut.
$> certbot certificates
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: andre.carto.net
Domains: andre.carto.net www.andre.carto.net
Expiry Date: 2020-01-02 09:36:12+00:00 (VALID: 89 days)
Certificate Path: [LOCAL PATH]/fullchain.pem
Private Key Path: [LOCAL PATH]/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
On peut vérifier l’état de la mise à jour ainsi, cette commande affiche divers services périodiques. Comme on vient d’activer le service à 2019-10-05 11:47:49, il n’y a pas encore d’autres occurrences.
$> systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Sat 2019-10-05 11:47:49 CEST 19h left n/a n/a certbot.timer certbot.service
Les détails s’obtiennent par la commande ci-bas. il ne faut cependant pas s’inquiéter de la ligne Active: inactive (dead)
.
$> systemctl status certbot.service ● certbot.service - Certbot Loaded: loaded ([LOCAL PATH]/certbot.service; static; vendor preset: enabled) Active: inactive (dead) Docs: file:///[LOCAL PATH]/python-certbot-doc/html/index.html https://letsencrypt.readthedocs.io/en/latest/
En effet, certbot ayant mis par défaut la durée à 90 jours, la mise à jour ne se fera pas 30 jours avant l’échéance du certificat. Il n’est pas facile de trouver une confirmation de ce fait, surtout que sous /etc/letsencrypt/renewal/andre.carto.net.conf
se trouve la ligne # renew_before_expiry = 30 days
qui est mise sous commentaire. À priori ces 30 jours sont fixés dans le code de base certbot, comme supposé ici.
30 jours avant l’échéance du certificat est lancé le service de mise à jour. Ce sera à raison de deux fois par jour jusqu’à ce soit avec succès.
$> vim [LOCAL PATH]/certbot.timer [Unit] Description=Run certbot twice daily [Timer] OnCalendar=*-*-* 00,12:00:00 RandomizedDelaySec=43200 Persistent=true [Install] WantedBy=timers.target
Réponse défaut avec plusieurs VirtualHosts sous Apache et Ubuntu
Lorsque l’on configure des sous-domaines du type andre.carto.net ou pro.carto.net à côté du site principal, on définit en général ces adresses: deux pour le domaine principal (carto.net et www.carto.net) et deux par sous-domaine (andre.carto.net, www.andre.carto.net, pro.carto.net, www.pro.carto.net). Il s’agit donc de trois sites différents, avec “www” devant ou pas. Quand on appelle cependant un autre sous-domaine non défini (comme projects.carto.net), le DNS renverra généralement au serveur gérant le domaine principal (carto.net) et celui-ci devra produire une réponse
Dans la définition des VirtualHosts sous /etc/apache2/sites-available/
on aura ces trois fichiers:
- a.carto.net
- andre.carto.net.conf
- carto.net.conf
- pro.carto.net.conf
Dans la logique par défaut sous Apache et Ubuntu il existe lors de l’installation un domaine [LOCAL PATH]/sites-available/000-default.conf
renvoyant à /var/www/html/index.html
. Ce sera cette réponse qui sera donné à l’appel de projects.carto.net. Observons bien les trois zéros devant et partons du principe que nous ayons effacé ce fichier 000-default.conf
. En appelant project.carto.net, ce sera a.carto.net qui sera servi. Tout simplement parce que c’est alphabétiquement le premier de la liste. Cela est indépendant des domaines principaux s’il y en a plusieurs!
La chose se complique quand on passe certains sites en https et d’autres non. Un exemple de VirtualHosts à la base:
- a.carto.net
- andre.carto.net.conf *
- carto.net.conf
- geoidee.ch.conf
- pro.carto.net.conf
- provence-guide.net.conf *
En passant uniquement ceux avec astérisque en https, on aura des fichiers additionnels sous /etc/apache2/sites-available/
:
- a.carto.net
- andre.carto.net.conf *
- andre.carto.net-le-ssl.conf
- carto.net.conf
- geoidee.ch.conf
- pro.carto.net.conf
- provence-guide.net.conf *
- provence-guide.net-le-ssl.conf
Rappelons-nous que geoidee.ch n’est pas sous https, mais que cette adresse réponde proprement sous http. Que se passe-t-il si on appelle l’adresse https://www.geoidee.ch/? Le navigateur reconnaîtra le domaine geoidee.ch, émettra un avertissement que l’appel sécurisé donne une réponse non-sécurisé. Si on confirme que l’on veut continuer, le serveur devrait répondre avec le domaine alphabétiquement par défaut, car https://www.geoidee.ch/ n’est pas défini. Or ce n’est pas a.carto.net, c’est andre.carto.net-le-ssl.conf. C’est donc toujours alphabétiquement le premier, mais c’est le premier défini en https!
Passer un site WordPress en https
Le principe pour le nom du domaine sur le serveur est le même que pour un site statique normal. Le problème est que WordPress stocke le nom du domaine avec le protocole dans la configuartion principale. Ce qui est plus grave par contre, c’est que tous les liens internes sont aussi stockés dans le texte avec le protocole http. Le problème est identique au changement complet de l’URL.
Après le changement sur le serveur, on s’enregistres sur son site et backend apparaît normalement sous https. On peut aussi éditer, mais on remarquera que dès que l’on appelle une page du frontend, celle-ci repasse en http. Les deux choses à faire donc:
Changer l’adresse du site WordPress
Sous Backend > Settings > General
il faut remplacer:
WordPress Address (URL) : https://andre.carto.net Site Address (URL): https://andre.carto.net
Après avoir confirmé ces changements (en bas), les changements entre backend et frontend restent tous en https.
Modifier tous les liens internes sous WordPress
Tous les liens sont enregistrés dans la base de données avec le texte en code HTML, il n’y a pas de table des liens. Les liens internes sont vraiment mis de la forme <a href="https://andre.carto.net/2019/passer-son-serveur-en-https/>
alors que sous la forme <a href="/2019/passer-son-serveur-en-https/>
cela aurait évité tous les ennuis. Il faut donc recherche et remplacer ces liens dans les tables de la base de données sur laquelle est basé l’instance WordPress. Cela marche bien avec le plug-in Search & Replace par Inpsyde GmbH, mais il y en a d’autres. Avantage de celui-ci: on peut agir sur toutes les tables et on peut faire un test pour trouver toutes les occurrences.
Une fois installé, on démarre le plugin sous Tools Search & Replace > Search & Replace
. L’interface est simple:
Search for: https://andre.carto.net
Replace with: https://andre.carto.net
Au-dessous on sélectionne toutes les tables et on peut lancer la recherche test. Cela dure quelques minutes. Il ne faut pas s’étonner du nombre d’occurrences trouvés, pour ce blog cela dépassait 300.000 cas! Le replacement est assez évident et il y a peu de chance d’occasionner un remplacement non réversible. On peu donc désactiver la case Dry Run et lancer le remplacement effectif.
Erreurs avec contenu externe
Pour que les navigateurs acceptent pleinement la sécurité activée, il faut que tous les éléments inclus soient servis sous https
. Cela arrive avec des inclusion comme youtube, des cartes Google Maps API, des cartes OSM ou simplement des photos incluses. Cela vaut aussi pour des éléments sur son propre site. Dans ces cas, dans la barre adresse du navigateur n’est pas affiché le cadenas fermé, mais une information du type: “Votre connexion à ce site n’est pas totalement sécurisé”. Les inclusions non-sécurisées peuvent être compliqués et récurrents. Il faut les exclure une après une. La console d’erreur des navigateurs aide un peu.
J’ai eu un cas compliqué avec des cartes Open Street Map (OSM) sur lesquelles je charge mes propres fichiers KLM qui contiennent des icônes graphiques que je sers de mon propre serveur. Ces fichiers KML sont édités dans Google Earth et pour que cela marche, il faut une adresse complète et non relative. J’avais longtemps une erreur, parce que dans mes fichiers KML, générés il y a plusieurs années, se trouvaient ce type de référence initialement sans le “s”. Cependant Google Earth rajoute souvent une longue liste de styles qui contient aussi des icônes non utilisés. Malheureusement, un fichier KML exporté de Google Earth en 2019 contient toujours des liens en http seulement vers ses propres icônes.
<href>https://provence-guide.net/pix/icon/i-ycro.png</href>
Bien sûr, il faut aussi s’occuper d’appeler les tuiles OSM correctement:
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
No Comments