Comment configurer Nginx en tant que proxy inverse sur Ubuntu 22.04

De Get Docs
Aller à :navigation, rechercher

Introduction

Un proxy inverse est la méthode recommandée pour exposer un serveur d'applications à Internet. Que vous exécutiez une application Node.js en production ou un serveur Web intégré minimal avec Flask, ces serveurs d'applications se lieront souvent à localhost avec un port TCP. Cela signifie que par défaut, votre application ne sera accessible que localement sur la machine sur laquelle elle réside. Bien que vous puissiez spécifier un point de liaison différent pour forcer l'accès via Internet, ces serveurs d'applications sont conçus pour être servis derrière un proxy inverse dans les environnements de production. Cela offre des avantages de sécurité en isolant le serveur d'applications de l'accès direct à Internet, la possibilité de centraliser la protection par pare-feu et un plan d'attaque réduit pour les menaces courantes telles que les attaques par déni de service.

Du point de vue du client, l'interaction avec un proxy inverse n'est pas différente de l'interaction directe avec le serveur d'applications. C'est fonctionnellement le même, et le client ne peut pas faire la différence. Un client demande une ressource puis la reçoit, sans aucune configuration supplémentaire requise par le client.

Ce didacticiel vous montrera comment configurer un proxy inverse à l'aide de Nginx, un serveur Web populaire et une solution de proxy inverse. Vous allez installer Nginx, le configurer en tant que proxy inverse à l'aide du proxy_pass directive et transférez les en-têtes appropriés de la demande de votre client. Si vous n'avez pas de serveur d'application à tester, vous devrez éventuellement configurer une application de test avec le serveur WSGI Gunicorn.

Conditions préalables

Pour terminer ce tutoriel, vous aurez besoin de :

  • Un serveur Ubuntu 22.04, configuré conformément à notre guide de configuration initiale du serveur pour Ubuntu 22.04,
  • L'adresse du serveur d'applications que vous souhaitez utiliser comme proxy, celle-ci sera appelée app_server_address tout au long du didacticiel. Cela peut être une adresse IP avec un port TCP (comme la valeur par défaut de Gunicorn de http://127.0.0.1:8000), ou un socket de domaine Unix (tel que http://unix:/tmp/pgadmin4.sock pour pgAdmin). Si vous n'avez pas de serveur d'application configuré pour tester, vous serez guidé dans la configuration d'une application Gunicorn qui se liera à http://127.0.0.1:8000.
  • Un nom de domaine pointé vers l'IP publique de votre serveur. Ceci sera configuré avec Nginx pour proxy votre serveur d'application.

Étape 1 - Installation de Nginx

Nginx est disponible pour l'installation avec apt via les référentiels par défaut. Mettez à jour l'index de votre référentiel, puis installez Nginx :

sudo apt update
sudo apt install nginx

Presse Y pour confirmer l'installation. Si vous êtes invité à redémarrer les services, appuyez sur ENTER pour accepter les valeurs par défaut.

Vous devez autoriser l'accès à Nginx via votre pare-feu. Après avoir configuré votre serveur selon les prérequis initiaux du serveur, ajoutez la règle suivante avec ufw:

sudo ufw allow 'Nginx HTTP'

Vous pouvez maintenant vérifier que Nginx est en cours d'exécution :

systemctl status nginx
Output● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-08-29 06:52:46 UTC; 39min ago
       Docs: man:nginx(8)
   Main PID: 9919 (nginx)
      Tasks: 2 (limit: 2327)
     Memory: 2.9M
        CPU: 50ms
     CGroup: /system.slice/nginx.service
             ├─9919 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─9920 "nginx: worker process

Ensuite, vous ajouterez un bloc de serveur personnalisé avec votre domaine et votre proxy de serveur d'applications.

Étape 2 - Configuration de votre bloc serveur

Il est recommandé de créer un fichier de configuration personnalisé pour vos nouveaux ajouts de blocs de serveur, au lieu de modifier directement la configuration par défaut. Créez et ouvrez un nouveau fichier de configuration Nginx à l'aide de nano ou votre éditeur de texte préféré :

sudo nano /etc/nginx/sites-available/your_domain

Insérez ce qui suit dans votre nouveau fichier, en veillant à remplacer your_domain et app_server_address. Si vous n'avez pas de serveur d'applications avec lequel tester, utilisez par défaut http://127.0.0.1:8000 pour la configuration facultative du serveur Gunicorn dans Étape 3 :

/etc/nginx/sites-available/votre_domaine

server {
    listen 80;
    listen [::]:80;

    server_name your_domain www.your_domain;
        
    location / {
        proxy_pass app_server_address;
        include proxy_params;
    }
}

Enregistrez et quittez, avec nano vous pouvez le faire en appuyant sur CTRL+O alors CTRL+X.

Ce fichier de configuration commence par une configuration Nginx standard, où Nginx écoutera sur le port 80 et répondre aux demandes adressées à votre_domaine et www.your_domain. La fonctionnalité de proxy inverse est activée via Nginx proxy_pass directif. Avec cette configuration, naviguer vers votre_domaine dans votre navigateur Web local sera identique à ouvrir app_server_address sur votre machine distante. Alors que ce didacticiel ne servira de proxy qu'à un seul serveur d'applications, Nginx est capable de servir de proxy pour plusieurs serveurs à la fois. En ajoutant plus de blocs d'emplacement selon les besoins, un seul nom de serveur peut combiner plusieurs serveurs d'applications via un proxy en une seule application Web cohérente.

Toutes les requêtes HTTP sont accompagnées d'en-têtes contenant des informations sur le client qui a envoyé la requête. Cela inclut des détails tels que l'adresse IP, les préférences de cache, le suivi des cookies, le statut d'autorisation, etc. Nginx fournit certains paramètres de transfert d'en-tête recommandés que vous avez inclus en tant que proxy_params, et les détails peuvent être trouvés dans /etc/nginx/proxy_params:

/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;

Avec les proxys inverses, votre objectif est de transmettre des informations pertinentes sur le client, et parfois des informations sur votre serveur proxy inverse lui-même. Il existe des cas d'utilisation où un serveur proxy voudrait savoir quel serveur proxy inverse a traité la demande, mais généralement, les informations importantes proviennent de la demande du client d'origine. Afin de transmettre ces en-têtes et de rendre les informations disponibles là où elles sont attendues, Nginx utilise le proxy_set_header directif.

Par défaut, lorsque Nginx agit comme un proxy inverse, il modifie deux en-têtes, supprime tous les en-têtes vides, puis transmet la requête. Les deux en-têtes modifiés sont les Host et Connection entête. Il existe de nombreux en-têtes HTTP disponibles, et vous pouvez consulter cette liste détaillée des en-têtes HTTP pour plus d'informations sur chacun de leurs objectifs, bien que ceux qui concernent les proxys inverses soient traités ici plus tard.

Voici les en-têtes transmis par proxy_params et les variables dans lesquelles il stocke les données :

  • Hôte : cet en-tête contient l'hôte d'origine demandé par le client, qui correspond au domaine et au port du site Web. Nginx conserve cela dans le $http_host variable.
  • X-Forwarded-For : cet en-tête contient l'adresse IP du client qui a envoyé la demande d'origine. Il peut également contenir une liste d'adresses IP, l'adresse IP du client d'origine venant en premier, puis une liste de toutes les adresses IP des serveurs proxy inverses qui ont transmis la demande. Nginx conserve cela dans le $proxy_add_x_forwarded_for variable.
  • X-Real-IP : cet en-tête contient toujours une seule adresse IP qui appartient au client distant. Cela contraste avec le X-Forwarded-For similaire qui peut contenir une liste d'adresses. Si X-Forwarded-For n'est pas présent, ce sera le même que X-Real-IP.
  • X-Forwarded-Proto : cet en-tête contient le protocole utilisé par le client d'origine pour se connecter, que ce soit HTTP ou HTTPS. Nginx conserve cela dans le $scheme variable.

Ensuite, activez ce fichier de configuration en créant un lien de celui-ci vers le sites-enabled répertoire que Nginx lit au démarrage :

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Vous pouvez maintenant tester votre fichier de configuration pour les erreurs de syntaxe :

sudo nginx -t

Si aucun problème n'est signalé, redémarrez Nginx pour appliquer vos modifications :

sudo systemctl restart nginx

Nginx est maintenant configuré en tant que proxy inverse pour votre serveur d'applications et vous pouvez y accéder à partir d'un navigateur local si votre serveur d'applications est en cours d'exécution. Si vous avez un serveur d'applications prévu mais qu'il ne fonctionne pas, vous pouvez procéder au démarrage de votre serveur d'applications prévu. Vous pouvez ignorer le reste de ce didacticiel.

Sinon, passez à la configuration d'une application de test et d'un serveur avec Gunicorn à l'étape suivante.

Étape 3 - Test de votre proxy inverse avec Gunicorn (facultatif)

Si vous aviez un serveur d'applications préparé et en cours d'exécution avant de commencer ce didacticiel, vous pouvez le visiter dans votre navigateur maintenant :

your_domain

Cependant, si vous ne disposez pas d'un serveur d'applications pour tester votre proxy inverse, vous pouvez suivre les étapes suivantes pour installer Gunicorn avec une application de test. Gunicorn est un serveur Python WSGI qui est souvent associé à un proxy inverse Nginx.

Mettez à jour votre apt index du référentiel et installation gunicorn:

sudo apt update
sudo apt install gunicorn

Vous avez également la possibilité d'installer Gunicorn via pip avec PyPI pour la dernière version qui peut être couplée avec un environnement virtuel Python, mais apt sert ici de banc d'essai rapide.

Ensuite, vous allez écrire une fonction Python pour renvoyer "Hello World!" sous forme de réponse HTTP qui s'affichera dans un navigateur Web. Créer test.py utilisant nano ou votre éditeur de texte préféré :

nano test.py

Insérez le code Python suivant dans le fichier :

def app(environ, start_response):
    start_response("200 OK", [])
    return iter([b"Hello, World!"])

Il s'agit du code minimum requis par Gunicorn pour démarrer une réponse HTTP qui affiche une chaîne de texte dans votre navigateur Web. Après avoir examiné le code, enregistrez et fermez votre fichier.

Démarrez maintenant votre serveur Gunicorn, en spécifiant le test module Python et le app fonctionner en son sein. Le démarrage du serveur prendra le contrôle de votre terminal :

gunicorn --workers=2 test:app
Output[2022-08-29 07:09:29 +0000] [10568] [INFO] Starting gunicorn 20.1.0
[2022-08-29 07:09:29 +0000] [10568] [INFO] Listening at: http://127.0.0.1:8000 (10568)
[2022-08-29 07:09:29 +0000] [10568] [INFO] Using worker: sync
[2022-08-29 07:09:29 +0000] [10569] [INFO] Booting worker with pid: 10569
[2022-08-29 07:09:29 +0000] [10570] [INFO] Booting worker with pid: 10570

La sortie confirme que Gunicorn écoute à l'adresse par défaut de http://127.0.0.1:8000. Il s'agit de l'adresse que vous avez configurée précédemment dans votre configuration Nginx pour proxy. Sinon, retournez à votre /etc/nginx/sites-available/your_domain fichier et modifiez le app_server_address associé au proxy_pass directif.

Ouvrez votre navigateur Web et accédez au domaine que vous avez configuré avec Nginx :

your_domain

Votre proxy inverse Nginx sert maintenant votre serveur d'applications Web Gunicorn et affiche "Hello World!".

Conclusion

Avec ce tutoriel, vous avez configuré Nginx en tant que proxy inverse pour permettre l'accès à vos serveurs d'applications qui ne seraient autrement disponibles que localement. De plus, vous avez configuré le transfert des en-têtes de demande, en transmettant les informations d'en-tête du client.

Pour des exemples de solution complète utilisant Nginx comme proxy inverse, consultez comment servir des applications Flask avec Gunicorn et Nginx sur Ubuntu 22.04 ou comment exécuter une interface Meilisearch à l'aide d'InstantSearch sur Ubuntu 22.04 .