18 avril 2024

Tuto V.2018 : Partie IV, mise en œuvre

Quatrième partie du tutoriel sur la virtualisation « Xen et OpenVswitch sont dans une Debian« .
Pour le moment nous avons mis en place Xen et Openvswitch dans lequel nous avons créé deux switchs virtuels :

  • br0 sur lequel sont branchés les machines qui doivent sortir (pour le moment le dom0 et la vm routeur)
  • brint qui est le switch de communication entre les VMs. Celui ci disposant en son sein de plusieurs VLans.

Nous allons maintenant créer trois machines :

  • le routeur
  • l’IDS
  • une machine avec un serveur web (nommée proxy car on s’en servira par la suite comme… proxy)

Niveau réseau, nous allons faire en sorte qu’elles communiquent comme il faut. La sécurisation de tout cela viendra plus tard.
Cette partie du tutoriel est assez conséquente car j’explique aussi quelques notions de réseaux importantes.

I – Création des Vms

A – Routeur

Cette machine sera branchée sur le bridge bro et sur le bridge interne brint. L’Ip coté externe sera l’Ip Failover (attribuée par Online) et coté interne : 10.2.1.2

dom0# xen-create-image --hostname routeur --role tuto --size 5G --memory 512M --swap 1G --vcpus=1 --ip=99.99.99.99

L’ip est volontairement mauvaise : on va modifier la configuration réseau plus tard.
On peut suivre la création avec :

dom0# tail -f /var/log/xen-tools/routeur.log

Une fois la vm créée, on va éditer le fichier /etc/xen/routeur.cfg.
Modifiez la partie vif en mettant ce qui suit :

vif         = [  'vifname=routeur.0,ip=IP_FAILOVER ,mac=MAC_FAILOVER,bridge=br0',
                 'vifname=routeur.1,ip=10.2.1.2 ,mac=00:16:3E:A0:02:02,bridge=brint.2',
                 'vifname=routeur.2,ip=10.99.1.2 ,mac=00:16:3E:A0:02:99,bridge=brint.99']

Ici, nous déclarons trois interfaces réseaux (qui dans la vm correspondront à eth0, eth1 et eth2).
La première interface est branchée sur br0 pour un accès direct au net. On la déclare avec l’IP FAILOVER fourni par Online et surtout, l’adresse MAC fournie également par Online. Lors de la commande d’une IP Failover, une fois rattachée à votre serveur dans l’interface Online, générez une adresse MAC de type XEN.
En cas de loupé ici, c’est le port réseau de votre box qui risque d’être coupé. Soyez donc bien sur de ce que vous mettez !
La seconde interface est branchée sur le bridge interne, et le port est affecté au vlan2.
La dernière interface est aussi branchée sur le bridge interne et le poste, affecté au vlan99.
Pour les adresses MACs internes, je prend toujours 00:16:3E pour le début (Vendor : Xen) et pour la seconde partie : AX:XX:YY, ou XXX est l’ip de ma machine, ici aa.bb.cc.02, et YY le Vlan dans lequel est positionné ce branchement. Ici, rien d’obligatoire à suivre ma méthode, mais en faisant de la sorte, je suis sur de ne pas avoir de MAC en doublon.
Maintenant, nous allons monter le disque du routeur pour modifier la configuration du réseau dans le fichier /etc/network/interfaces de la vm :

dom0# mkdir /mnt/vm
dom0# mount /dev/vg0/routeur-disk /mnt/vm
dom0# nano /mnt/vm/etc/network/interfaces

La, remplacez le contenu par ce qui suit :

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
 address IPFAILOVER
 netmask 255.255.255.0
 gateway GATEWAY ONLINE (la même que votre dédibox)
auto eth1
iface eth1 inet static
 address 10.2.1.2
 netmask 255.255.255.0
auto eth2
iface eth2 inet static
 address 10.99.1.2
 netmask 255.255.255.0

Puis on démonte :

dom0# umount /mnt/vm

Et voila pour la première vm; on la démarrera plus tard.

B – IDS

Cette machine va inspecter le flux réseau transitant entre ses deux interfaces. Pour l’instant, on la prépare simplement, l’ids sera installé plus tard.
Pour cette partie, j’aurais pu faire autrement, je l’expliquerais dans le futur tutoriel sur les IDS (mirroring, machine en pont).
Dans notre cas, j’ai choisi d’installer une machine en sortie du routeur. Dans ce cas la, le seul fonctionnement possible est qu’elle aussi, agisse comme un routeur. Elle reçoit les paquets du réseau 10.2.1.0/24 et les transfère vers le réseau 10.10.1.0/24. Et vice-versa, du réseau 10.10.1.0/24 vers le réseau 10.2.1.0/24.

dom0# xen-create-image --hostname ids --role tuto --size 10G --memory 1G --swap 1G --vcpus=1 --ip=99.99.99.99

On va modifier sa configuration réseau.
Dans le fichier /etc/xen/ids.cfg :

vif         = [ 'vifname=ids.0,ip=10.2.1.3 ,mac=00:16:3E:A0:03:02,bridge=brint.2',
                'vifname=ids.1,ip=10.10.1.3 ,mac=00:16:3E:A0:03:10,bridge=brint.10',
                'vifname=ids.2,ip=10.99.1.3 ,mac=00:16:3E:A0:03:99,bridge=brint.99']

Puis :

dom0# mount /dev/vg0/ids-disk /mnt/vm
dom0# nano /mnt/vm/etc/network/interfaces

La, remplacez le contenu par ce qui suit :

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
 address 10.2.1.3
 netmask 255.255.255.0
 gateway 10.2.1.2
auto eth1
iface eth1 inet static
 address 10.10.1.3
 netmask 255.255.255.0
auto eth2
iface eth2 inet static
 address 10.99.1.3
 netmask 255.255.255.0

On démonte :

dom0# umount /mnt/vm

 

C – Proxy

Pour les besoins du tutoriel, nous allons créer un simple serveur Web qui nous permettra de tester au final qu’un http://IP_FAILOVER pointera bien sur celle ci (une fois les règles de NAT déterminées dans le routeur).

dom0# xen-create-image --hostname proxy --role tuto --size 10G --memory 512M --swap 1G --vcpus=1 --ip=99.99.99.99

On va modifier sa configuration réseau.
Dans le fichier /etc/xen/web.cfg :

vif         = [ 'vifname=proxy.0,ip=10.10.1.10 ,mac=00:16:3E:A0:10:10,bridge=brint.10',
                'vifname=proxy.1,ip=10.99.1.10 ,mac=00:16:3E:A0:10:99,bridge=brint.99']

Puis :

dom0# mount /dev/vg0/proxy-disk /mnt/vm
dom0# nano /mnt/vm/etc/network/interfaces

La, remplacez le contenu par ce qui suit :

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
 address 10.10.1.10
 netmask 255.255.255.0
 gateway 10.10.1.3 (ici la gateway est bien l'ids, c'est par lui qu'on joint les autres réseaux)
auto eth1
iface eth1 inet static
 address 10.99.1.10
 netmask 255.255.255.0

On démonte :

dom0# umount /mnt/vm

Voila, nos trois vms sont prêtes.

II – Mise en place

On va maintenant démarrer les vms et configurer ce qu’il faut dessus pour que cela fonctionne.
Avant tout on va connecter notre Dom0 sur le vlan 99 :

dom0# ifconfig vlansys 10.99.1.1 netmask 255.255.255.0 broadcast 10.99.1.255

Cette interface va nous servir pour administrer nos VMs.
Le petit hic la, c’est que rajouter la config de cette interface dans le fichier /etc/network/interface comme on aurait l’habitude de faire semble ne rien produire, elle n’est pas monté au démarrage (sûrement du à openvswitch, j’ai creusé, mais pas encore trouvé pourquoi)
Tant pis, solution de contournement : on va rajouter cela à dans un fichier /root/scripts/debugo :

#!/bin/bash
ifconfig vlansys 10.99.1.1 netmask 255.255.255.0 broadcast 10.99.1.255

Rendez le exécutable :

dom0# chmod +x /root/scripts/debugo

Ensuite, on va créer un « service » qui se chargera d’exécuter ce script au démarrage
Créez un fichier /etc/systemd/system/debugo.service et mettez ce qui suit :

[Unit]
Description=Ip Vlan 99
After=network-online.target
[Service]
Type=oneshot
ExecStart=/root/scripts/debugo
[Install]
WantedBy=multi-user.target

Puis :

dom0# systemctl enable debugo.service

Pour le démarrer de suite :

dom0# systemctl start debugo

EDIT : Un lecteur me signale que cela fonctionne en mettant ceci dans le fichier /etc/network/interfaces :

allow-hotplug vlansys
iface vlansys inet static
ovs_bridge brint
ovs_type OVSIntPort
ovs_options tag = 99
address 10.99.1.1
netmask 255.255.255.0

Merci à lui.

A – Routeur

Il est temps de lancer la vm routeur :

dom0# cd /etc/xen
dom0# xen create routeur.cfg

Et pour accéder à la console :

dom0# xen console routeur

Ou alors, si vous voulez lancer la vm et afficher la console en meme temps :

dom0# xen create routeur.cfg -c

Pour quitter la console CTRL+$ ou CTRL+^, selon votre client SSH.
Mais si vous avez tout bien suivi, vous devriez pouvoir vous y connecter en ssh depuis l’hyperviseur :

dom0# ssh 10.99.1.2

De suite, on va corriger un petit quelque chose, une route en trop. En effet, avec notre configuration, Debian rajoute une route inutile. A priori, ça n’empêche en rien le fonctionnement, mais étant de nature méfiante, je préfère l’enlever.

routeur# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 GATEWAY_ONLINE 0.0.0.0 UG 0 0 0 eth0
10.2.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
10.99.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2
AAA.BBB.CCC.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

La dernière route (qui reprend la même classe que mon IP failover est inutile. Nous allons la supprimer.

routeur# route del -net AAA.BBB.CCC.0 netmask 255.255.255.0

Encore un truc curieux, si l’on rajoute cela fichier /etc/network/interfaces, ça ne fonctionne pas (la, je ne comprend pas, si quelqu’un voit….)
Ma solution de contournement :
Fichier /root/scripts/debugo :

#!/bin/bash
route del -net AAA.BBB.CCC.0 netmask 255.255.255.0

Ensuite :

routeur# chmod +x /root/scripts/debugo

Même principe que sur l’hyperviseur, on va créer un service.
Créez un fichier /etc/systemd/system/debugo.service et mettez ce qui suit :

[Unit]
Description=Route
After=network-online.target
[Service]
Type=oneshot
ExecStart=/root/scripts/debugo
[Install]
WantedBy=multi-user.target

Puis :

routeur# systemctl enable debugo.service

Pour le démarrer de suite :

routeur# systemctl start debugo

Maintenant, testons :
On doit pouvoir pinger cette VM depuis l’extérieur sur son Ip publique (ici, mon Ip failover), se connecter dessus en ssh, etc..
Et, depuis celle ci, les pings vers l’extérieur fonctionnent également.
Pour le moment, tout est bon.

B – IDS

On démarre la seconde machine, l’IDS.

dom0# xen create /etc/xen/ids.cfg

On doit pouvoir se connecter dessus depuis le dom0 :

dom0# ssh 10.99.1.3

Depuis la machine ids,  on doit pouvoir pinger le routeur 10.2.1.2 et depuis le routeur, on doit pinger l’ids (10.2.1.3)
Par contre, un ping vers le net depuis l’ids ne fonctionne pas.
Coté routeur, installons tcpdump pour voir ce qu’il se passe :

routeur# apt-get install tcpdump

On écoute sur l’interface ou arrive le ping depuis l’ids

routeur# tcpdump -i eth1 icmp -n
00:10:26.395336 IP 10.2.1.3 > 8.8.8.8: ICMP echo request, id 338, seq 159, length 64

Par contre rien sur l’interface eth0 :

routeur# tcpdump -i eth0 icmp -n

Normal : pour activer le transfert (forward) de paquets entre interface, il faut utiliser cette commande :

routeur# echo 1 > /proc/sys/net/ipv4/ip_forward

Pour rendre cette modification persistante (ici, au reboot ip_forward repasserait à 0), dans le fichier /etc/sysctl.conf, trouvez la ligne

net.ipv4.ip_forward=1

et décommentez la.
Ensuite :

sysctl -p /etc/sysctl.conf

Et la, nous voyons les pings passés sur eth0

# tcpdump -i eth0 icmp -n
00:13:06.483479 IP 10.2.1.3 > 8.8.8.8: ICMP echo request, id 338, seq 319, length 64

Cependant, sur l’ids, aucun retour de notre ping … Pourquoi ?
Pour expliquer, je me sers d’un autre serveur pour la démonstration, sur l’adresse 99.99.99.99, adresse fictive mais qui est une adresse « internet », situé de l’autre côté du routeur pour votres ids.
Depuis l’ids, je ping 99.99.99.99 et sur cette machine :

99.99.99.99# tcpdump icmp
 17:33:36.054076 IP 10.2.1.3 > 99.99.99.99: ICMP echo request, id 399, seq 262, length 64

Le ping arrive bien mais son adresse source est 10.2.1.3 qui bien sur n’est pas routable… bref la machine 99.99.99.99 ne sait pas a qui renvoyer le paquet.
Tout cela est bien mesquin n’est ce pas ?
Pas de soucis, il suffit au niveau du routeur de lui demander de modifier l’adresse source des paquets qui sortent par son interface eth0 et venant de la machine 10.2.1.3 :

routeur# iptables -t nat -A POSTROUTING -o eth0 -s 10.2.1.3 -j SNAT --to IPFAILOVER

Cette règle demande à modifier l’adresse source de chaque paquet sortant par eth0. Chaque paquet aura donc l’IP Failover en source, du coup le serveur distant saura ou renvoyer la réponse, et le routeur de faire suivre au demandeur (Policy Accept par défaut d’iptable dans la table NAT, chaine FORWARD, on s’occupera du FW plus tard)
On teste un ping vers 8.8.8.8 depuis l’ids, cela fonctionne.

C – Proxy

Maintenant, démarrons la dernière vm.
Celle ci doit déjà pouvoir pinger l’ids sur l’adresse 10.10.1.3 et depuis l’ids, on doit la pinger sur 10.10.1.10.
Par contre, impossible de pinger l’extérieur depuis cette VM.
Bien sur, il faut activer le forward sur l’ids :

ids# echo 1 > /proc/sys/net/ipv4/ip_forward

Ajoutons la modification au reboot : fichier /etc/sysctl.conf, trouvez la ligne

net.ipv4.ip_forward=1

et décommentez la.
Ensuite :

sysctl -p /etc/sysctl.conf

Mais cela ne suffit pas.
Lancons un ping vers 8.8.8.8 depuis la machine proxy 10.10.1.10 et sur le routeur :

routeur# tcpdump -n icmp
 13:14:31.887146 IP IPFAILOVER > 8.8.8.8: ICMP echo request, id 451, seq 1, length 64
 13:14:31.923442 IP 8.8.8.8 > IPFAILOVER : ICMP echo reply, id 451, seq 1, length 64
 13:14:31.923471 IP 8.8.8.8 > 10.10.1.10: ICMP echo reply, id 451, seq 1, length 64

Pour le retour le routeur reçoit un paquet à destination de 10.10.1.10, seulement, si l’on fait :

# route -n
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         GATEWAYONLINE   0.0.0.0         UG    0      0        0 eth0
10.2.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth1
10.99.1.0       0.0.0.0         255.255.255.0   U     0      0        0 eth2

Nous constatons que le routeur ne sait pas quoi faire des paquets à destination du réseau 10.10.1.0/24.
Un peu comme avant, ou la machine 99.99.99.99 ne savait pas quoi faire des paquets en provenance de 10.2.1.2
La première solution serait d’ajouter une règle de DNAT sur l’ids comme il en existe déjà une sur le routeur mais cette solution n’est pas la bonne.
Pourquoi ?
Nous voulons que ce soit le routeur qui définisse qui fait quoi par la suite (par ex, rediriger le port 80 vers telle vm, autoriser tel vm a sortir sur tel port, etc..)
Bref, les règles dans iptables se feront avec les ips du réseau 10.10.1.0/24 (en passant par la gateway de ce réseau, 10.2.1.3). Si nous utilisions l’ids pour faire du masquerade, nous pourrions nous passer de la route nouvelle du routeur, mais dans ce cas, il faudrait faire l’aiguillage des paquets dans l’ids, ce qui n’est pas son rôle.
On va plutôt ajouter une route côté routeur, pour lui dire comment joindre le réseau 10.10.1.0/24
On va donc stipuler que les paquets à destination du réseau 10.10.1.0 doivent transiter par la machine IDS 10.2.1.3 sur l’interface eth1

routeur# route add -net 10.10.1.0/24 gw 10.2.1.3 dev eth1

Ajoutez cette ligne à votre fichier /root/scripts/debugo. Il doit ressembler à cela :

#!/bin/bash
route del -net AAA.BBB.CCC.0 netmask 255.255.255.0
route add -net 10.10.1.0/24 gw 10.2.1.3 dev eth1

Autorisons le POSTROUTING pour le réseau 10.10.1.0/24 (pour que les paquets sortant en provenance de ce réseau aient leur ip source changs et ainsi voir le retour)

routeur#iptables -t nat -A POSTROUTING -o eth0 -s 10.10.1.0/24 -j SNAT --to IPFAILOVER

Et la, magie, les pings depuis cette VM vers l’extérieur doivent passer.
Pour terminer la démo, installons simplement Nginx (avec le paquet nginx-extras, qui ajoutent quelques fioritures qui nous seront utiles plus tard…)

# apt-get install nginx-extras

Puis sur la vm routeur, on va spécifier que les paquets qui sont destinés au port 80 doivent etre redirigé vers l’IP 10.10.1.10.

routeur# iptables -t nat -A PREROUTING -i eth0 -d IP_FAILOVER -p tcp --dport 80 -j DNAT --to-destination 10.10.1.10

Et depuis un navigateur, testez un http://IPFAILOVER, vous devriez trouver la page nginx par défaut.

Voila qui clôture ce copieux chapitre.
Dans la suite, nous allons rajouter un peu de firewall sur ces nouvelles machines dans la Partie V : Firewall.

5 réflexions sur « Tuto V.2018 : Partie IV, mise en œuvre »

  1. I have in my /etc/network/interfaces
    allow-hotplug vlansys
    iface vlansys inet static
    ovs_bridge brint
    ovs_type OVSIntPort
    ovs_options tag = 99
    address 10.99.1.1
    netmask 255.255.255.0
    This gets at launch vlansys an IP
    Sorry for my english

  2. Bonjour,
    Dans la ligne ifconfig vlan99 10.99.1.1 netmask 255.255.255.0 broadcast 10.99.1.255 il faut changer vlan99 par vlansys

  3. Bonjour,
    ma configuration fonctionne comme indiqué par moi, l’interface réseau reçoit son IP.
    Désolé, je ne parle que l’allemand, (Google Translate)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *