[Routage] Question Infra virtualisée avec full NAT + routeur

Bonsoir,

Les deux questions sont posées à la fin du post. J’ai été obligé de développer un peu, je pense que le contexte est important pour comprendre. Ces questions ont un rapport avec : sécurité réseau / routage / iptables.

J’ai un serveur dédié chez OVH, avec une IP publique qui sera pour l’exemple 37.37.37.37/24. Le but est de ne pas utiliser l’IP Forwarding de OVH et donc ne posséder qu’une seule IP et MAC publique chez eux.

Ce serveur dédié est un hyperviseur XEN afin de déployer une infrastructure virtualisée. Je me retrouve donc avec un serveur physique virtualisant plusieurs machines virtuelles hébergeant elles-mêmes des services (par exemple LAMP, messagerie, firewall) dont certains nécessitent d’être accessibles depuis le web.
Les machines virtuelles nécessitant une connexion au réseau se trouvent derrière un Routeur/Firewall PfSense virtualisé.
Niveau réseau, le but est de faire du NAT pour les machines virtuelles. Elles sont donc sur le sous réseau 192.168.1.0/24. L’hyperviseur quand à lui possède la carte réseau physique (celle de OVH) eth0 en DHCP et qui récupère l’IP 37.37.37.37/24 qui m’a été attribuée.
Une machine virtuelle PfSense fait office de routeur/firewall pour les machines virtuelles. Elle est donc la passerelle pour le réseau des VM.

L’adressage est conçu comme ceci :

  • l’hyperviseur a la carte physique eth0 avec l’IP publique 37.37.37.37 qui permet d’accéder au net
  • l’hyperviseur a un bridge virtuel Dummy0 avec l’IP 192.168.0.1/24
  • l’hyperviseur a un bridge virtuel Xbr0 avec l’IP 192.168.1.1/24
  • la VM Routeur/Firewall PfSense a une carte réseau virtuelle avec l’IP 192.168.0.254/24
  • la VM Routeur/Firewall PfSense a une carte réseau virtuelle avec l’IP 192.168.1.254/24
  • Toutes les autres VM ont une carte réseau virtuelle avec une IP sur le réseau 192.168.1.0/24

Les bridges sont utilisés pour créer des sous-réseaux inteligibles par XEN. Pour info pour ceux qui ne connaissent pas, dans le fichier de configuration des machines virtuelles sur l’hyperviseur, il faut déclarer les interfaces réseau ainsi que le bridge qu’elles vont utiliser et qui doit-être existant sur l’hyperviseur.
Voici pour exemple la partie sur les interfaces réseau dans le fichier de configuration de la machine virtuelle Routeur/Firewall PfSense:

vif = [ ‘bridge=xbr0, mac=00:16:3e:00:01:01’, ‘bridge=dummy0, mac=00:16:3e:00:00:01’]

Explication de la ligne:

‘bridge=xbr0, mac=00:16:3e:00:01:01’ --> Utilisation du Bridge Xbr0 créé sur l’hyperviseur se trouvant sur le réseau 192.168.1.0. La carte réseau 1 dans la machine virtuelle aura comme MAC 00:16:3e:00:01:01. L’IP sera définie dans le système virtualisé.
‘bridge=dummy0, mac=00:16:3e:00:00:01’ --> Utilisation du Bridge Dummy0 créé sur l’hyperviseur se trouvant sur le réseau 192.168.0.0. La carte réseau 2 dans la machine virtuelle aura comme MAC 00:16:3e:00:00:01. L’IP sera définie dans le système virtualisé.

Pour que cela fonctionne, il m’a fallu sur l’hyperviseur transférer tout le traffic arrivant sur 37.37.37.37 vers 192.168.0.1, pour que le routeur/firewall PfSense récupère les paquets sur son interface 192.168.0.254 et les route sur le réseau 192.168.1.0 (réseau des autres machines virtuelles) via son interface 192.168.1.254.

Voici l’iptables de l’hyperviseur:

forward sur Dummy0 (192.168.0.1)

iptables -A FORWARD --in-interface dummy0 -j ACCEPT

on NAT tout ce qui sort sur eth0 (IP publique OVH)

iptables --table nat -A POSTROUTING --out-interface eth0 -j MASQUERADE

On laisse passer un accès SSH depuis l’extérieur sur l’hyperviseur avec le port 7575

iptables -t nat -A PREROUTING -p tcp --dport 7575 -i eth0 -j DNAT --to 192.168.0.1:7575

Full NAT entre l’interface publique et l’interface “coté WAN” du routeur/firewall PfSense

iptables -t nat -A PREROUTING -d 37.37.37.37 -j DNAT --to 192.168.0.254
iptables -t nat -A POSTROUTING -s 192.168.0.254 -j SNAT --to 37.37.37.37

routes de l’hyperviseur:

Table de routage IP du noyau
Destination Passerelle Genmask Indic Metric Ref Use Iface
default sbg-gw-6k.fr.eu 0.0.0.0 UG 0 0 0 eth0
37.37.37.37 * 255.255.255.0 U 0 0 0 eth0
192.168.0.0 * 255.255.255.0 U 0 0 0 dummy0
192.168.1.0 * 255.255.255.0 U 0 0 0 xbr0

Maintenant que vous avez eu la patience et le courage de lire jusqu’ici, je vous expose mes questions :

  • J’ai laissé un accès SSH ouvert sur l’hyperviseur pour qu’en cas de problème sur ma machine virtuelle PfSense je puisse toujours accéder à l’hyperviseur et débugger plutôt qu’être obligé de redémarrer mon serveur via l’interface OVH en mode Rescue et CHROOT dans mon système pour commenter le lancement du script iptables et pouvoir rétablir l’accès.
    Est-ce cohérent? C’est risqué vu qu’un accès en root sur mon hyperviseur donne évidemment les pleins droits sur les machines virtuelles. Cependant, l’accès en root au login est interdit dans la configuration de ssh. Qu’en pensez-vous?

  • Forcément, quand mon hyperviseur a besoin d’accéder au net (mises à jour par exemple), il le fait par sa carte physique eth0 37.37.37.37 sans passer par la machine virtuelle PfSense, ceci étant dû à la route par défaut.
    Est-ce risqué? Y a-t’il un moyen pour le faire passer par PfSense? J’ai simplement essayé d’ajouter la route par défaut “route add default dev xbr0” pour envoyer vers 192.168.0.0 et se faire router par PfSense mais ça m’a planté l’accès, j’ai du CHROOTer mon système pour récupérer l’accès SSH. Je pense que c’est parce que les paquets tournaient en rond mais je n’arrive plus à prendre du recul sur ce souci.
    Je réfléchis trop avant de taper une commande parce que c’est assez pénible de se scier l’accès au réseau sur ce genre d’infra…

Salut,
Alors petite remarque ^^ , un schéma, même avec de rectangle tout moche aiderait à comprendre ce que tu veux faire.

Mais pour répondre à ta question (d’après ce que j’en ai compris) bah un accès SSH de secours ne me parait pas horrible.
Le rapport bénéfices risques me parait largement favorable pour le coup. Mais tu peux quand même sécursiser un chti peu le tout, avec un login par cléf publique et une limitation des sources ou encore en plus du fail2ban sur le 7575 si tu es parano :laughing: .

Pour ta seconde question, (et toujours si j’ai tout compris comme il faut) bah c’est normal que cela ne fonctionne pas car les flux sortent du pfsense en 192.168.1.X et doivent être NATé et routé par l’hyperviseur.
Donc évidemment si tu routes les flux en sortie de l’hyperviseur par le pfsense…

Mais sinon, une question me taraude… pourquoi envoyer tout les flux vers le pfsense et pas uniquement les flux utiles.
Autre question c’est pour un besoin “limité” et non professionnel j’espère ? car cela ne me parait pas très “scalable”?

Voila , my 2 cents…

Voici un schéma

L’hyperviseur via iptables envoi tous les paquets reçus sur eth0 vers Dummy0 et plus spécifiquement 192.168.0.254.

Ok pour ssh, ça se met en place facilement et c’est toujours plus sécurisant. C’est vrai que se priver d’un accès ssh dans ce cas là c’est pas très flexible.

Du coup pour la route c’est bien ça… Mais à la limite si ça ne pose pas de réel souci de sécurité ça ne me dérange pas plus que ça que l’hyperviseur ait un accès direct au net. Tout ce qui y arrive (mis à part sur le port 7575) depuis l’extérieur est ensuite routé sur le PfSense en 192.168.0.254 (Dummy0) qui redistribue jusqu’à l’IP de l’hyperviseur 192.168.1.1 (Xbr0) dans le cas où il est à destination d’un paquet.

Je renvoie tous les flux pour ne garder qu’un “vrai” point de filtrage et de routage : la VM routeur/firewall. Ca permet de standardiser la configuration “intra-hyperviseur” pour d’éventuels déploiements. Cette VM routeur/firewall est destinée à me fournir des services réseaux comme : proxy, reverse proxy, DNS, NAT, NTP, Filtrage et autres joyeusetés.
Cette solution est mise en oeuvre pour une utilisation “semi-professionnelle” (site web et messagerie en production, cloud perso, tests persos pour d’éventuelles extensions/évolutions…).
Pour répondre à ta remarque sur le manque de scalabilité, c’est pour le moment destiné à ne rester qu’un simple hyperviseur sans load balancing ou cluster.

Je suis ouvert à toute critique/suggestion sur les principes de routage.

Pour préciser, ce type d’infra était déjà présent sur mon serveur derrière ma propre connexion Internet mais toutes ces questions de routage se sont présentées lors du déploiement sur un dédié : je ne pouvais plus bridger une carte réseau virtuelle avec une mac virtuelle sur eth0 de l’hyperviseur, le switch de OVH me ban le port quand il détecte ça.

Observations :

  1. Le nom “dummy0” pour un pont n’est pas très heureux car il est normalement utilisé par la première interface factice créée par le module “dummy”.

  2. Ton schéma n’est pas très représentatif de la topologie réseau de ton infrastructure. Ce serait plus parlant de représenter la dom0 et les domU de la même façon comme des machines normales plutôt que comme un hyperviseur contenant les machines virtuelles, ce qui n’a aucun intérêt du point de vue réseau.

  3. Ainsi on verrait mieux que la dom0 est branchée en parallèle de la pfsense sur ses deux interfaces, ce qui n’est pas génial du point de vue isolation car en cas d’erreur de routage il serait assez facile de court-circuiter le pfsense. L’utilisation d’un pont pour la liaison entre le pfsense et les serveurs n’est pas justifiée autrement que par le fait qu’il n’y a pas d’autre solution avec Xen avant la version 4.3 (à partir de cette version, on peut le remplacer par un “open vswitch”). Une possibilité pour isoler au mieux le dom0 des serveurs est de bloquer tous les paquets émis et reçus localement par dummy0 avec ebtables, et de ne laisser passer que les paquets transmis entre le pfsense et les serveurs.

Bonjour,

[quote=“PascalHambourg”]Observations :

  1. Le nom “dummy0” pour un pont n’est pas très heureux car il est normalement utilisé par la première interface factice créée par le module “dummy”.[/quote]

Tout à fait. Ca m’a d’ailleurs posé un problème à moment donné et j’ai du désactiver le module dummy. J’ai mit ce nom parce que je faisais mes tests en me référant à plusieurs documentations présentant des config. différentes et je me suis un peu mélangé les pinceaux. J’en profiterai pour corriger ça dans la foulée de la modification que tu proposes en 3).

Le collègue avec qui j’ai réalisé ça m’en a fait un autre du coup, avec des noms de ponts cohérents :

[quote=“PascalHambourg”]
3) Ainsi on verrait mieux que la dom0 est branchée en parallèle de la pfsense sur ses deux interfaces, ce qui n’est pas génial du point de vue isolation car en cas d’erreur de routage il serait assez facile de court-circuiter le pfsense. L’utilisation d’un pont pour la liaison entre le pfsense et les serveurs n’est pas justifiée autrement que par le fait qu’il n’y a pas d’autre solution avec Xen avant la version 4.3 (à partir de cette version, on peut le remplacer par un “open vswitch”). Une possibilité pour isoler au mieux le dom0 des serveurs est de bloquer tous les paquets émis et reçus localement par dummy0 avec ebtables, et de ne laisser passer que les paquets transmis entre le pfsense et les serveurs.[/quote]

C’est exactement pour ce genre de propositions que je suis venu poster ici.
Au départ Xen avait été installé en 4.1 mais les domU HVM refusaient de démarrer dans cette config. alors que les domU PV fonctionnaient. Après le passage en 4.4 tout s’est passé comme sur des roulettes.
Je vais donc suivre tes suggestions : open vswitch pour remplacer le pont entre le PfSense et les serveurs. J’imagine que l’intérêt d’open vswitch dans mon cas est que le dom0 ne sera pas atteignable par les domU, mis à part le domU pfsense qui aura toujours une de ses deux pattes sur le pont lui permettant d’être relié au WAN. Ou alors je me trompe et il me faudra quand même bloquer le trafic via ebtables.

Je vous remercie pour vos avis.

Et vice versa.
Pas atteignable directement via le réseau en tout cas, puisque le dom0 n’aura pas besoin d’avoir une interface dans le switch virtuel alors que c’est inévitable avec un pont traditionnel. Ainsi la couche réseau du dom0 ne verra pas le trafic sur le switch virtuel entre les domU.

Même avec des règles ebtables bien choisies pour bloquer tout le trafic réseau “normal”, un pont ne permet pas d’atteindre une isolation aussi complète : il resterait possible au dom0 d’écouter et d’injecter des paquets directement sur les interfaces virtuelles qui le relient aux domU, court-circuitant les règles ebtables du pont.

A ce sujet, le pont xbr0 est-il indispensable ? Il ne contient que l’interface virtuelle vers le domU pfsense, aussi le dom0 pourrait aussi bien utiliser directement celle-ci.

Je reviens sur un point évoqué précédemment que je n’avais pas commenté : l’utilisation du domU pfsense par le dom0 comme passerelle par défaut. En le faisant de façon naïve, tu as évidemment créé une boucle de routage puisque le dom0 était déjà la passerelle par défaut du domU pfsense. Mais on doit pouvoir y parvenir avec un peu de routage avancé, en différenciant le trafic émis localement ou reçu de l’extérieur (routé vers pfsense) du trafic reçu en provenance de pfsense (routé vers l’extérieur).

Une autre façon de faire envisageable consisterait à donner le contrôle de la carte réseau physique au domU pfsense plutôt qu’au dom0 grâce au “PCI passthrough”.

Mais dans tous les cas, cela serait risqué en cas de problème car tu n’aurais plus d’accès direct au dom0 depuis l’extérieur.

Effectivement, quand j’ai fait la modification en supprimant le pont et en utilisant open vswitch sans lui préciser d’IP je me suis rendu compte que la communication était impossible dans les deux sens. C’est parfait comme cela pour le moment.

Il y a donc bien un réel avantage à passer par open vswitch dans ce cas là. Merci pour l’info.

Justement, tu soulèves un point important du problème que j’ai rencontré lors du déploiement sur le serveur dédié. Utiliser le mode bridge de Xen pour les domU (pont qui englobe les interfaces physiques avec les virtuelles) était impossible parce que le switch de OVH filtre apparemment les adresses MAC. J’avais l’impression de me faire bannir le port lorsqu’un domU demandait à sortir sur le WAN. Après quelques recherches sur le net il s’est avéré que c’était bien ça et qu’il m’était impossible d’utiliser ce mode réseau dans Xen. J’ai donc créé un pont xbr0 totalement virtuel afin de faire du routage entre celui-ci et l’interface physique eth0, avec du masquerading derrière.

Oui, je vais essayer de travailler sur cette dernière étape pour avoir quelque chose qui me plait.

La solution du “PCI Passthrough” a été ma première envisagée étant sur du matériel qui le permet, mais c’est exactement pour la même raison que tu cites que je ne l’ai pas choisie. Je tenais à garder un minimum de souplesse sur une éventuelle intervention en cas de problème sur le domU pfsense.
La solution en terme de simplicité aurait été des IP Failover, mais j’ai décidé de m’en passer sachant que ça devait-être possible sans et qu’elles sont facturées.

Merci bien, je te dois un pack.

Même si OVH ne filtrait pas les adresses MAC, cela n’aurait pas pu fonctionner de toute façon : pour cela, il aurait fallu que chaque domU pontée avec l’interface physique dispose de sa propre adresse IP publique.

Mais cela n’a aucun rapport avec ma mise en question du pont xbr0. Un pont est utile pour relier plusieurs interfaces, physiques ou virtuelles. Or xbr0 ne contient qu’une seule interface vers le domU pfsense. La seule justification que je vois à sa présence, c’est si les scripts par défaut de Xen ne permettent pas de créer une interface virtuelle pour une domU sans l’associer à un pont.

C’est bien ça. Si on déclare une interface dans un domU, même si on ne lui précise aucun pont, il prendra celui par défaut (xenbr0).

Bonjour,

Voici la réalisation finale :

Carte physique en PCI Passthrough sur le domU pfsense. Tant pis pour la nécessité de démarrer la machine sur un système de secours en cas de problème sur le domU pfsense.