Outils pour utilisateurs

Outils du site


cours:informatique:sysadmin:gerer_serveur_linux_et_services:320_reverse_proxy_nginx

Notes et transcriptions du cours “Gérez votre serveur Linux et ses services” disponible sur la plateforme Openclassrooms.

Mettez en place un reverse-proxy avec Nginx

Comme je vous l’ai expliqué à la fin du dernier chapitre, dans un environnement de production, Tomcat a besoin d’un serveur web qui gère les requêtes des clients, et qui ne lui transmette que les requêtes que doit traiter l’application Java. On parle de reverse-proxy pour désigner une application placée en frontal (directement en contact avec les clients) et qui joue le rôle d’un intermédiaire avec des applications placées en backend (sans contact direct avec les clients).

Un reverse-proxy fait l'intermédiaire entre des clients et des serveurs de backend

Les deux raisons principales qui peuvent amener à utiliser un reverse-proxy sont l’amélioration :

  • de la sécurité ;
  • des performances.

Nginx est un serveur web léger et performant. Il est particulièrement performant pour servir des fichiers statiques et pour analyser des URL. Pour cette raison, il est couramment employé en tant que reverse-proxy. Le backend peut être aussi bien un serveur Apache configuré pour gérer PHP qu’un serveur applicatif comme Tomcat.

Nginx se prononce Engine X, soit phonétiquement quelque chose comme “haine gin Aix”

Si vous voulez installer Nginx pour écouter sur le port 80 (ou 443 pour HTTPS), il va falloir d’abord configurer Apache pour écouter sur d’autres ports.

Changez les ports sur lesquels écoute Apache

Tomcat écoute sur le port 8080. Pour éviter tout conflit, je vous propose de configurer Apache pour écouter sur les ports :

  • 7080 pour le HTTP (au lieu de 80) ;
  • 7443 pour le HTTPS (au lieu de 443).

Changez les numéros de port en conséquence dans le fichier /etc/apache2/ports.conf, et la configuration de vos virtual hosts dans /etc/apaches/sites-available/, puis redémarrez Apache :

$ sudo systemctl restart apache2

Installez le serveur web Nginx

Vous pouvez maintenant installer Nginx par la commande suivante :

apt install nginx

Vous trouverez alors la configuration de Nginx dans /etc/nginx. Le fichier de configuration principal est nginx.conf. Vous y trouvez des directives simples comme :

user www-data;

qui définit l’utilisateur auquel appartient Nginx. Il y a également des “blocs” tels que le bloc http{} :

http {
 ...
}

qui définit la configuration générale du serveur, et contient tout un tas de directives simples.

Comme pour Apache, les lignes commençant par un # sont des commentaires, et la configuration inclut les fichiers :

  • /etc/nginx/conf/*.conf
  • /etc/nginx/modules-enables/*.conf
  • /etc/nginx/sites-enabled/*

Passez maintenant à la configuration de vos sites dans /etc/nginx/sites-available.

Configurez Nginx

Dans Nginx, les “virtual hosts” s’appellent des “server blocs” car ils sont configurés dans des blocs server{}. Commencez par créer le fichier /etc/nginx/sites-available/01-www.example.com.conf. Il permettra de joindre Jenkins et Apache et il contient :

upstream backend_jenkins{
    server 127.0.0.1:8080;
}

upstream backend_apache{
    server 127.0.0.1:7080;
}

server {
    listen    80;
    server_name    www.example.com example.com;

    location /jenkins {
        include proxy_params;
        proxy_pass http://backend_jenkins;
    }

    location / {
        include proxy_params;
        proxy_pass http://backend_apache;
    }
}
upstream backend_jenkins{} définit un bloc “upstream” dont le nom est backend_jenkins. Ce bloc contient les adresses des serveurs de backend. Si plusieurs adresses sont configurées (une directive server par ligne), Nginx va automatiquement répartir la charge entre ces serveurs
server {} c’est l’équivalent du <VirtualHost /> d’Apache, c’est dans ce bloc que vous allez configurer votre site
listen spécifie l’IP et le port correspondant
server_name précise les domaines valables pour ce site. Plusieurs domaines peuvent être précisés, séparés par des espaces
location /jenkins {} précise les règles qui s’appliquent aux adresses qui commencent par “/jenkins” (après le nom de domaine), comme http://www.example.com/jenkins
proxy_pass http://backend_jenkins; indique d’agir en tant que proxy et de transmettre les requêtes avec le protocole HTTP vers les serveurs définis dans le bloc upstream “backend_jenkins”
include proxy_params; inclut les directives présentes dans le fichier /etc/nginx/proxy_params

Le fichier proxy_params contient les directives les plus courantes pour les proxy web. Elles indiquent les en-têtes HTTP à transmettre :

cat /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

En particulier, l’en-tête Host va permettre à Apache de savoir à quel virtual host transmettre la requête. Les autres requêtes vont permettre à Apache de savoir que c’est un proxy qui transmet les requêtes, et de connaître la véritable IP des clients. Sans ça, Apache s’imaginerait que toutes les requêtes viennent de 127.0.0.1 !

Il vous reste alors à activer votre “server block” en faisant un lien symbolique vers le répertoire sites-enabled, et à recharger Nginx pour prendre en compte votre configuration :

ln -s /etc/nginx/sites-available/01-www.example.com.conf /etc/nginx/sites-enabled/01-www.example.com.conf
systemctl reload nginx

Enfin, même si Apache reçoit maintenant la véritable IP des clients dans l’en-tête X-Forwarded-For, il reste à installer le module rpaf pour que cette IP apparaisse dans les logs en tant qu’IP source des requêtes (et non 127.0.0.1) :

apt install libapache2-mod-rpaf
systemctl restart apache2

Voilà, maintenant vous aurez bien l’adresse réelle de vos clients dans vos logs Apache. :)

Si votre proxy Nginx et votre serveur Apache sont sur des machines différentes, il faudra indiquer l’adresse IP de votre proxy dans le fichier de configuration du module /etc/apache2/mods-available/rpaf.conf.

Au final, dans la configuration ci-dessus, toutes les requêtes vers www.example.com commençant par “/jenkins” seront redirigées vers l’application Jenkins hébergée par Tomcat, et toutes les autres adresses seront redirigées vers Apache.

La dernière chose qui reste à configurer, c’est de passer les sites en HTTPS pour sécuriser les connexions avec les clients.

Configurez Nginx pour utiliser HTTPS

Vous avez déjà vu comment créer des certificats signés par Let’s Encrypt. Je vais donc vous montrer maintenant la configuration à appliquer pour les utiliser avec Nginx. Votre fichier /etc/nginx/sites-available/01-www.example.org.conf devrait ressembler à ça :

upstream backend_jenkins{
    server 127.0.0.1:8080;
}

upstream backend_apache{
    server 127.0.0.1:7080;
}

server {
    listen    80;
    server_name    www.example.com example.com;

    #Redirige toutes les requêtes http vers https
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem

    location /jenkins {
        include proxy_params;
        proxy_pass http://backend_jenkins;
    }

    location / {
        include proxy_params;
        proxy_pass http://backend_apache;
    }
}
  • Les blocs upstream{} ne changent pas.
  • Le bloc server{} pour le port 80 contient juste une directive pour rediriger les requêtes en HTTPS.
  • Dans le bloc server{} pour le port 443, la directive listen précise ssl en plus du port, et les directives ssl_certificate et ssl_certificate_key indiquent les fichiers certificats à utiliser.

En rechargeant la configuration Nginx, vous pouvez maintenant vous connecter à vos fichiers Apache à l’adresse https://www.example.com/ et à Jenkins par l’adresse https://www.example.com/jenkins.

Obligez vos clients à passer par votre proxy

Vous pouvez maintenant utiliser votre proxy pour vous connecter à vos backends, mais il est toujours possible pour vos clients de se connecter directement à vos backends. En général, c’est quelque chose qu’on cherche à éviter d’un point de vue sécurité. Il est donc très important de configurer vos backends pour n’autoriser les connexions que depuis votre proxy.

Ici, votre proxy et vos backends sont sur la même machine, donc une manière simple de faire ça est de ne les faire écouter que sur l’interface locale 127.0.0.1. Dans d’autres configurations, vous pourriez par exemple utiliser un pare-feu.

Pour Apache, mettez à jour vos fichiers /etc/apache2/ports.conf et /etc/apache2/sites-available/01-www.example.com.conf pour remplacer par exemple tous les 7080 par des 127.0.0.1:7080 (idem pour les 7443). Ensuite, redémarrez Apache.

Pour la configuration de Jenkins, vous allez utiliser votre première valve Tomcat.

Une valve Tomcat va permettre d’agir comme un préprocesseur pour chaque requête. Elle va donc faire ses traitements entre la réception de la requête et l’émission de la réponse.

Vous trouverez, entre autres, les valves suivantes :

  • La valve de journal d’accès : org.apache.catalina.valves.AccessLogValve.
  • La valve de filtre d’adresse distante : org.apache.catalina.valves.RemoteAddrValve.
  • La valve de filtre d'hôte distant : org.apache.catalina.valves.RemoteHostValve.
  • La valve de dump : org.apache.catalina.valves.RequestDumperValve.

Dans notre situation, nous allons utiliser la valve de filtre d’adresse distante (RemoteAddrValve).

Pour Jenkins, vous allez créer un fichier “context”, comme vous l’avez fait pour l’application Manager. Copiez le fichier context du Manager pour créer celui de Jenkins :

cd /etc/tomcat8/Catalina/localhost
cp manager.xml jenkins.xml

Éditez ensuite la balise <Context /> du fichier jenkins.xml comme ceci :

<Context path=”/jenkins”
    docBase=”jenkins” >
    <Valve className=”org.apache.catalina.valves.RemoteAddrValve”
        allow=”127.0.0.1” />
</Context>

Il ne vous reste plus qu’à redémarrer Tomcat.

En résumé

  • Un reverse-proxy est une application qui joue le rôle d’intermédiaire entre des clients et des applications backend.
  • Le serveur web Nginx est couramment employé en tant que reverse-proxy.
  • La configuration de Nginx est différente de celle d’Apache. Elle est composée de blocs de directives.
  • La sécurité est renforcée quand tous les accès passent par le reverse-proxy, et que les accès directs au backend sont bloqués.

Dans le prochain chapitre, vous allez découvrir une autre forme de proxy : le proxy-cache.

◁ Précédent | ⌂ Retour au sommaire | Suivant ▷

cours/informatique/sysadmin/gerer_serveur_linux_et_services/320_reverse_proxy_nginx.txt · Dernière modification : 2024/05/02 09:47 de yoann