Notion de base du serveur web Nginx

04 avril 2022
Server
Nginx
Notion de base du serveur web Nginx - Banner

Introduction

Un serveur web ou serveur HTTP (Hypertext Transfert Protocol) est une machine qui prend et répond la page demandée par l'utilisateur en utilisant le protocole HTTP.

Nginx est un serveur web Open Source crée par Igor Sysoev lancé en 2004. Il s'est focalisé sur la performance, la légèreté et la haute simultanéité des connexions qui sont tous des problèmes connus par les autres serveurs web comme Apache HTTP Serveur.

Pour la suite, il faut que vous aviez un Nginx installé dans votre machine. Si ce n'est pas le cas, vous pouvez l'installer en suivant ce tutoriel.

Configuration

La configuration de Nginx consiste à créer un ensemble de serveurs virtuels qui gèrent le traitement des demandes pour des domaines ou des adresses IP particuliers. Chaque serveur virtuel possède ses propres configurations qui définissent la manière dont il gère une requête. Typiquement lorsqu'on veut faire une redirection vers un autre serveur ou faire une réécriture d'URL.

La définition de ces configurations se fait tous à l'aide de ce qu'on appelle une directive que l'on va voir dans la suite.

La configuration de Nginx se trouve dans le dossier /etc/nginx. Ce dossier contient plusieurs fichiers mais ce qui nous intéresse sont:

  • nginx.conf: contient la configuration générale.
  • conf.d/ et sites-enabled/: contient la configuration des différents serveurs.

Vous pouvez mettre la configuration de tous vos serveurs dans nginx.conf mais pour avoir une meilleure organisation, il vaut mieux créer une fichier de configuration pour chaque serveur dans conf.d ou sites-enabled.

Serveur virtuel

Un serveur virtuel est défini dans une directive server du context http, comme ceci:

http {
  # Configuration du serveur 1
  server {}
  # Configuration du serveur 2
  server {}
}

La directive http nous dit que nous sommes dans la configuration d'un serveur web mais non pas dans un serveur mail ou autres.

Pour indiquer à votre serveur la requête qu'il doit écouter, il faut utiliser la directive listen en spécifiant l'adresse IP et le port.

server {
  #Le serveur écoute les requêtes qui viennent sur l'IP 127.0.0.1 et le port 8080
  listen 127.0.0.1:8080;
}

Si vous ne spécifiez pas le port, le serveur écoute sur le port "standard" 80. Et pour l'adresse, si vous ne la spécifiez pas, le serveur écoute sur toutes les adresses.

Si plusieurs serveurs écoutent la même adresse IP et port, Nginx teste l'entête Host de la requête contre la valeur de la directive server_name pour déterminer le serveur correspondant. La valeur de server_name peut être un text plein, un caractère générique ou une expression regulière.

server {
  #Ce serveur écoute les requêtes qui a un Host devlogger.net ou www.devlogger.net
  listen      80;
  server_name devlogger.net www.devlogger.net;
}

Si le nom de certains serveurs correpond à l'entête Host de la requête, Nginx prend le serveur le plus approprié suivant ces étapes:

  • Nom exacte
  • Caractère générique le plus long commençant par un astérisque, comme *.devlogger.net
  • Caractère générique le plus long terminant par un astérisque, comme devlogger.*
  • Première expression régulière correspondante (une expression régulière doit comme par un tilde ~)

Si l'entête Host de la requête ne correspond à aucun nom de serveur, Nginx utilise le serveur par défaut. Le serveur par défaut est le premier bloc de serveur qui se trouve dans le fichier nginx.conf à moins que vous l'indiquez explicitement à l'aide du paramètre default_server.

server {
  listen 80 default_server;
  #...
}

Configuration des localisations

Une fois que Nginx a décidé le serveur qui doit prendre une requête, il teste l'URI spécifié dans l'entête de la requête contre les paramètres des directives location définies dans le bloc server. La directive location définit la manière de gérer une requête en fonction de son URI.

On peut définir le paramètre de la localisation avec deux manière différentes: chaînes de préfixe et une expression régulière.

location /images/ {
  #Les URI comme /images/hero.png sont traités ici
}
location ~ \.html?$ {
  #Le modificateur tilde ~ indique que c'est une expression régulière
  #Les URI qui se terminent par .html ou .html sont traités ici
}

Voici le processus de sélection que Nginx suit pour choisir une localisation:

  • Il test l'URI avec toutes les chaines de préfixe.
  • Si une localisation correspond exactement à l'URI et en plus elle contient le modificateur =, la recherche s'arrête et Nginx prend ce bloc.
  • Si non, si la localisation qui correspond le mieux contient le modificateur ^~ (caret-tilde), alors les expressions régulières ne sont pas vérifiées.
  • Si non, Nginx mémorise la localisation qui possède la chaîne de préfixe correspondante la plus longue.
  • Ensuite, Il test l'URI contre toutes les expressions régulières.
  • Si une localisation correspond à l'expression régulière, la recherche s'arrête et Nginx prend cette localisation.
  • Sinon, si aucune expression régulière correspond, Nginx utilise la localisation correspond à la chaîne de préfixe mémorisée (point 4).

Voici deux exemples d'utilisation de la directive location: servir des fichiers statiques et se comporter comme un serveur proxy grâce à cette directive.

server {
  location /images/ {
    #La directive "root" spécifie le dossier racine pour la requête.
    #Si l'URI est /images/hero.png, Nginx délivre le fichier dans /data/hero.png.
    root /data;
  }
  location / {
    #La directive "proxy_pass" passe la requête vers le serveur en paramètre.
    proxy_pass http://other-server.com;
  }
}

Utilisation des variables

On peut utiliser des variables dans la configuration de Nginx et elles sont dénotées par un $ (dollar) au début de son nom. Nginx possède des variables prédéfinies telles que les variables de son core HTTP mais on peut aussi créer notre variable pour faire notre propre logique.

Retourne des codes de réponse HTTP spécifique

Nginx peut retourner directement une réponse comme faire une redirection ou renvoyer une erreur spéficique.

location /not/found {
  return 404;
}
location /old/url {
  #Les code 301, 302, 303 et 307 exigent un second paramètre qui est l'URL de la redirection.
  return 301 http://example.com/new/url;
}

La directive return peut être incluse dans le bloc location ou server.

Gestions des erreurs

Avec la directive error_page, Nginx peut retourner une page personnalisée avec un code d'erreur HTTP lorsque les erreurs surviennent.

#Afficher la page 404.html lorsqu'une erreur 404 arrive
error_page 404 /404.html;

Réécriture d'URL

Une réécriture d'URL avec Nginx se fait directement dans la configuration du serveur. Elle se fait à l'aide de la directive rewrite qui peut être incluse dans le bloc location ou server. L'URI d'une requête peut subir plusieurs modifications durant son traitement et elle contient deux paramètres obligatoires et un paramètre optionnel dans sa définition. Le premier paramètre est l'expression régulière qui doit correspondre à l'URI de la requête. Le deuxième paramètre est l'URI qui remplace l'URI correspondant. Le troisième paramètre est un drapeau qui peut interrompre le traitement de la réécriture d'URL, par exemple faire une redirection (301 ou 302) ou stoppé le traitement d'autres directives.

#Le drapeau "break" indique qu'on stop la réécriture.
rewrite ^/post/(.*)$ /post?id=$1 break;
#Le drapeau "last" indique qu'on stop la réécriture dans context courant du server et location,
#et Nginx passe à nouveau la réécriture vers d'autres localisations.
rewrite ^/tag/(.*)$ /tag?id=$1 last;

Réécriture de la réponse HTTP

Nginx peut réécrire aussi la réponse avant de l'envoyer au client grâce à la directive sub_filter.

location / {
  sub_filter 'href="http://127.0.0.1:8080/'    'href="https://$host/';
  sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
  #La directive "sub_filter_once" dit à Nginx d'appliquer consécutivement
  #le "sub_filter" dans une localisation.
  sub_filter_once on;
}

Une réponse déjà modifiée par une sub_filter n'est pas remplacée à nouveau si une autre correspondance de sub_filter se produit.