17 octobre 2021
Virtualisation Xen

Tuto Virtualisation : Partie III, mise en oeuvre

EDIT 2018 : Retrouvez cette série de tuto dans une grosse mise à jour ici : Xen et OpenVswitch sont dans une Debian 9 – V.2018

Troisième partie du tutoriel sur la virtualisation « Xen et OpenVswitch sont dans une Debian« .
Dans la première partie, nous avons mis en place Xen, puis dans la seconde, Openvswitch dans lequel nous avons créé deux switchs virtuels :

  • br0 sur lequel sont branchés les machines qui doivent sortir (en l’occurence, le dom0 et la vm routeur)
  • brint qui est le switch de communication entre les vms. Celui ci disposant 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)

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.
Préparez le café et les clopes (hou pas bien !), le cerveau va chauffer !

I – Création des Vms

A – Routeur

Cette machine sera branchée sur le bridge bro et sur le bridge interne. 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.
On peut suivre la création avec :

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

Une fois la vm créé, on va éditer le fichier /etc/xen/routeur.cfg.
Notez la MAC attribué a l’interface par défaut (MAX_XEN) et remplacez la partie vif par ce qui suit :

vif         = [  'vifname=routeur.0,ip=IP_FAILOVER ,mac=MAC_FAILOVER,bridge=br0',
                 'vifname=routeur.1,ip=10.2.1.2 ,mac=MAC_XEN,bridge=brint.2',
                 'vifname=routeur.2,ip=10.99.1.2 ,mac=MAC_XEN+1,bridge=brint.99']

Ici, nous déclarons trois interfaces réseaux (qui dans la vm correspondront à eth0, eth1 et eth2). Pour l’adresse MAC de la pâte routeur.1 prenez la MAC qu’a créé Xen et ajoutez lui 1 (par ex.)
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 foirage ici, c’est le port réseau de votre box qui risque d’être coupé. Soyez 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
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
autot 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 forward 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:69:9D:4A,bridge=brint.2',
                'vifname=ids.1,ip=10.10.1.3 ,mac=00:16:3E:69:9D:4B,bridge=brint.10',
                'vifname=ids.2,ip=10.99.1.3 ,mac=00:16:3E:69:9D:4C,bridge=brint.99']

Puis :

dom0# mkdir /mnt/vm
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
autot eth2
iface eth2 inet static
 addresse 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:69:6F:4A,bridge=brint.10',
                'vifname=proxy.1,ip=10.99.1.10 ,mac=00:16:3E:69:6F:4B,bridge=brint.99']

Puis :

dom0# mkdir /mnt/vm
dom0# mount /dev/vg0/web-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 vlan99 10.99.1.1 netmask 255.255.255.0 broadcast 10.99.1.255

Cette interface va nous servir pour administrer nos domus…
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 (surement du à openvswitch, j’ai creusé, mais pas encore trouvé pourquoi)
Tant pis, solution de contournement (certe un peu crade mais cela fonctionne) : on va rajouter cela à dans un fichier /etc/init.d/debugo :

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

Rendez le exécutable et insérez le au démarrage

dom0# chmod +x /etc/init.d/debugo

Au passage, rajoutez aussi ces deux règles dans le fichier /etc/init.d/firewall :

  • Autoriser le ssh depuis le dom0 vers les domu :
iptables -t filter -A OUTPUT -d 10.99.1.0/24 -p tcp --dport 22 -j ACCEPT
  • Autoriser les domu à interroger le ntp :
iptables -t filter -A INPUT -p udp --dport 123 -j ACCEPT

Puis on exécute :

dom0# /etc/init.d/firewall

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 en un coup :

dom0# xen create routeur.cfg -c

Pour quitter la console CTRL+$ ou CTRL+^, depend de 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

Et la, deux solutions : vous êtes en train de tester chez vous ou sur un réseau ou l’hyperviseur et cette machine ont une IP dans le même sous réseau (par exemple, quand je maquettais chez moi, l’hyperviseur avait l’IP 192.168.0.200 et mon domu routeur, l’IP 192.168.0.201. Dans ce cas, pas de soucis, les routes seront bonnes (IP et Gateway dans le même réseau). Vous pouvez pinger l’extérieur et l’extérieur peut vous pinger;
Par contre, si vous êtes sur une dédibox avec ces fameuses IPFailover, elles sont généralement dans un tout autre réseau et la, paf, pas de routes correctes :

routeur# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
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
195.154.49.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

On va donc devoir lui dire comment joindre la gateway (qui je rappelle est la même qu’utilise le Dom0)
Dans mon cas, la gateway de ma box est 62.210.83.1

routeur# route add 62.210.83.1/32 dev eth0
routeur# route add default gw 62.210.83.1 dev eth0

Et la, on doit pouvoir pinger cette VM de l’extérieur sur son Ip publique (ici, mon Ip failover), se connecter dessus en ssh, etc..
Depuis celle ci, les pings vers l’extérieur fonctionnent également.
Par contre, si on tente de pinger une machine sur le réseau 195.154.49.0/24, cela échoue..
Il faut supprimer la route :

routeur# route del -net 195.154.49.0 netmask 255.255.255.0

Encore un truc curieux, si l’on rajoute les routes dans le fichier /etc/network/interfaces, ça ne fonctionne pas (la, je ne comprend pas, si quelqu’un voit….)
Ma solution de contournement :
Fichier /etc/init.d/debugo (en mettant la bonne gateway) :

#!/bin/bash
route add 62.210.83.1/32 dev eth0
route add default gw 62.210.83.1 dev eth0
route del -net 195.154.49.0 netmask 255.255.255.0

Ensuite :

routeur# chmod +x /etc/init.d/debugo
routeur# insserv debugo

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

Une certaine lenteur doit vous sauter aux yeux, signe d’un soucis de résolution dns (mais ce n’est rien, on va rapidement y remédier).
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
00:10:27.395359 IP 10.2.1.3 > 8.8.8.8: ICMP echo request, id 338, seq 160, length 64
00:10:28.395391 IP 10.2.1.3 > 8.8.8.8: ICMP echo request, id 338, seq 161, 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 la rendre 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
00:13:07.483422 IP 10.2.1.3 > 8.8.8.8: ICMP echo request, id 338, seq 320, 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
 17:33:37.053951 IP 10.2.1.3 > 99.99.99.99: ICMP echo request, id 399, seq 263, length 64
 17:33:38.054086 IP 10.2.1.3 >99.99.99.99: ICMP echo request, id 399, seq 264, 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 du réseau 10.2.1.0/24 :

routeur# iptables -t nat -A POSTROUTING -o eth0 -s 10.2.1.0/24 -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 recoit 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
RESEAUONLINE.0  0.0.0.0         255.255.255.0   U     0      0        0 eth0

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 /etc/init.d/debugo pour que cette route soit chargée avec les deux autres.
Il doit ressembler à cela :

#!/bin/bash
route add 62.210.83.1/32 dev eth0
route add default gw 62.210.83.1 dev eth0
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

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.

# apt-get install nginx

Puis sur la vm routeur :

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 IV : Firewall.

2 réflexions sur « Tuto Virtualisation : Partie III, mise en oeuvre »

  1. On peut suivre la création avec :
    dom0# tail -f /var/log/xen-tools/routeur.log
    =>/var/log/xen-tools# tail -f routeur–role.log
    Une fois la vm créé, on va éditer le fichier /etc/xen/routeur.cfg. => existe plus. pas trouvé

Laisser un commentaire

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