Comment utiliser Apache en tant que proxy inverse avec mod_proxy sur Ubuntu 16.04

introduction

Unreverse 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 inversés sont utiles car de nombreuses applications Web modernes traitent les demandes HTTP entrantes à l’aide de serveurs d’applications dorsaux auxquels les utilisateurs ne doivent pas accéder directement et ne prennent souvent en charge que des fonctionnalités HTTP rudimentaires.

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 demandes entrantes vers plusieurs serveurs d’applications différents, augmentant ainsi les performances à l’échelle et offrant une sécurité à l’échec. 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'extensionmod_proxy pour rediriger les connexions entrantes vers un ou plusieurs serveurs backend s'exécutant sur le même réseau. Ce tutoriel utilise un simple backend écrit avec le withFlask web framework, mais vous pouvez utiliser n'importe quel serveur backend de votre choix.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin de:

[[step-1 -—- activate-need-apache-modules]] == Étape 1 - Activation des modules Apache nécessaires

Apache contient de nombreux modules disponibles, mais non activés dans une nouvelle installation. Tout d’abord, nous devons activer ceux que nous utiliserons dans ce tutoriel.

Les modules dont nous avons besoin sontmod_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, nous allons utiliser:

  • mod_proxy, le module Apache principal du module proxy pour la redirection des connexions; il permet à Apache d'agir comme une passerelle vers les serveurs d'applications sous-jacents.

  • mod_proxy_http, qui ajoute la prise en charge des connexions HTTP par proxy.

  • mod_proxy_balancer etmod_lbmethod_byrequests, qui ajoutent des fonctionnalités d'équilibrage de charge pour plusieurs serveurs backend.

Pour activer ces quatre modules, exécutez les commandes suivantes successivement.

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod 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), nous allons créer deux serveurs principaux très basiques. Cela nous aidera à vérifier si la configuration fonctionne correctement, mais si vous avez déjà votre propre application (s) dorsale (s), vous pouvez passer à l'étape 3.

[[step-2 -—- creating-backend-test-servers]] == Étape 2 - Création de serveurs de test backend

L'exécution de serveurs dorsaux simples constitue un moyen simple de vérifier si votre configuration Apache fonctionne correctement. Ici, nous allons créer deux serveurs de test qui répondent aux requêtes HTTP en imprimant une ligne de texte. Un serveur diraHello world! et l'autre diraHowdy world!.

[.note] #Note: Dans les configurations sans test, les serveurs principaux renvoient généralement tous le même type de contenu. Cependant, pour ce test en particulier, le fait que les deux serveurs renvoient des messages différents permet de vérifier facilement que le mécanisme d'équilibrage de charge utilise les deux.
#

Flask est un microframework Python pour la construction d'applications Web. Nous utilisons Flask pour créer les serveurs de test, car une application de base 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 consulterthese Python tutorials.

Mettez à jour la liste des packages en premier.

sudo apt-get update

Ensuite, installez Pip, le gestionnaire de paquets Python recommandé.

sudo apt-get -y install python3-pip

Utilisez Pip pour installer Flask.

sudo pip3 install flask

Maintenant que tous les composants requis sont installés, commencez par créer un nouveau fichier qui contiendra le code du premier serveur principal dans le répertoire de base de l'utilisateur actuel.

nano ~/backend1.py

Copiez le code suivant dans le fichier, puis enregistrez et fermez-le.

~/backend1.py

from flask import Flask
app = Flask(__name__)

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

Les deux premières lignes 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 fonctionhome() indique à Flask d'utiliser la valeur de retour dehome() comme réponse aux requêtes HTTP dirigées vers l'URL racine/ de l'application.

Le deuxième serveur principal est identique au premier, à l'exception du retour à une ligne de texte différente. Commencez donc par dupliquer le premier fichier.

cp ~/backend1.py ~/backend2.py

Ouvrez le fichier récemment copié.

nano ~/backend2.py

Modifiez le message à renvoyer deHello world! àHowdy world!, puis enregistrez et fermez le fichier.

~/backend2.py

from flask import Flask
app = Flask(__name__)

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

Utilisez la commande suivante pour démarrer le premier serveur d'arrière-plan sur le port8080. Cela redirige également la sortie de Flask vers/dev/null car cela nuirait plus loin à la sortie de la console.

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

Ici, nous précédons la commandeflask en définissant la variable d'environnementFLASK_APP sur la même ligne. Les variables d'environnement constituent 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 dansHow To Read and Set Environmental and Shell Variables on a Linux VPS.

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, car nous passerons un autre nom de fichier de la même manière pour indiquer à la commandeflask de démarrer le deuxième serveur

De même, utilisez cette commande pour démarrer le deuxième serveur sur le port8081. Notez la valeur différente de la variable d'environnementFLASK_APP.

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

Vous pouvez tester que les deux serveurs fonctionnent à l'aide decurl. Testez le premier serveur:

curl http://127.0.0.1:8080/

Cela afficheraHello world! dans le terminal. Testez le deuxième serveur:

curl http://127.0.0.1:8081/

Cela afficheraHowdy world! à la place.

[.note] #Note: pour fermer les deux serveurs de test une fois que vous n'en avez plus besoin, comme lorsque vous avez terminé ce tutoriel, vous pouvez simplement exécuterkillall flask.
#

Dans l’étape suivante, nous modifierons le fichier de configuration d’Apache pour permettre son utilisation en tant que proxy inverse.

[[step-3 -—- modifying-the-default-configuration-to-enable-reverse-proxy]] == Étape 3 - Modification de la configuration par défaut pour activer le proxy inverse

Dans cette section, nous allons configurer l'hôte virtuel Apache par défaut pour qu'il serve de proxy inverse pour un serveur dorsal unique ou un tableau de serveurs dorsaux à charge équilibrée.

[.Remarque]##

Note: dans ce didacticiel, nous appliquons 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 ce tutoriel deHow To Set Up Apache Virtual Hosts on Ubuntu 16.04.

Si votre serveur Apache agit à la fois comme serveur HTTP et HTTPS, votre configuration de proxy inverse doit être placée dans les hôtes virtuels HTTP et HTTPS. Pour en savoir plus sur SSL avec Apache, vous pouvez lire ce tutoriel deHow To Create a Self-Signed SSL Certificate for Apache in Ubuntu 16.04.

Ouvrez le fichier de configuration Apache par défaut à l'aide denano ou 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 ci-dessous explique comment configurer ce bloc pour inverser le proxy pour un seul serveur dorsal, et le second configure un proxy inverse à charge équilibrée pour plusieurs serveurs dorsaux.

[[example-1 -—- reverse-proxy-a-single-backend-server]] === Exemple 1 - Reverse Proxying d'un seul serveur backend

Remplacez tout le contenu du blocVirtualHost par ce qui suit, pour que votre fichier de configuration ressemble à ceci:

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


    ProxyPreserveHost On

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

Si vous avez suivi les exemples de serveurs à l'étape 2, utilisez127.0.0.1:8080 comme indiqué dans le bloc ci-dessus. Si vous avez vos propres serveurs d'applications, utilisez plutôt leurs adresses.

Il y a trois directives ici:

  • ProxyPreserveHost oblige Apache à transmettre l'en-têteHost d'origine au serveur backend. Ceci est utile car il informe le serveur principal de l'adresse utilisée pour accéder à l'application.

  • ProxyPass est 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 retournera la réponse au client d'origine.

  • ProxyPassReverse doit avoir la même configuration queProxyPass. Il demande à Apache de modifier les en-têtes de réponse du serveur principal. Cela garantit que si le serveur back-end retourne un en-tête de redirection d'emplacement, le navigateur du client sera redirigé vers l'adresse proxy et non l'adresse du serveur back-end, ce qui ne fonctionnerait pas comme prévu.

Pour appliquer ces modifications, redémarrez Apache.

sudo systemctl restart apache2

Maintenant, 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 verrezHellow world!.

[[example-2 -—- load-balancing-across-multiple-backend-servers]] === Exemple 2 - Équilibrage de charge sur plusieurs serveurs backend

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

Remplacez tout le contenu du blocVirtualHost par ce qui suit, afin que votre fichier de configuration ressemble à ceci:

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



    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:8081


    ProxyPreserveHost On

    ProxyPass / balancer://mycluster/
    ProxyPassReverse / balancer://mycluster/

La configuration est similaire à la précédente, mais au lieu de spécifier directement un seul serveur backend, nous avons utilisé un blocProxy supplémentaire pour définir plusieurs serveurs. Le bloc est nommébalancer://mycluster (le nom peut être librement modifié) et se compose d'une ou plusieurs directivesBalancerMember+`s, which specify the underlying backend server addresses. The `+ProxyPass etProxyPassReverse utilisent le pool d'équilibrage de charge nommémycluster au lieu d'un serveur.

Si vous avez suivi les exemples de serveurs à l'étape 2, utilisez127.0.0.1:8080 et127.0.0.1:8081 pour les directivesBalancerMember, comme indiqué dans le bloc ci-dessus. Si vous avez vos propres serveurs d'applications, utilisez plutôt leurs adresses.

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 backend au lieu de la page Apache standard. Si vous avez suivi l'étape 2, l'actualisation de la page plusieurs fois devrait afficherHello world! etHowdy world!, ce qui signifie que le proxy inverse a fonctionné et qu'il équilibre la charge entre les deux serveurs.

Conclusion

Vous savez maintenant comment configurer Apache en tant que proxy inverse sur un ou plusieurs serveurs d'applications sous-jacents. mod_proxy peut être utilisé efficacement pour configurer le proxy inverse vers des serveurs d'applications écrits dans un vaste éventail 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 des sites très fréquentés ou pour offrir une haute disponibilité via plusieurs serveurs, ou pour fournir une prise en charge SSL sécurisée à des serveurs dorsaux ne prenant pas SSL en charge de manière native.

Bien quemod_proxy avecmod_proxy_http soit la combinaison de modules peut-être la plus couramment utilisée, il en existe plusieurs autres qui prennent en charge différents protocoles réseau. Nous ne les avons pas utilisés ici, mais certains autres modules populaires incluent:

  • mod_proxy_ftp pour FTP.

  • 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 sockets Web.

Pour en savoir plus surmod_proxy, vous pouvez lirethe official Apache mod_proxy documentation.