[Tuto] Utilisation du mode 'stream' avec Nginx

Bambusa29

Chevalier Jedi
10 Avril 2022
340
148
83
Suite à la demande de @MilesTEG , voici un petit tuto rapide pour utiliser les sockets sous Nginx

Préambule :

On va s'intéresser dans ce mini tuto, comment gérer en entrée de Nginx (ou Swag), autre chose que le protocole HTTP/HTTPS.
Nginx possède aussi des fonctionnalités basique pour gérer des flux TCP/UDP de bas niveau.
Nginx est donc tout a fait capable en théorie de gérer n’importe quel type de flux en entrée, autre que du HTTP : RDP, accès bases de donnés, SSH... etc

Je vais prendre l'exemple concret d'un accès à une bases de donnés FireBird depuis l’extérieur via un nom de domaine et le faire traverser le reverse proxy pour rediriger mon flux socket vers le serveur de bases de données.
Je l'avais tester aussi avec des accès SSH a travers le proxy.

Pour gérer ce type de flux TCP/UDP, nginx utilise une section 'stream' au lieu d'une section traditionnelle 'http'

Restriction :

Le mode 'stream' n'est pas compatible avec le mode 'http'; c'est donc soit l'un ou l'autre pour un service.
Le mode 'stream' perd la notion de destinataire (nous n'avons plus que l'ip de la Box, plus l'url du domaine) au niveau de notre aiguillage : on ne peut donc plus filtrer avec le nom de domaine. On ne peux filtrer que via le numéro de port
L'aiguillage se fait que via le numéro de port, donc il doit être unique et ne pas être utiliser pour d'autres services. Si j'ai par exemple deux services sur le port 8080 en mode 'stream', cela ne fonctionnement pas.

Le mode 'stream' :

Le mode 'stream' utilise les 'Websocket' pour fonctionner. Il est assez simple à activer. Je vais vous montrer comment je l'utilise moi personnellement, mais il y a sans doute d'autres façons de s'organiser.

Le principe est le même que le mode 'http' :

- Config globale dans le fichier 'nginx.conf' a la racine de 'nginx' (/etc/nginx)
- Config des services dans le répertoire 'conf.d'.

La config globale : nginx.conf

Je rajoute cette section a la fin de mon fichier de configuration :

Bash:
stream {

    include /etc/nginx/conf.d/geo_log.conf; # optionnel
    log_format combined '$time_iso8601 $remote_addr '
                        '$protocol $status $bytes_sent $bytes_received '
                        '$session_time $upstream_addr '
                        '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

    access_log /var/log/nginx/stream.log combined buffer=1k flush=5s;
    access_log syslog:server=192.168.2.57,facility=local7,tag=nginx_firebird,severity=notice combined if=$log_off; # optionnel

    include /etc/nginx/conf.d/stream.conf; # lieu ou se trouve mes configs de services
}

Le 1er include est perso, c'est pour faire un filtrage conditionnel de mes logs en fonction de l'IP vers le serveur syslog.
Mon serveur Syslog est hors de la DMZ, d'ou une règle spéciale sur le firewall (par défaut la DMZ, n'a aucun accès au LAN) pour pouvoir envoyer les messages depuis mon Nginx vers mon serveur Rsyslog.

La config des services :

Mes config se trouvent dans le fichier 'stream.conf' que j'ai placé dans /etc/nginx/conf.d

Bash:
upstream firebird {
   server 192.168.3.12:3050;
}


server {
   listen 3050;
   proxy_pass firebird;
}

Contexte :

- Le serveur de bases de donnés se trouve dans ma DMZ à l'adresse 192.168.3.12
- Le serveur écoute le port 3050 et utilise une directive 'proxy_pass' pour rediriger vers la section 'upstream'

La config de la box :

box.png


Tout ce qui arrive sur le port 3050 est renvoyer sur mon Firewall, qui part la suite renvoi vers Nginx.

Test connexion :


Pour tester le service, j'effectue une connexion ODBC depuis un poste Windows en utilisant mon nom de domaine qui me renvoi vers ma Box.

odbc.png

Je vérifie mes logs : j'ai bien une réponse '200' du serveur.

nginx.png
 
Dernière édition: