Comment utiliser Apache comme proxy inverse avec mod proxy sur Ubuntu 20.04

De Get Docs
Aller à :navigation, rechercher

Introduction

Un reverse proxy est un type de serveur proxy qui prend les requêtes HTTP(S) et les distribue de manière transparente à un ou plusieurs serveurs principaux. Les proxys inverses sont utiles car de nombreuses applications Web modernes traitent les requêtes HTTP entrantes à l'aide de serveurs d'applications principaux. Ces serveurs ne sont pas destinés à être accessibles directement aux utilisateurs et ne prennent souvent en charge que les fonctionnalités HTTP de base.

Vous pouvez utiliser un proxy inverse pour empêcher l'accès direct à ces serveurs d'applications sous-jacents. Ils peuvent également être utilisés pour répartir la charge des requêtes entrantes sur plusieurs serveurs d'applications différents, augmentant ainsi les performances à grande échelle et offrant une sécurité intégrée. Ils peuvent combler les lacunes avec des fonctionnalités que les serveurs d'applications n'offrent pas, telles que la mise en cache, la compression ou le cryptage SSL.

Dans ce didacticiel, vous allez configurer Apache en tant que proxy inverse de base à l'aide de l'extension mod_proxy pour rediriger les connexions entrantes vers un ou plusieurs serveurs principaux s'exécutant sur le même réseau. Ce didacticiel utilise un backend écrit avec le Flask web framework, mais vous pouvez utiliser n'importe quel serveur backend que vous préférez.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de :

Étape 1 - Activation des modules Apache nécessaires

Apache contient de nombreux modules qui sont disponibles mais non activés dans une nouvelle installation. Tout d'abord, vous devrez activer ceux que vous utiliserez dans ce didacticiel.

Les modules dont vous avez besoin sont mod_proxy lui-même et plusieurs de ses modules complémentaires, qui étendent ses fonctionnalités pour prendre en charge différents protocoles réseau. Plus précisément, vous utiliserez les éléments suivants :

  • mod_proxy : le module proxy principal pour rediriger les connexions. Il permet à Apache d'agir comme une passerelle vers les serveurs d'applications sous-jacents.
  • mod_proxy_http : ajoute la prise en charge des connexions HTTP par proxy.
  • mod_proxy_balancer et mod_lbmethod_byrequests : ces éléments ajoutent des fonctionnalités d'équilibrage de charge pour plusieurs serveurs principaux.

Pour activer ces quatre modules, exécutez la commande suivante :

sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests

Pour appliquer ces modifications, redémarrez Apache :

sudo systemctl restart apache2

Apache est maintenant prêt à agir en tant que proxy inverse pour les requêtes HTTP. Dans la prochaine étape facultative, vous allez créer deux serveurs principaux de base. Ceux-ci aideront à vérifier si la configuration fonctionne correctement, mais si vous avez déjà votre propre application backend, vous pouvez passer à Étape 3.

Étape 2 - Création de serveurs de test principaux (recommandé)

L'exécution de certains serveurs principaux peut aider à tester si votre configuration Apache fonctionne correctement. Ici, vous allez créer deux serveurs de test qui répondent aux requêtes HTTP en imprimant une ligne de texte. Un serveur dira Hello world! et l'autre dira Howdy world! Cela vous permettra de tester l'équilibrage de charge entre plusieurs services.

Remarque : Dans les configurations réelles, les serveurs principaux renvoient généralement tous le même type de contenu. Cependant, pour les besoins de ce test, le fait que les deux serveurs renvoient des messages différents permet de vérifier que le mécanisme d'équilibrage de charge utilise les deux.


Flask est un microframework Python pour la création d'applications Web. Cette étape explique comment utiliser Flask pour créer les serveurs de test, car une application minimale ne nécessite que quelques lignes de code. Vous n'avez pas besoin de connaître Python pour les configurer, mais si vous souhaitez apprendre, vous pouvez consulter notre série sur Comment coder en Python.

Commencez par mettre à jour la liste d'index des packages à l'aide de apt :

sudo apt update

Installez ensuite pip, le gestionnaire de packages Python recommandé :

sudo apt install python3-pip

Ensuite, utilisez pip pour installer Flask :

sudo pip3 install Flask

Maintenant que tous les composants requis sont installés, créez un nouveau fichier qui contiendra le code du premier serveur principal dans le répertoire personnel de l'utilisateur actuel. Vous pouvez le faire avec votre éditeur de texte préféré, ici nous utiliserons nano :

nano ~/backend1.py

Insérez l'extrait de code suivant dans le fichier :

~/backend1.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello world!'

Les deux premières lignes de code initialisent le framework Flask. Il existe une fonction, home(), qui renvoie une ligne de texte (Hello world!). La ligne @app.route('/') au-dessus de la définition de la fonction home() indique à Flask d'utiliser la valeur de retour de home()' en réponse aux requêtes HTTP adressées à la racine /. URL de l'application.

Une fois que vous avez terminé, enregistrez et quittez le fichier. Si vous utilisez nano, vous pouvez le faire en appuyant sur CTRL + X, puis sur Y et ENTER.

Le deuxième serveur principal est exactement le même que le premier, mis à part le renvoi d'une ligne de texte différente. Par conséquent, exécutez cp pour copier le contenu du premier fichier, backend1.py dans le fichier backend2.py :

cp ~/backend1.py ~/backend2.py

Ouvrez maintenant le fichier nouvellement copié à l'aide de votre éditeur de texte préféré :

nano ~/backend2.py

Mettez à jour le message qui renvoie le message Hello world! pour lire Howdy world! à la place :

~/backend2.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return 'Howdy world!'

Une fois la mise à jour terminée, enregistrez et fermez le fichier.

Ensuite, utilisez la commande suivante pour démarrer le premier serveur d'arrière-plan sur le port 8080. Cela redirige également la sortie de Flask vers /dev/null car cela brouillerait la sortie de la console plus loin :

FLASK_APP=~/backend1.py flask run --port=8080 >/dev/null 2>&1 &

Ici, vous faites précéder la commande flask en définissant la variable d'environnement FLASK_APP sur la même ligne. Les variables d'environnement sont un moyen pratique de transmettre des informations aux processus générés à partir du shell. Vous pouvez en savoir plus sur les variables d'environnement dans notre guide sur Comment lire et définir des variables d'environnement et de shell sur un VPS Linux.

Dans ce cas, l'utilisation d'une variable d'environnement garantit que le paramètre s'applique uniquement à la commande en cours d'exécution et ne restera pas disponible par la suite. Ceci est nécessaire pour éviter toute confusion car vous passerez un autre nom de fichier de la même manière pour indiquer à la commande flask de démarrer le deuxième serveur.

De même, vous souhaitez exécuter la commande suivante pour démarrer le deuxième serveur sur le port 8081. Notez la valeur différente de la variable d'environnement FLASK_APP :

FLASK_APP=~/backend2.py flask run --port=8081 >/dev/null 2>&1 &

Vous pouvez maintenant tester si les deux serveurs fonctionnent en utilisant la commande curl. Commencez par tester le premier serveur. Cette commande utilise curl pour se connecter à 127.0.0.1, une adresse IP spéciale qui représente localhost. Cela signifie que la commande suivante indique à votre serveur de se connecter à lui-même et d'imprimer sa propre réponse :

curl http://127.0.0.1:8080/

Cela imprimera la réponse suivante du serveur :

OutputHello world!

Ensuite, testez le second serveur :

curl http://127.0.0.1:8081/

Comme précédemment, cela imprimera la réponse attendue du serveur :

OutputHowdy world!

Dans l'étape suivante, vous modifierez le fichier de configuration d'Apache pour permettre son utilisation en tant que proxy inverse.

Étape 3 - Modification de la configuration par défaut pour activer le proxy inverse

Dans cette section, vous configurerez l'hôte virtuel Apache par défaut pour qu'il serve de proxy inverse pour un seul serveur principal ou un ensemble de serveurs principaux à charge équilibrée.

Remarque : Dans ce didacticiel, vous appliquez la configuration au niveau de l'hôte virtuel. Sur une installation par défaut d'Apache, il n'y a qu'un seul hôte virtuel par défaut activé. Cependant, vous pouvez également utiliser tous ces fragments de configuration dans d'autres hôtes virtuels. Pour en savoir plus sur les hôtes virtuels dans Apache, vous pouvez lire notre tutoriel Comment configurer des hôtes virtuels Apache sur Ubuntu 20.04.

Si votre serveur Apache agit à la fois comme un serveur HTTP et HTTPS, votre configuration de proxy inverse doit être placée à la fois dans les hôtes virtuels HTTP et HTTPS. Pour en savoir plus sur SSL avec Apache, vous pouvez lire notre tutoriel sur Comment créer un certificat SSL auto-signé pour Apache dans Ubuntu 20.04.


Ouvrez le fichier de configuration Apache par défaut à l'aide de votre éditeur de texte préféré :

sudo nano /etc/apache2/sites-available/000-default.conf

Dans ce fichier, vous trouverez le bloc <VirtualHost *:80> commençant sur la première ligne. Le premier exemple suivant explique comment configurer ce bloc pour inverser le proxy pour un seul serveur principal, et le deuxième exemple configure un proxy inverse à charge équilibrée pour plusieurs serveurs principaux.

Exemple 1 — Proxy inverse d'un seul serveur principal

Tout d'abord, remplacez tout le contenu du bloc VirtualHost afin que votre fichier de configuration se lise comme suit. Si vous avez suivi les exemples de serveurs dans Étape 2, utilisez 127.0.0.1:8080. Si vous avez vos propres serveurs d'applications, utilisez plutôt leurs adresses :

/etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

Il y a trois directives représentées, voici un bref aperçu de ce qu'elles font :

  • ProxyPreserveHost : oblige Apache à transmettre l'en-tête d'origine Host au serveur principal. Ceci est utile car cela permet au serveur principal de connaître l'adresse utilisée pour accéder à l'application.
  • ProxyPass : la principale directive de configuration du proxy. Dans ce cas, il spécifie que tout ce qui se trouve sous l'URL racine (/) doit être mappé sur le serveur principal à l'adresse donnée. Par exemple, si Apache reçoit une requête pour /example, il se connectera à http://your_backend_server/example et renverra la réponse au client d'origine.
  • ProxyPassReverse : doit avoir la même configuration que ProxyPass. Il indique à Apache de modifier les en-têtes de réponse du serveur principal. Cela garantit que si le serveur principal renvoie un en-tête de redirection d'emplacement, le navigateur du client sera redirigé vers l'adresse proxy et non vers l'adresse du serveur principal, ce qui ne fonctionnerait pas comme prévu.

Une fois que vous avez terminé d'ajouter ce contenu, enregistrez et quittez le fichier.

Pour appliquer ces modifications, redémarrez Apache :

sudo systemctl restart apache2

Désormais, si vous accédez à http://your_server_ip dans un navigateur Web, vous verrez la réponse de votre serveur principal au lieu de la page d'accueil standard d'Apache. Si vous avez suivi l'Étape 2, cela signifie que vous verrez Hello world! dans le navigateur.

Exemple 2 - Équilibrage de charge sur plusieurs serveurs principaux

Si vous avez plusieurs serveurs principaux, un bon moyen de répartir le trafic sur eux lors du proxy consiste à utiliser les fonctionnalités d'équilibrage de charge de mod_proxy.

Ouvrez d'abord le fichier de configuration Apache par défaut à l'aide de votre éditeur de texte préféré :

sudo nano /etc/apache2/sites-available/000-default.conf

Remplacez maintenant tout le contenu du VirtualHost afin que votre fichier de configuration se lise comme suit. Si vous avez suivi les exemples de serveurs dans Étape 2, utilisez 127.0.0.1:8080 et 127.0.0.1:8081 pour les directives BalancerMember. Si vous avez vos propres serveurs d'applications, utilisez plutôt leurs adresses :

/etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:8081
</Proxy>

    ProxyPreserveHost On

    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/
</VirtualHost>

La configuration est similaire à la précédente, mais au lieu de spécifier directement un seul serveur principal, ces directives font ce qui suit :

  • Proxy : ce bloc Proxy supplémentaire est utilisé pour définir plusieurs serveurs. Le bloc est nommé balancer://mycluster (le nom peut être modifié librement) et se compose d'un ou plusieurs BalancerMember, qui spécifient les adresses de serveur principal sous-jacentes.
  • ProxyPass et ProxyPassReverse: these directives use the load balancer pool named mycluster` au lieu d'un serveur spécifique.

Si vous avez suivi les exemples de serveurs dans Étape 2, utilisez 127.0.0.1:8080 et 127.0.0.1:8081 pour les directives BalancerMember, comme écrit dans le bloc ci-dessus. Si vous avez vos propres serveurs d'applications, utilisez plutôt leurs adresses.

Une fois que vous avez terminé d'ajouter ce contenu, enregistrez et quittez le fichier.

Pour appliquer ces modifications, redémarrez Apache :

sudo systemctl restart apache2

Si vous accédez à http://your_server_ip dans un navigateur Web, vous verrez les réponses de vos serveurs principaux au lieu de la page Apache standard. Si vous avez suivi l'Étape 2, l'actualisation de la page plusieurs fois devrait afficher Hello world ! et Howdy world !, ce qui signifie que le proxy inverse a fonctionné et que la charge est équilibrée entre les deux serveurs.

Remarque : Pour fermer les deux serveurs de test lorsque vous n'en avez plus besoin, comme lorsque vous avez terminé ce didacticiel, vous pouvez exécuter la commande killall flask.


Conclusion

Vous savez maintenant comment configurer Apache en tant que proxy inverse pour un ou plusieurs serveurs d'applications sous-jacents. mod_proxy peut être utilisé efficacement pour configurer un proxy inverse vers des serveurs d'applications écrits dans une vaste gamme de langages et de technologies, tels que Python et Django, ou Ruby et Ruby on Rails. Il peut également être utilisé pour équilibrer le trafic entre plusieurs serveurs principaux pour les sites à fort trafic, pour fournir une haute disponibilité via plusieurs serveurs ou pour fournir une prise en charge SSL sécurisée aux serveurs principaux ne prenant pas en charge SSL de manière native.

Alors que mod_proxy avec mod_proxy_http est peut-être la combinaison de modules la plus couramment utilisée, il en existe plusieurs autres qui prennent en charge différents protocoles réseau. Vous ne les avez pas utilisés dans ce didacticiel, mais certains autres modules populaires incluent :

  • mod_proxy_ftp pour FTP (protocole de transfert de fichiers).
  • mod_proxy_connect pour le tunnel SSL.
  • mod_proxy_ajp pour AJP (Apache JServ Protocol), comme les backends basés sur Tomcat.
  • mod_proxy_wstunnel pour les prises Web.

Pour en savoir plus sur mod_proxy, vous pouvez lire la documentation officielle Apache mod_proxy.