Janvier 2013 Archives

2013-01-22 12:02

Xen, la kimsufi, et l'IPV6

J'ai profité de la nouvelle gamme de kimsufi pour changer de serveur dédié, et passer à une solution Xen + Puppet. Il est ainsi facile de créer machine de test, pour jouer pendant quelques heures avec un nouveau logiciel sans pourrir le système hôte.

Afin de déployer mon serveur rapidement, j'ai opté pour un dom0 sous Debian Wheezy (qui est déjà en phase de freeze, et devrait rapidement devenir la nouvelle Debian stable). Mais parce que j'aime FreeBSD, c'est l'OS d'un de mes domU. Et comme FreeBSD est une horreur à déployer en tant que domU, j'ai déployé un deuxième domU sous NetBSD.

Je souhaitais que chacune de mes machine soit joignable en ipv4 et ipv6. Je vais donc décrire ma démarche dans cet article.

Prérequis : posséder un dom0 avec connexion IPv4 et IPv6 fonctionnelles.


Créer le bridge


Le bridge permettra de relier plusieurs interfaces entre elles, à la manière d'un switch. On pourra ainsi connecter toutes les machines virtuelles à ce bridge, pour qu'elle puisse de joindre entre elle. On pourra également router le traffic entre l'interface physique eth0 et le bridge, pour joindre le monde extérieur.

J'ai commencé par créer le réseau virtuel. Il faut pour cela charger le module dummy :

# modprobe dummy

On peut ensuite ajouter le ligne suivante dans le fichier /etc/modules afin de le charger au démarrage :

dummy

Il faut ensuite créer une interface virtuelle dummy0, et lui attribuer une IP. On utilisera le réseaux 10.0.0.0/24 en IPv4. Pour l'IPv6, j'utiliserai une partie du /64 fourni par OVH. Je possède un stock d'adresse du type 2001:1:2:3::/64. J'utiliserai le sous-réseau 2001:1:2:3:1::/80 pour mon réseau virtuel.

Je modifie donc le fichier /etc/network/interfaces pour ajouter la section suivante :

auto br0
iface br0 inet static
        ##
        # ipv4 address
        address 10.0.0.1
        netmask 255.255.255.0
        broadcast 10.0.0.255
        ##
        # ipv6 address
        up ip -6 addr add 2001:1:2:3:1::111/80 dev br0
        down ip -6 addr del 2001:1:2:3:1::111/80 dev br0
        ##
        # Add dummy0 (virtual interface) and setup the bridge
        bridge_ports dummy0
        bridge_maxwait 5
        bridge_stp off
        bridge_fd 0

On attribue ici les adresses 10.0.0.1 et 2001:1:2:3:1::1231 au bridge br0. On connecte y l'interface virtuelle dummy0.


Router les adresses IPv6


L'interface br0 possède donc l'IPv6 2001:1:2:3:1::1231. Deux autres machines seront connectées avec les IPv6 2001:1:2:3:1::1232 et 2001:1:2:3:1::1233. Il faudra router les paquets entre les interfaces eth0 et br0. Il faut donc activer le transfert d'IP en IPv6. On ajoute les lignes suivantes à /etc/sysctl.conf :

net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1

Puis on applique les changements avec la commande :
# sysctl -p

Enfin, on ajoute les routes nécessaires dans /etc/network/interfaces, en modifiant la section précedemment ajoutée :

auto br0
iface br0 inet static
        ##
        # ipv4 address
        address 10.0.0.1
        netmask 255.255.255.0
        broadcast 10.0.0.255
        ##
        # ipv6 address
        up ip -6 addr add 2001:1:2:3:1::111/80 dev br0
        down ip -6 addr del 2001:1:2:3:1::111/80 dev br0
        ##
        # Add dummy0 (virtual interface) and setup the bridge
        bridge_ports dummy0
        bridge_maxwait 5
        bridge_stp off
        bridge_fd 0
	##
        # Add routes
        post-up ip route add 2001:1:2:3:1::/80 dev br0
        post-down ip route del 2001:1:2:3:1::/80 dev br0


Transférer les paquets NDP


Il est impossible, à ce stade, de joindre le monde extérieur depuis une machine du sous-réseau 2001:1:2:3:1::/80. En effet, le routeur d'OVH s'attend à trouver un réseau "à plat". Il considère donc uniquement les adresses attribuées à eth0.

La manière la plus simple de résoudre ce problème serait de modifier les tables de routage du routeur, par exemple via une interface web. Ce n'est malheureusement pas possible. Il va donc falloir tricher un peu.

En IPv6, le protocole utilisé pour découvrir les différents appareils connectés à un lien est appelé NDP (Neighbor Discovery Protocol). C'est l'équivalent du protocle ARP en IPv4, mais avec de nombreuses fonctionnalités supplémentaires : découverte des routeurs, auto-configuration de l'interface et des routes...
Le noyeau Linux possède une fonctionnalité appelée "proxy NDP", qui permet de transférer les paquets NDP d'une interface à une autre, et de résoudre les situations telles que celle qui nous concerne.

On va donc transférer les paquets NDP des adresses 2001:41d0:8:b74d:1::1231, 2001:41d0:8:b74d:1::1232 et 2001:41d0:8:b74d:1::1233 sur l'interface eth0, et les paquets NDP de la passerelle OVH (2001:1:2:3ff:ff:ff:ff:ff) sur l'interface br0. De cette manière, la paserelle verra un réseau "plat" possédant 4 adresses (2001:41d0:8:b74d::1, 2001:41d0:8:b74d:1::1231, 2001:41d0:8:b74d:1::1232, et 2001:41d0:8:b74d:1::1233).

On commence par activer le proxy NDP en modifiant le fichier /etc/sysctl.conf :

net.ipv6.conf.default.proxy_ndp=1
net.ipv6.conf.all.proxy_ndp=1

On applique la nouvelle configuration :

# sysctl -p

On modifie la section précédemment ajoutée dans le fichier /etc/network/interfaces pour indiquer quels paquets NDP transférer, et sur quelle interface :

auto br0
iface br0 inet static
        ##
        # ipv4 address
        address 10.0.0.1
        netmask 255.255.255.0
        broadcast 10.0.0.255
        ##
        # ipv6 address
        up ip -6 addr add 2001:1:2:3:1::1/80 dev br0
        down ip -6 addr del 2001:1:2:3:1::1/80 dev br0
        ##
        # Add dummy0 (virtual interface) and setup the bridge
        bridge_ports dummy0
        bridge_maxwait 5
        bridge_stp off
        bridge_fd 0
        ##
        # Add routes and NDP proxy (to be reachable)
        post-up ip route add 2001:1:2:3:1::/80 dev br0
        post-up ip neigh add proxy 2001:1:2:3ff:ff:ff:ff:ff dev br0
        post-up ip neigh add proxy 2001:1:2:3:1::1 dev eth0
        post-up ip neigh add proxy 2001:1:2:3:1::2 dev eth0
        post-up ip neigh add proxy 2001:1:2:3:1::3 dev eth0
        post-down ip route del 2001:1:2:3:1::/80 dev br0
        post-down ip neigh del proxy 2001:1:2:3ff:ff:ff:ff:ff dev br0
        post-down ip neigh del proxy 2001:1:2:3:1::1 dev eth0
        post-down ip neigh del proxy 2001:1:2:3:1::2 dev eth0
        post-down ip neigh del proxy 2001:1:2:3:1::3 dev eth0

L'adresse 2001:1:2:3ff:ff:ff:ff:ff est celle de la passerelle OVH.


IPv4 : le NAT


OVH fournit une seule adresse IPv4. J'ai donc choisit d'utiliser le NAT pour joindre le monde extérieur en IPv4. Pour cela, il faut d'abord activer le transfert d'IP pour l'IPv4. On ajoute dans le fichier /etc/sysctl.conf :

net.ipv4.ip_forward=1

Puis on applique les changements avec la commande :
# sysctl -p

Pour faire le transfert d'adresse, on ajoute ensuite la règle iptables suivante :

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE


Connecter les domU


Comme nous avons configuré nous-même le réseau, Xen n'a pas à s'en charger. On doit donc désactiver les scripts de configuration de Xen, en commentant les différentes lignes contenant network-script dans le fichier /etc/xen/xend-config.sxp :

# #(network-script network-bridge)
#(network-script network-route)
#(network-script network-nat)

On redémarre Xen pour prendre la nouvelle configuration en compte :

# /etc/init.d/xen restart

Il ne reste plus qu'à connecter les domU à l'interface br0, en spécifiant dans le fichier /etc/xen/nom_du_domU le paramètre suivant :

vif=['bridge=br0']

On paramétrera ensuite le domU à l'aide de la console Xen, pour utiliser la passerelle 2001:1:2:3ff:ff:ff:ff:ff en ipv6, et 10.0.0.1 en ipv4.


Posted by St3rk | Permanent link