• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 23/06/2022

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).

Schéma de fonctionnement d'un reverse-proxy
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.

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 :

$ sudo 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 :

$ sudo ln -s /etc/nginx/sites-available/01-www.example.com.conf /etc/nginx/sites-enabled/01-www.example.com.conf
$ sudo 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) :

$ sudo apt install libapache2-mod-rpaf
$ systemctl restart apache2

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

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.

Capture d'écran d'un navigateur client se connectant à l'adresse http://www.example.com/jenkins et affichant la page d'accueil de Jenkins
Accès à Jenkins sur le port 80 grâce à Nginx

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.

Exemple de certificat de réussite
Exemple de certificat de réussite