Lundi 14 octobre 2019

Guide d’utilisation d’un proxy inverse pour HTTP(S), SSH et MySQL/MariaDB à l’aide de NGINX

Ce guide vous guidera à travers l’installation et la configuration de NGINX afin de permettre l’exécution de plusieurs serveurs physiques, de machines virtuelles ou d’une combinaison des deux derrière une seule adresse IP publique. Vous pouvez choisir d’exécuter un certain nombre de serveurs Web sur des machines virtuelles et de les administrer localement, ou d’utiliser des outils d’accès à distance, tels que SSH, sur chacun des hôtes. Par exemple, si l’accès local sera indisponible en dehors des heures normales de bureau. Ce guide peut faciliter les deux scénarios.

Les configurations présentées ici conviendraient le mieux à un laboratoire domestique ou à un réseau de petite entreprise ayant des limitations sur les adresses IP publiques disponibles. Il y aurait peu de raisons, le cas échéant, d’exécuter une configuration telle que celle-ci, lorsque plusieurs serveurs ou machines virtuelles sont loués à partir d’un service d’hébergement, vous obtiendrez de toute façon une adresse IP publique pour chaque serveur ou hôte.

Je vais vous montrer comment installer NGINX et faire des configurations qui permettront au serveur d’agir en tant que proxy inverse pour HTTP (S), SSH, FTP et MySQL / MariaDB.

Sans plus tarder - Mise en route

Dans ce guide, j’utiliserai les noms d’hôte et les adresses IP suivants.

rproxy.example.com  192.168.1.1
web1.example.com    192.168.1.2
db1.exmple.com      192.168.1.3

Préparer le serveur hôte

Dans votre console shell (navigateur ou directement connecté)

sudo nano /etc/ssh/sshd_config 

Décommentez les lignes:

  • Port modifiez le numéro de port en 23456
  • ListenAddress et changez-le en 0.0.0.0

Pour ceux qui ne connaissent peut-être pas nano, appuyez sur CTRL + X, tapez y, puis appuyez sur Entrée. Cela permettra de sauvegarder et de fermer un fichier. Si aucune modification n’a été apportée au fichier, CTRL + x fermera le fichier sans demander la sauvegarde. Vous serez renvoyé à l’invite de commande.

Une fois les modifications terminées, vous devrez redémarrer le serveur ssh pour que les modifications prennent effet. Votre connexion actuelle n’est pas affectée par ce redémarrage.

systemctl restart ssh 

Vérifiez que vous pouvez vous connecter à l’aide de SSH à partir d’un terminal situé sur un autre ordinateur de votre réseau local.

ssh user@192.168.1.1 -p23456 

Laissez ce terminal ouvert après vous être connecté avec SSH et déconnectez-vous de la console / du serveur. Vous n’avez plus besoin de l’utiliser pour le reste de ce guide.

À partir de ce moment, vous exécuterez des commandes au niveau racine à partir de votre terminal. La commande suivante éliminera le besoin d’ajouter des commandes suivantes avec sudo.

sudo -s 

Mettez à jour la base de données de packages Apt et mettez à niveau Ubuntu pour vous assurer que vous disposez des packages les plus récents.

apt update && apt -y upgrade 

Si quelque chose au cours de la mise à niveau indique que de nouveaux noyaux ont été installés, vous devez redémarrer l’ordinateur une fois que la mise à niveau est terminée pour vous assurer que vous travaillez sur un système entièrement mis à jour.

Définition du nom d’hôte du serveur proxy inverse

hostnamectl set-hostname rproxy.example.com

Si vous utilisez un serveur virtuel, vous pouvez avoir un fichier nommé cloud.cfg qui doit être modifié pour conserver le nom d’hôte défini ici. La commande suivante affichera un fichier avec un contenu ou une page vide. Si vous voyez une page vide, vous pouvez simplement CTRL + x et ignorer cette étape, car vous n’avez rien à faire.

nano /etc/cloud/cloud.cfg 

Modifiez la ligne de préservation du nom d’hôte en true et fermez / enregistrez le fichier.

If your system is currently local only you will need to show this server where your other servers/virtual hosts are.

nano /etc/hosts 

Le fichier hosts ressemblera à ceci après les modifications. Les adresses IP et les hôtes doivent correspondre à votre propre infrastructure (Ceci concerne rproxy.example.com, 192.168.1.2 web1.example.com, 192.168.1.3 db1.example.com)

127.0.0.1 localhost
127.0.1.1  rproxy.example.com
192.168.1.2    web1.example.com
192.168.1.3    db1.example.com

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Installer NGINX

apt install -y nginx 

Après l’installation, vous devriez vérifier votre version de NGINX. Il est primordial que vous disposiez d’une version 1.9 ou supérieure pour vous permettre d’inverser le proxy pour SSH et MySQL / MariaDB.

nginx -v 

Comme vous pouvez le constater, la version 1.14 de NGINX est installée, ce qui correspond à la configuration par défaut sous Ubuntu 18.04 (10 octobre 2019).

nginx version: nginx/1.14.0 (Ubuntu) 

Préparation de NGINX pour qu’il fonctionne comme un proxy inverse

Avec cette configuration, vous ne servirez aucun site Web directement à partir du serveur hôte de proxy inverse. Vous allez créer une nouvelle structure de répertoire sous /etc/nginx/. Cela préservera les configurations NGINX par défaut si vous souhaitez annuler ces modifications ultérieurement ou si vous décidez que vous souhaitez également servir les sites Web directement à partir de cet hôte. Il est possible d’exécuter la configuration par défaut avec ces configurations de proxy inverse. Toutefois, si Apache2 se trouve sur le même serveur, des ports de substitution sont nécessaires pour l’écoute et vous devez toujours utiliser un proxy inverse pour les sites Web que cette instance d’Apache2 sert.

Construire la structure de répertoire du proxy inverse

cd /etc/nginx && mkdir rproxy && cd rproxy && mkdir http http/available http/enabled stream stream/available stream/enabled

Maintenant que la structure est en place, vous pouvez créer les fichiers de configuration. J’utilise nano mais vous pouvez utiliser l’éditeur avec lequel vous vous sentez à l’aise. Nano créera / mettra à jour les fichiers lors de la sauvegarde.

Before you proceed, open an empty document on your computer or get a pen and paper to note down the ports you configure.

Configuration des serveurs proxy Web (http)

Créez le (s) fichier (s) de configuration http pour le (s) site (s) internet en conséquence

nano http/available/example.com.conf

Copiez le bloc serveur dans la page ouverte dans le terminal avec nano ajustant en conséquence example.com www.example.com, 192.168.1.2.

# Note down ports 80 and 443

server {
    server_name example.com www.example.com;
    listen 80;
    set $upstream 192.168.1.2;
    location / {
         proxy_pass_header Authorization;
         proxy_pass http://$upstream;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_http_version 1.1;
         proxy_set_header Connection "";
         proxy_buffering off;
         client_max_body_size 0;
         proxy_read_timeout 10000s;
         proxy_redirect off;
     }
}

Configuration des proxies inversés SSH, MySQL/MariaDB (stream/flux)

Avant de poursuivre, décidez lequel vous souhaitez utiliser, par hôte ou par service.

  • Par hôte : vous allez créer une configuration pour chaque hôte, ce qui peut être utile pour modifier rapidement les paramètres d’un seul hôte.
  • Par service : vous aurez les ports de service pour tous les serveurs dans un fichier pour chacun, SSH, MySQL / MariaDB et FTP.

Utilisation des configurations par service

Ajoutez les configurations SSH.

nano stream/available/ssh.conf 
# Notez les ports d'écoute
# Note down the listen ports

upstream web1-ssh {
  server 192.168.1.2:22;
}

server {
  listen 22002;
  proxy_pass web1-ssh;
}

upstream db1-ssh {
  server 192.168.1.3:22;
}

server {
  listen 22003;
  proxy_pass db1-ssh;
}

# Add as many upstream and server block pairs as you will need for your remote accessed SSH servers. # Ajoutez autant de paires de blocs en amont et de serveurs que vous en aurez besoin pour vos serveurs SSH accessibles à distance.

Ajoutez les configurations MySQL / MariaDB.

nano stream/available/db.conf 
# Notez les ports d'écoute
# Note down the listen ports

upsteam db1-mysql {
  server 192.168.1.3:3306;
}

server {
  listen 33063;
  proxy_pass db1-mysql;
}

# Add as many upstream/server block pairs as you will need for your remote accessed MySQL/MariaDB servers to this file.
# Ajoutez à ce fichier autant de paires de blocs amont / serveur dont vous aurez besoin pour les serveurs MySQL / MariaDB auxquels vous avez accédé à distance.

Créez maintenant les configurations de proxy inverse FTP.

nano stream/available/ftp.conf 
upstream web1-ftp {
  server 192.168.1.3:21
}

server {
  listen 21002;
  proxy_pass web1-ftp;
}

# Add as many upstream/server block pairs as you will need for your remote accessed FTP servers.
# Ajoutez autant de paires de blocs amont / serveur que vous en aurez besoin pour vos serveurs FTP accessibles à distance.

Utilisation des fichiers de configuration par hôte

nano /etc/nginx/rproxy/stream/available/web1.example.com.conf 
# Notez les ports d'écoute
# Note down the listen ports

upstream web1-ssh {
  server 192.168.1.3:22;
}

server {
  listen 22002;
  proxy_pass web-ssh;
}

Création du fichier hôte pour db1.example.com

nano /etc/nginx/rproxy/stream/available/db1.example.com.conf 
# Notez les ports d'écoute
# Note down the listen ports

upsteam db1-mysql {
  server 192.168.1.3:3306;
}

server {
  listen 33063;
  proxy_pass db1-mysql;
}

upstream db1-ssh {
  server 192.168.1.3:22;
}

server {
  listen 22003;
  proxy_pass db1-ssh;
}

Comme vous pouvez le voir, c’est un peu peu orthodoxe. Vous utilisez des ports publics de manière non standard, en choisissant les ports dont vous avez besoin, puis en les dirigeant vers NGINX. Cela serait normal, sauf que vous utilisez maintenant un port différent pour chaque service sur chaque serveur auquel vous souhaitez accéder à distance. Cela signifie, en prenant SSH comme exemple, un numéro de port différent pour chaque hôte activé par SSH 22 222 2222 22222, par exemple, pointerait vers le port 22 sur quatre serveurs ou machines virtuelles différents.

Ce n’est pas le cas pour NGINX à inverser le proxy pour les sites Web, tant que NGINX a une configuration de serveur définie pour un site Web, il fonctionnera correctement avec uniquement les ports 80 et 443 qui lui sont transférés.

À ce stade, vous avez probablement compris que vous pouviez simplement utiliser les étapes HTTP et ignorer les étapes de flux au lieu de transférer plusieurs ports pour plusieurs services vers le serveur / l’adresse IP approprié. En effet, cela peut être fait. Cependant, cela ajouterait une autre couche de complexité et deviendrait difficile à maintenir avec l’augmentation du nombre de serveurs, car vous devrez peut-être modifier les ports par défaut de chaque serveur pour ssh, mysql et ftp. Cette configuration est déjà complexe, mais cela pourrait être fait si vous le vouliez.

En utilisant un proxy inverse pour ces services, comme je l’ai déjà montré, vous réduisez la complexité de manière significative en fournissant un emplacement unique pour effectuer ces modifications de configuration. Vous n’avez pas besoin de modifier les ports de l’ensemble de votre infrastructure.

En prime, les autres serveurs de votre infrastructure n’ont besoin d’écouter que sur les interfaces locales et les ports par défaut si c’est ce que vous préférez. Si vous gérez localement, vous pouvez utiliser les adresses IP locales et les ports de service par défaut pour accéder aux services requis. Ainsi, vous n’avez pas besoin de référencer vos notes pour mémoriser les ports corrects, il vous suffit de connaître l’adresse IP et les informations d’identification de connexion.

Tout rassembler

Pour commencer à utiliser les configurations de proxy inverse NGINX, vous devez apporter des modifications au fichier de configuration principal. Mettez en commentaire la ligne d’inclusion actuelle dans le bloc http (si vous ne servez pas également de sites Web directement à partir de NGINX).

cd /etc/nginx 

Notez les parties ci-dessous pour déterminer les éléments à modifier.

        include /etc/nginx/conf.d/*.conf;
#       include /etc/nginx/sites-enabled/*;

        # Reverse proxy http configuration files.
        include /etc/nginx/rproxy/http/enabled/*.conf;
}

stream {

    # Reverse proxy stream configuration files.
    include /etc/nginx/rproxy/streams/enabled/*.conf;
}
 nano nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascri$

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
#       include /etc/nginx/sites-enabled/*;

        # Reverse proxy http configuration files.
        include /etc/nginx/rproxy/http/enabled/*.conf;
}

stream {

    # Reverse proxy stream configuration files.
    include /etc/nginx/rproxy/streams/enabled/*.conf;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
# 
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}
    

Activer les configurations de proxy inverse.

Tout d’abord, activez toutes les configurations http

ln -s /etc/nginx/rproxy/http/available/*.conf /etc/nginx/rproxy/http/enabled

Activer toutes les configurations de flux

ln -s /etc/nginx/rproxy/stream/available/*.conf /etc/nginx/rproxy/stream/enabled

Effectuez un test pour vérifier que la configuration de NGINX en tant que proxy inverse est correcte.

nginx -T 

Dans la sortie, vous devriez voir un message de réussite avec toutes les configurations personnalisées que vous avez effectuées précédemment.

Redémarrez NGINX pour activer les configurations de proxy inverse.

systemctl restart nginx 

Vérifiez que NGINX est à l’écoute sur tous les ports configurés. vérifiez sur vos notes que tous les ports sont indiqués dans les résultats.

netstat -tulpn | grep nginx 

La sortie devrait ressembler à quelque chose comme ça

tcp        0      0 0.0.0.0:22           0.0.0.0:*               LISTEN      4964/nginx: master  
tcp        0      0 0.0.0.0:22002           0.0.0.0:*               LISTEN      4964/nginx: master  
tcp        0      0 0.0.0.0:22003           0.0.0.0:*               LISTEN      4964/nginx: master
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4964/nginx: master  
tcp        0      0 0.0.0.0:33062           0.0.0.0:*               LISTEN      4964/nginx: master  
tcp        0      0 0.0.0.0:33063           0.0.0.0:*               LISTEN      4964/nginx: master  
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      4964/nginx: master  

Ouvrir le serveur pour le trafic

Maintenant que NGINX est à l’écoute et prêt à agir en tant que proxy inverse pour toutes les connexions pour lesquelles nous souhaitons autoriser le trafic, désactivez temporairement UFW lors des étapes suivantes. Cela facilitera le dépannage si les choses ne fonctionnent pas correctement.

ufw disable 

Ports de transfert

Malheureusement, je suis incapable de vous guider ici. Vous devrez consulter le manuel de votre routeur ou consulter votre routeur en ligne pour savoir comment procéder. En résumé, toutefois, vous souhaitez transférer chacun des ports écoutés par NGINX sur la machine hôte NGINX. Dans mon routeur spécifique, je peux configurer des “applications” personnalisées.

Cela me permet d’affecter un nombre quelconque de ports ou de plages de ports non attribués à l’application personnalisée, qui sera ensuite affectée à une adresse IP de réseau local ou à un périphérique connecté spécifique identifié par son nom d’hôte. Dans tous les cas, cela signifie que je suis en mesure de basculer tous les ports attribués à cette application personnalisée sur n’importe quel hôte de mon réseau sans avoir à supprimer tous les ports et à les réaffecter. C’est une excellente option et je vous recommande vivement de choisir un routeur compatible.

Cette fonctionnalité petite mais incroyablement utile du pare-feu de mon routeur m’a incité à installer un second proxy inverse reflétant les configurations de mon proxy inverse actif. Je l’ai mis hors tension et je peux démarrer et faire basculer les ports sur celui-ci en moins de 3 minutes de découverte. J’imagine qu’il existe des sociétés d’hébergement professionnelles qui auraient du mal à respecter le délai de reprise après sinistre. Tout cela est dû au désir de gérer plusieurs serveurs sur un réseau domestique.

Vérifier le fonctionnement.

Maintenant que vous avez du trafic capable de circuler sur votre proxy inverse, vous devez vérifier que tout fonctionne comme prévu. Vérifiez que les sites Web fonctionnent correctement, effectuez des connexions et des tâches SSH, FTP et MySQL / MariaDB. Une fois que vous êtes convaincu que tout fonctionne comme il se doit, vous activez UFW et ajoutez des règles pour autoriser chacun des ports. Sécuriser le serveur proxy inverse

ufw enable 

Vous voudrez autoriser 80 et 443 de n’importe où. et probablement restreindre SSH, FTP et MySQL / MariaDB à une adresse IP ou un nom d’hôte. Vous pouvez commenter les règles pour identifier rapidement le service / serveur auquel vous avez attribué le port.

ufw allow 80
ufw allow 443
 ufw allow from 1.2.3.4 to any port 22002 comment 'web1 SSH'
 ufw allow from somehost.domain.com to any port 33061 comment 'db1 MySQL/MariaDB'

 ufw reload
 ufw status numbered

Mise à jour d’Apache2

Lors de l’exécution derrière un proxy inverse, les fichiers journaux Apache2 enregistrent l’adresse IP du serveur proxy inverse au lieu de l’adresse IP du visiteur du site Web. Pour rétablir l’enregistrement IP normal dans Apache2, un module est disponible pour corriger ce problème.

Effectuez les étapes suivantes sur chaque serveur Web sur lequel une instance Apache2 est installée.

sudo apt install -y libapache2-mod-rpaf 

Pour vous assurer qu’Apache2 va maintenant enregistrer les adresses IP correctes, modifiez légèrement le fichier rpaf.conf. Ubuntu 18.04 a déjà créé le fichier pour nous, il nous suffit de le modifier en changeant l’adresse IP en surbrillance pour celle de l’hôte proxy inverse de NGINX.

nano /etc/apache2/mods-available/rpaf.conf 
<ifmodule rpaf_module="">
    RPAFenable On

    # When enabled, take the incoming X-Host header and
    # update the virtualhost settings accordingly:
    RPAFsethostname On

    # Define which IP's are your frontend proxies that sends
    # the correct X-Forwarded-For headers:
    RPAFproxy_ips 127.0.0.1 ::1

    # Change the header name to parse from the default
    # X-Forwarded-For to something of your choice:
#   RPAFheader X-Real-IP
</ifmodule>

Notes finales

NGINX et Apache2 dans le même hôte

Deux services ne peuvent pas écouter sur le même port d’un serveur ou d’une machine virtuelle. Si NGINX est installé sur le même serveur ou la même machine virtuelle qu’un serveur Web Apache2, vous devez modifier le port sur lequel Apache2 écoute. NGINX a besoin des ports 80 et 443 pour exécuter ses fonctions HTTP (S) car ce sont les ports par défaut pour HTTP et HTTPS.

Reportez-vous à la section http de ce guide et ajoutez les configurations de proxy inverse pour les sites Web desservis par cette instance Apache2 de la même manière que celles des autres serveurs du réseau. Changer le port d’écoute Apache2

Si vous avez un système de gestion de serveur installé tel que ISPConfig, ce système gère les fichiers Apache2 vhost. Vous devez donc vous renseigner sur la façon de modifier les ports sur lesquels Apache2 écoute. Effectuez une recherche sur les forums ISPConfig, puis apportez les modifications nécessaires. Sinon, vous devriez consulter les forums Ubuntu ou le site Web Apache2 pour savoir comment effectuer ces modifications.

Note: Apache2 ports do not need to be altered when it is the only web server installed on server or virtual machine.