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.
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
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
Merci pour la correction 😉
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)
Merci, j’ai rajouté cela 😉