Menu Fermer

Nginx : faire une redirection (301, 302, HTTP vers HTTPS, URL, …)

Nginx est un puissant serveur Web HTTP haute performance open source. Il peut fonctionner comme proxy inversé ou proxy POP3 / IMAP. Parmi les nombreuses fonctionnalités, il est possible de créer des redirections de pages, de sites, domaines.
Avec Nginx, on peut créer des redirections 301, 302 ou complètement réécrire une URL à l’aide de règles rewrite.

Dans ce tutoriel, je vous donne de nombreux exemples de redirections Nginx avec les explications afin de pouvoir créer votre propre redirections HTTP.

Nginx : faire une redirection (301, 302, HTTP vers HTTPS, URL, ...)

Les redirections Nginx : comment ça marche

Une redirection HTTP consiste à rediriger un domaine, une URL ou un fichier vers une autre adresse.
Le serveur renvoie une en-tête HTTP avec une code HTTP spécifique.
En effet, il existe deux types de redirections.

Une redirection temporaire (statut code 302 Found) comme son nom l’indique permet de créer une redirection temporaire d’une ressource vers une autre.
Cela est utile par exemple pour mettre hors ligne une page spécifique ou un site entier en redirigeant les visiteurs vers une page de maintenance.

Une redirection permanente (statut code 301 Moved Permanently). Informe le navigateur internet de ne plus utiliser l’ancienne adresse et de mémoriser la nouvelle.
Cette redirection est utile lorsque vous changez l’URL d’une page WEB ou si une page n’est plus accessible et rediriger les visiteurs vers une autre page internet.
Enfin on peut aussi l’utiliser après des modifications techniques, par exemple, un changement de CMS.

Dans Nginx, les redirections se font essentiellement avec la directive rewrite qui permet de réécrire la requête HTTP.
On peut alors rediriger une page entière ou utiliser des regex pour rediriger des pages avec une structure spécifique.
Ainsi, selon les besoins, la maitrise des regex est utile, pour plus d’informations : Guide d’utilisation des expressions régulières.
Enfin il est aussi possible d’utiliser la directive return plus simple à utiliser pour retourner un code HTTP 301 ou 302 sur un bloc server ou dans un bloc location.

L’utilisation de la directive rewrite est décrite dans ce tutoriel :

Comment faire une redirection avec Nginx

Redirection permanente 301 ou une redirection temporaire 302

Dans Nginx la redirection permanente ou temporaire d’une page WEB se fait avec rewrite et utilise la même structure.
Simplement, on indique à la fin à l’aide d’un drapeau le type de redirection redirect ou permanent.

Pour créer une redirection permanente 301 sur Nginx, on utilise rewrite avec l’ancienne page puis la nouvelle page.
Enfin on termine avec redirect.

rewrite ^/ancienne_page$ http://www.newdomain.com/nouvelle_page redirect;

De même pour créer une redirection temporaire 302, on utilise la même structure et on termine avec le flag permanent.

rewrite ^/ancienne_page$ http://www.newdomain.com/nouvelle_page permanent;

Redirection d’une page vers une autre (ou un fichier)

La redirection d’un fichier ou d’une page vers une autre se fait avec rewrite comme expliqué dans le paragraphe précédent.
On peut donc rediriger une page spécifique ou un type de pages utilisant une structure spécifique à l’aide des expressions régulières.

Location path_pattern {        
     rewrite ^/oldURL$ https://www.domainone.com/nouvelleURL redirect; 
}

Par exemple, ci-dessous, je redirige une ancienne page du site https://www.malekal.com/tutorial_nLite.php vers https://www.malekal.com/tutorial-et-guide-nlite/ et ainsi de suite.

rewrite ^/tutorial_nLite.php$ https://www.malekal.com/tutorial-et-guide-nlite/ permanent;
rewrite ^/tutorial_LogMeIn.php$ https://www.malekal.com/tutorial-et-guide-logmein/ permanent;
rewrite ^/tutorial_ProcessExplorer.php$ https://www.malekal.com/tutorial-process-explorer/ permanent;
rewrite ^/tutorial_Microsoft_Security_Essentials.php$ https://www.malekal.com/tutorial-microsoft-security-essentials/ permanent;
rewrite ^/tutorial_Dial-a-fix.php$ https://www.malekal.com/tutorial-dial-a-fix/ permanent;

Redirection des pages avec des paramètres et variables

Mais on peut utiliser des redirections plus complexes à l’aide de regex, notamment en stockant les motifs dans des variables exactement comme avec la commande sed.

Par exemple, ci-dessous, on redirige toutes les images PNG du dossier wp-content de WordPress, vers un script PHP qui permet de watermark les images.
$1 correspond au motif de la première parenthèse soit le chemin de l’URL et $2 à la second parenthèse soit le nom fichier image.
Les variables sont alors utilisées en argument dans le script wm.php

      location ^~ /wp-content {
               rewrite ^/(.*)/(.*\.(png|PNG)$) /wm.php?d=wordpress&p=$1&i=$2;
      }

Voici un autre exemple ci-dessous pour rediriger les anciennes pages du forum https://forum.malekal.com/XXX-fYYY vers https://forum.malekal.com/viewtopic?f=$2.
$2 correspond à la variable f (second parenthèse), soit le numéro du forum.

rewrite ^/(.*)-f([0-9]*) /viewforum.php?f=$2&$query_string break;

La mise en place d’extension de sitemap pour WordPress nécessite souvent l’ajout de règle rewrite afin de rediriger des pages.
Par exemple ici, on redirige les requêtes de l’index du site map /sitemap_index.xml vers /index.php?sitemap=1.
Puis les pages du sitemap selon leurs numéros avec la même logique.

 rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
 rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

Redirection d’une page avec un argument spécifique

On peut aussi tester la présence d’un argument afin d’effectuer des redirections de pages spéciques.
Par exemple sur le forum, je redirige des pages viewtopic ou viewforum selon la valeur de l’argument t.

location ~ /view(topic|forum)\.php(/|$) {
            [...]
    if ($args ~ "t=381(&|$)") {  rewrite ^ https://www.malekal.com/proteger-pc-virus-pirates/ permanent; }
    if ($args ~ t=36057) { rewrite ^ https://www.malekal.com/reparer-reinitialiser-reinstaller-firefox/ permanent; }
    if ($args ~ t=35837) { rewrite ^ https://www.malekal.com/supprimer-desinstaller-edge-de-windows-10-7-8/ permanent; }
    if ($args ~ t=33839) { rewrite ^ https://www.malekal.com/adwcleaner-supprimer-virus-adwares-pup/ permanent;   }
    if ($args ~ t=1065) {  rewrite ^ https://www.malekal.com/demander-aide/ permanent;  }
    if ($args ~ t=53039) { rewrite ^ https://www.malekal.com/supprimer-desinstaller-edge-de-windows-10-7-8/ permanent;  }
    if ($args ~ t=52529) { rewrite ^ https://www.malekal.com/quest-ce-que-le-dossier-winsxs-et-le-magasin-des-composants-de-windows-10/ permanent; }
    if ($args ~ t=49834) { rewrite ^ https://www.malekal.com/ransomwares-rancongiciels-definition-comment-en-proteger/ permanent; }
    if ($args ~ t=52454) { rewrite ^ https://www.malekal.com/windows-10-mouchards-confidentialite-collecte-donnees/ permanent;      }
    if ($args ~ t=55579) { rewrite ^ https://www.malekal.com/antimalware-execution-service-et-forte-utilisation-cpu-disque-ou-ram-sur-windows-10/ permanent; }
    if ($args ~ t=52494) { rewrite ^ https://www.malekal.com/optimiser-son-disque-sur-windows-10/ permanent;  }

Ainsi par exemple l’URL https://forum.malekal.com/viewtopic?t=52529 redirige vers https://www.malekal.com/quest-ce-que-le-dossier-winsxs-et-le-magasin-des-composants-de-windows-10/

Redirection d’un site www en non-www

Pour retirer les www. d’un site afin de passer en non-www.
On créé un bloc server et on déclare le domaine avec server_name par exemple www.monsite.fr puis on utilise return 301 pour rediriger vers http://monsite.fr.
La variable $request_uri permet de renvoyer l’URL dans la requête HTTP.

server {
    server_name www.monsite.fr;
    return 301 $scheme://monsite.fr$request_uri;
}

avec rewrite, cela donne :

server {
    listen 443;
    server_name www.malekal.com;
    rewrite ^/(.*)$ https://malekal.com$request_uri permanent;
}

Redirection d’un site entier ou domaine

Lors d’un changement de domaine sur un site WEB, on peut rediriger l’ancien domaine vers le nouveau.

Pour cela, on créé le bloc server avec le server_name puis on redirige tout le contenu à l’aide du regex ^/(.*)$ vers le nouveau domaine.
$request_uri permet de rediriger n’importe quelle URL vers le nouveau domaine.

server {
    listen 443;
    server_name malekal.com;
    rewrite ^/(.*)$ https://www.malekal.com$request_uri permanent;
}

Notez que l’on pourrait aussi utiliser la variable $1 pour renvoyer les URL de cette manière :

server {
    listen 443;
    server_name malekal.com;
    rewrite ^/(.*)$ https://www.malekal.com/$1 permanent;
}

Enfin encore en utilisant la directive return :

server {
    listen 80 default_server;
    listen 443 ssl default_server;
    server_name _;
    return 301 $scheme://www.malekal.com;
}

Redirection HTTP vers HTTPS (et port 80 vers le port 443)

Pour forcer le site en HTTPs et SSL, on peut aussi demander à rediriger toutes les connexions HTTP (du port 80) vers du HTTPS (port 443).
Pour cela, on créé un bloc server_name qui écoute sur le port 80 à l’aide de la directive listen.
Puis on créé une redirection 301 avec return sans oublier d’utiliser la variable $request_uri afin de renvoyer l’URL complète avec les arguments.

server {
        server_name www.malekal.com;
        listen 80;
        return 301 https://$host$request_uri;
}

Redirection par un code serveur

On peut aussi rediriger les codes serveur. Cela est utile par exemple lorsque l’on veut afficher des pages spécifiques sur les erreurs 403, 404 ou 503.
Par exemple pour personnaliser la page 403 avec Nginx :

error_page 403 /403.html;

Notez que l’on peut rediriger plusieurs codes serveurs à la fois de cette manière :

error_page 500 502 503 504  /50x.html;

Enfin il est aussi possible de rediriger les codes serveurs vers un bloc Nginx spécifique à l’aide de @ :

server {
[...]
error_page 404 502 504 = @php_micro;
[...]
}

location @php_micro {
[...]
}

Redémarrer nginx

Pour vérifier que la configuration est correcte :

nginx -t
sudo systemctl nginx reload