NSX-T : L3 et L7 sont dans un bateau …

Salut les loulous ^^ . Il y a quelques jours, nous avons été alerté par la cellule Cyberveille santé au sujet d’une IP publique sous notre responsabilité ayant un comportement pour le moins étrange : des centaines de ports TCP y apparaissaient « ouverts » et répondaient donc à leurs scans automatisés. Ceci fut le début d’une enquête qui a duré plus d’une semaine, pour aboutir à une découverte assez fondamentale sur NSX-T … prenez la pillule rouge avec moi …

Il y a environ une dizaine de jours, on nous alertait au sujet d’une IP répondant de manière plus qu’inquiétante à un scan externe de la part de la cellule CyberVeille Santé (plus d’infos ici, pour les curieux). Evidemment, ce type d’alerte réclame des investigations rapides et une réponse appropriée, nous donc avons enquêté puis reproduit le problème avec nos propres outils. Un scan standard type nmap confirmait la notification, voici d’ailleurs un extrait du résultat de ce scan sur l’IP en question :

Starting Nmap 7.70 ( https://nmap.org ) at 2021-10-13 20:24 CEST
Nmap scan report for toto.hyperbizarre.cheznous (xxx.xxx.xxx.xxx)
Host is up (0.098s latency).
rDNS record for xxx.xxx.xxx.xxx : 
PORT      STATE    SERVICE
7/tcp     open     echo
9/tcp     open     discard
13/tcp    open     daytime
21/tcp    open     ftp
22/tcp    open     ssh
23/tcp    open     telnet
25/tcp    filtered smtp
26/tcp    open     rsftp
37/tcp    open     time
53/tcp    open     domain
79/tcp    open     finger
80/tcp    open     http
81/tcp    open     hosts2-ns
(…)
2000/tcp  open     cisco-sccp
2001/tcp  open     dc
2049/tcp  open     nfs
2121/tcp  open     ccproxy-ftp
2717/tcp  open     pn-requester
3000/tcp  open     ppp
3128/tcp  open     squid-http
3306/tcp  open     mysql
(…)
49152/tcp open     unknown
49153/tcp open     unknown
49154/tcp open     unknown
49155/tcp open     unknown
49156/tcp open     unknown
49157/tcp open     unknown

Plus étrange encore, nous pouvions lancer plusieurs nmap différents, presque à chaque fois, nous avions des réponses un peu différentes, mais toujours beaucoup trop verbeuses (des dizaines de port ouverts). La première chose a été de se dire : impossible qu’un serveur unique, derrière ce NAT (puis que nous n’utilisons pas de Load Balancing sur ce service) ne puisse répondre « open bar » à tant de ports qui, de plus, n’ont strictement rien à voir et pour certains ne correspondent plus à rien de concret. D’autre part, un nmap direct sur la machine virtuelle cible, hors NAT, nous donnait un résultat beaucoup plus cohérent et en accord avec les vrais services réellement ouverts de celle-ci.

On ne pouvait évacuer à ce stade une éventuelle erreur humaine sur un des équipements de la chaine de liaison entre le routeur de périmètre et la machine cible. Nous avons commencé par revoir toute nos règles et policies DFW sur la chaine de liaison coté NSX, ainsi que le paramétrage de chaque intermédiaire (TIER0, TIER etc). Je précise que le NAT portait sur un service spécifique, le HTTPS (ça aura de l’importance plus tard, retenez bien la notion de service).

Au niveau topologie, rien de très extraordinaire, un pare-feu périmétrique, devant le TIER0 « public » de notre infrastructure NSX-T, suivi d’un TIER1, qui porte le NAT en question, suivi enfin d’un segment sur lequel est connecté la VM cible dont on veut ouvrir le service web. Aucune règle particulière sur le TIER0, à part les règles de routage, bien entendu. L’avantage de cette organisation était, pour nous, justement, sa « simplicité » ce qui nous a permis de reconstruire très vite un environnement équivalent sur notre NSX de test.

… et nous avons reproduit le problème en 5 minutes ! Cela nous a au moins appris qu’il ne s’agissait pas d’un composant externe à NSX-T chez nous, mais bien d’une fonction/paramètre/comportement spécifique à celui-ci. En désespoir de cause, je me suis retourné, avant d’ouvrir un SR chez VMware, sur notre magnifique channel slack VMUGFR (ici) sur lequel on trouve, en dehors de la hotline VMware officielle, à peu près tout ce que vous pouvez imaginer de barbus, vétérants de la production et autres ingénieurs/techniciens brillants (pas assez de femmes, malheureseuement … rejoignez-nous mesdames si vous me lisez !). Durant environ 48 heures, les idées, tests complémentaires et hypothèses en tout genre vont bon train sans pour autant que quelqu’un ne pose un diagnostic. Mieux (ou pire c’est selon), certains arrivent également à reproduire de leur coté, ôtant définitivement le doute d’un composant chez nous.

Arrive vendredi soir. En refaisant le point une nième fois sur notre problème, je repère un paramètre spécifique qu’on utilise, il est vrai assez peu, le « translated port » au sein de la déclaration de NAT. Au point où j’en étais, je me suis dit que, peut-être, le moteur de NAT NSX-T (qui était quand même bien suspect depuis quelques jours) avec un port de destination spécifique, serait forcé de n’ouvrir que le port cible initial… Je modifiais donc ledit paramètre et demandais à un collègue de re-tester un scan, une fois de plus … OZAAAANNNNA ! Le NAT se comportait enfin normalement ! n’affichant plus qu’un seul port ouvert, correspondant à ce qui était en théorie attendu.

Fort de cette trouvaille, j’ouvre tout de même un SR chez VMware pour me faire expliquer ce comportement et je m’empresse de communiquer la découvert aux collègues du VMUGFR. Alexis (vous pouvez le féliciter, au passage, sur Twitter ici), un de mes potes barbus, spécialiste réseau devant l’Eternel, visiblement intrigué, lui aussi, par ce dernier fait, réalise quelques tests complémentaires et arrive à une conclusion presque logique et en tout cas, potentiellement parfaitement valide : en fait, lorsque vous ouvrez un service spécifique sur votre NAT, par exemple HTTPS ou SSH, de base, NSX-T vous propose effectivement des services sans indiquer à aucun moment le port TCP auquel on pense traditionnellement.

Vous vous rappelez la notion de service (et pas de port, notez bien) : ce qui semble se passer c’est que le NAT du TIER1 NSX est en réalité un firewall L7 et pas L3 : NSX traduit cela en acceptant, par défaut, toute ouverture de session TCP (le triplet syn/ack/synack) mais va plus loin et vérifie ensuite si le flux correspond réellement au service demandé, au hasard du HTTP 1.1 avec un TLS 1.2, ou encore l’initialisation d’une vraie session SSH. Conséquence, Il écoute toutes les ouvertures de sessions TCP et même commence à recevoir quelques trames complémentaire avant de décider s’il faut ouvrir ce service légitime ou pas. Si le flux est un flux HTTPS classique, validé au niveau TCP et protocolaire L7, ALORS, en toute fin, ce flux est redirigé vers le port traditionnel de votre machine écoutant ce type de flux, le 443.

Le fait de forçer la redirection vers un « translated port » spécifique, à la manière d’une onde de probabilité quantique, on force le moteur NAT à « réduire le paquet d’onde » et n’ouvrir qu’un seul port redirigé sans équivoque vers la cible. Dans tous les cas, même si l’analyse que l’on fait du comportement du NAT n’est pas exactement ce qui se passe, nul doute qu’avec les informations trouvées, le SR que j’ai ouvert ce Vendredi nous donnera surement la root cause ou une explication approchante.

Notre erreur semble donc avoir été de penser que le NAT NSX-T va beaucoup plus loin qu’un firewall L3 traditionnel.

Nul doute que ce n’est pas fini, étant donné mon SR ouvert, mais Alexis prévoit sans doute de faire un article complémentaire sur MyVMworld.fr dans les jours/semaines qui viennent, pour apporter un éclairage plus technique encore que ce que j’ai pu vous donner.

Quelle aventure technique mes amis ^^ !!
Affaire à suivre…