nginx
Rediriger HTTP vers HTTPS et vers www en une seule redirection avec nginx
Fiche écrite en 2018, pour les navigateurs et les versions de l’époque. Vérifiez qu’elle correspond encore à votre environnement avant de l’appliquer.
Un site joignable sous quatre adresses (avec ou sans www, en HTTP ou en HTTPS) doit n’en garder qu’une. La configuration qu’on trouve souvent enchaîne deux redirections : HTTP vers HTTPS, puis sans www vers www. Ça fonctionne, mais c’est une requête de plus pour chaque visiteur et chaque robot.
Avec un bloc server par cas, chaque variante part directement vers l’adresse finale :
# Tout ce qui arrive en HTTP, avec ou sans www
server {
listen 80;
listen [::]:80;
server_name exemple.fr www.exemple.fr;
return 301 https://www.exemple.fr$request_uri;
}
# HTTPS sans www : le certificat doit couvrir les deux noms
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name exemple.fr;
ssl_certificate /etc/letsencrypt/live/exemple.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemple.fr/privkey.pem;
return 301 https://www.exemple.fr$request_uri;
}
# L'adresse canonique
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.exemple.fr;
ssl_certificate /etc/letsencrypt/live/exemple.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemple.fr/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
root /var/www/exemple/web;
# ...
}
Pour vérifier, on interroge chaque variante et on regarde l’en-tête Location : il doit pointer directement vers https://www.exemple.fr/contact. Sur l’en-tête HSTS, prudence : une fois envoyé, le navigateur refusera le HTTP pendant toute la durée indiquée. On commence par une valeur courte (une journée, max-age=86400), et on n’ajoute includeSubDomains qu’après avoir vérifié que tous les sous-domaines sont bien en HTTPS.
nginx -t && systemctl reload nginx
# Chaque variante doit répondre 301 vers l'adresse finale, en une fois
for u in http://exemple.fr http://www.exemple.fr https://exemple.fr; do
curl -sI "$u/contact" | grep -iE '^(HTTP|location)'
done
Sources
- nginx, directive return nginx.org
- MDN, Strict-Transport-Security developer.mozilla.org