9. Créer des interfaces de type veth

L'introduction d'un nouvel espace de nom réseau revient à introduire une nouvelle table de routage dans un même système. Dans la vue ci-dessous, le cadre vert illustre les éléments ajoutés au routeur R2 : un lien vers un espace de noms baptisé green avec un serveur web hébergé à l'intérieur.

Les manipulations présentées dans cette section doivent aussi être réalisées sur le routeur R3 en suivant le plan d'adressage présenté à la Section 2, « Topologie réseau étudiée ».

Topologie logique avec un espace de noms réseau

Q25.

Comment créer une paire d'interfaces réseau virtuelles de type veth sur un système GNU/Linux ?

Rechercher dans les pages de manuels la commande ip link la syntaxe qui permet de créer la paire d'interfaces veth0 et veth1.

# ip link add veth1 type veth peer name veth0

# ip link ls dev veth0
5: veth0@veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN \
                                mode DEFAULT group default qlen 1000
    link/ether 86:22:d2:14:05:b4 brd ff:ff:ff:ff:ff:ff

# ip link ls dev veth1
6: veth1@veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN \
                                mode DEFAULT group default qlen 1000
    link/ether 9e:c8:44:e6:fa:70 brd ff:ff:ff:ff:ff:ff

Q26.

Comment créer un nouvel espace de noms réseau appelé green et affecter l'interface veth1 à cet espace de noms ?

Rechercher dans les pages de manuels ip-netns la syntaxe qui permet de créer un nouvel espace de noms réseau.

# ip netns add green
# ip netns ls
green

L'affectation d'une interface à l'espace de noms se fait avec la commande suivante.

# ip link set veth1 netns green

Q27.

Comment visualiser et modifier l'état des interfaces de type veth dans les deux espaces de noms réseau ?

Rechercher dans les pages de manuels ip-netns la syntaxe qui permet d'exécuter une commande dans un nouvel espace de noms réseau.

On active les deux interfaces et on affiche les informations d'état.

# ip link set dev veth0 up

# ip link ls dev veth0
5: veth0@if6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue \
                        state LOWERLAYERDOWN mode DEFAULT group default qlen 1000
    link/ether 86:22:d2:14:05:b4 brd ff:ff:ff:ff:ff:ff link-netns green
# ip netns exec green ip link set dev veth1 up

# ip netns exec green ip link ls dev veth1
6: veth1@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue \
                        state UP mode DEFAULT group default qlen 1000
    link/ether 9e:c8:44:e6:fa:70 brd ff:ff:ff:ff:ff:ff link-netnsid 0

Q28.

Comment valider les communications entre les deux espaces de noms réseau ?

Utiliser les adresses de lien local IPv6 pour faire un test ICMP avec l'adresse multicast de sollicitation d'hôte.

Le test avec la commande ping doit désigner l'interface du lien à utiliser.

# ping -c2 ff02::1%veth0
PING ff02::1%veth0(ff02::1%veth0) 56 data bytes
64 bytes from fe80::8422:d2ff:fe14:5b4%veth0: icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from fe80::9cc8:44ff:fee6:fa70%veth0: icmp_seq=1 ttl=64 time=0.168 ms (DUP!)
64 bytes from fe80::8422:d2ff:fe14:5b4%veth0: icmp_seq=2 ttl=64 time=0.046 ms

--- ff02::1%veth0 ping statistics ---
2 packets transmitted, 2 received, +1 duplicates, 0% packet loss, time 20ms
rtt min/avg/max/mdev = 0.046/0.098/0.168/0.051 ms

Le voisinage réseau de l'interface veth0 désigne l'adresse MAC de l'interface veth1 dans l'espace de noms réseau green.

# ip nei ls dev veth0
fe80::9cc8:44ff:fee6:fa70 lladdr 9e:c8:44:e6:fa:70 STALE

Réciproquement, le voisinage réseau de l'interface veth1 désigne l'adresse MAC de l'interface veth0.

# ip netns exec green ip nei ls dev veth1
fe80::8422:d2ff:fe14:5b4 lladdr 86:22:d2:14:05:b4 router STALE

On peut donc conclure que le lien point à point entre les deux espaces de noms réseau est fonctionnel.

Q29.

Comment ajouter deux préfixes réseau IPv4 et IPv6 sur la liaison point à point entre les deux interfaces de type veth ?

Comme lors des étapes précédentes, on reprend les commandes ip avec la désignation de l'espace de noms réseau pour l'interface à l'extrémité du lien point à point.

Dans notre exemple sur le routeur R2, on utilise les préfixes 10.1.2.0/30 et 2001:678:3fc:d::/64.

  • Pour l'interface veth0 :

    # ip addr add 10.1.2.1/30 brd + dev veth0
    # ip -6 addr add 2001:678:3fc:d::1/64 dev veth0
  • Pour l'interface veth1 :

    # ip netns exec green ip addr add 10.1.2.2/30 brd + dev veth1
    # ip netns exec green ip -6 addr add 2001:678:3fc:d::2/64 dev veth1

Comme dans la question précédente, on peut qualifier la communication entre les deux interfaces au niveau réseau à l'aide de la commande ping.

Voici une copie d'écran des tests effectués depuis l'espace de noms green.

# ip netns exec green ping -qc2 10.1.2.1
PING 10.1.2.1 (10.1.2.1) 56(84) bytes of data.

--- 10.1.2.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 33ms
rtt min/avg/max/mdev = 0.043/0.055/0.067/0.012 ms

# ip netns exec green ping -qc2 2001:678:3fc:d::1
PING 2001:678:3fc:d::1(2001:678:3fc:d::1) 56 data bytes

--- 2001:678:3fc:d::1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 18ms
rtt min/avg/max/mdev = 0.050/0.081/0.113/0.032 ms

Q30.

Comment publier les préfixes réseau correspondant à la nouvelle liaison point à point via OSPF avec un débit binaire de lien à 1Gbps ?

Une fois la console vtysh ouverte, accéder en mode configuration de l'interface puis des deux démons de routage.

interface vethX
bandwidth
router ospf
network A.B.C.D/MM area 0
router ospf6
interface vethX area 0.0.0.0

On commence par la définition du débit binaire au niveau de l'interface.

R1# conf t
R1(config)# int veth0
R1(config-if)# bandwidth 1000000
R1(config-if)# ^Z

On peut ensuite publier les préfixes réseau IPv4 et IPv6 au niveau de chaque instance de protocole de routage OSPF.

R1# conf t
R1(config)# router ospf
R1(config-router)# network 10.1.2.0/30 area 0
R1(config-router)# ^Z
R1# conf t
R1(config)# router ospf6
R1(config-ospf6)# interface veth0 area 0.0.0.0
R1(config-ospf6)# ^Z

Enfin, on vérifie la présence des deux préfixes réseau dans les bases OSPF.

R2# sh ip route 10.1.2.0/30
Routing entry for 10.1.2.0/30
  Known via "ospf", distance 110, metric 1, tag 0, vrf 0
  Last update 00:02:44 ago
  >  directly connected, veth0

Routing entry for 10.1.2.0/30
  Known via "connected", distance 0, metric 0, tag 0, vrf 0, best, fib
  >* directly connected, veth0
R2# sh ipv6 route 2001:678:3fc:d::/64
Routing entry for 2001:678:3fc:d::/64
  Known via "ospf6", distance 110, metric 1, tag 0, vrf 0
  Last update 00:04:44 ago
  >  directly connected, veth0

Routing entry for 2001:678:3fc:d::/64
  Known via "connected", distance 0, metric 0, tag 0, vrf 0, best, fib
  >* directly connected, veth0

Q31.

Est-ce que les adresses IPv4 et IPv6 situées dans l'espace de noms green joiganbles depuis les réseaux distants ?

Le fait d'avoir placé l'interface veth1 dans un espace de noms réseau distinct, impose l'utilisation d'une table de routage propre à cet espace. Sur la base des opérations déjà effectuées, on s'interroge sur le fait que ces opérations suffisent pour que les communications soient fonctionnelles.

On fait des tests ICMP et ICMP6 depuis un autre routeur pour constater que si les flux parviennent bien à destination, il n'existe pas de solution retour.

Dans l'exemple ci-dessous, on teste les communications entre le routeur R1 et l'interface veth1 située au delà du routeur R3

On lance une requête ICMP depuis R1.

R1:~# ping -c3 10.1.3.2
PING 10.1.3.2 (10.1.3.2) 56(84) bytes of data.

--- 10.1.3.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 40ms

On lance l'analyse réseau dans l'espace de noms réseau green.

R3:~# ip netns exec green /usr/bin/tshark -i veth1 -f icmp
<snipped/>
Capturing on 'veth1'
 1 0.000000000    10.1.13.1 → 10.1.3.2     ICMP 98 Echo (ping) request  id=0x1309, seq=1/256, ttl=63
 2 1.013794602    10.1.13.1 → 10.1.3.2     ICMP 98 Echo (ping) request  id=0x1309, seq=2/512, ttl=63
 3 2.037727585    10.1.13.1 → 10.1.3.2     ICMP 98 Echo (ping) request  id=0x1309, seq=3/768, ttl=63
^C3 packets captured

On relève bien l'arrivée des requêtes à destination. Il n'y a cependant aucune réponse à ces requêtes.

En reprenant le même test avec ICMP6, on relève le même problème.

R1:~# ping -c3 2001:678:3fc:f::2
PING 2001:678:3fc:f::2(2001:678:3fc:f::2) 56 data bytes

--- 2001:678:3fc:f::2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 27ms

L'analyse réseau ne montre que l'arrivée des requêtes à destination.

R3:~# ip netns exec green /usr/bin/tshark -i veth1 -f icmp6
<snipped/>
Capturing on 'veth1'
 1 0.000000000 2001:678:3fc:d::1 → 2001:678:3fc:f::2 ICMPv6 118 Echo (ping) request id=0x130a, seq=1, hop limit=63
 2 1.001038537 2001:678:3fc:d::1 → 2001:678:3fc:f::2 ICMPv6 118 Echo (ping) request id=0x130a, seq=2, hop limit=63
 3 2.025046012 2001:678:3fc:d::1 → 2001:678:3fc:f::2 ICMPv6 118 Echo (ping) request id=0x130a, seq=3, hop limit=63

Q32.

Comment compléter les tables de routage IPv4 et IPv6 situées dans l'espace de noms green pour que le trafic sortant par l'interface veth1 soit émis correctement ?

On complète les tables de routage avec une route par défaut pour joindre les réseaux distants depuis l'espace de noms green.

La lecture des tables de routage dans l'espace de noms réseau green explique tout. Ces tables ne contiennent que l'entrée relative au lien point à point configuré entre les interfaces veth0 et veth1.

R3:~# ip netns exec green ip route ls
10.1.3.0/30 dev veth1 proto kernel scope link src 10.1.3.2

R3:~# ip netns exec green ip -6 route ls
2001:678:3fc:f::/64 dev veth1 proto kernel metric 256 pref medium
fe80::/64 dev veth1 proto kernel metric 256 pref medium

Il faut donc compléter ces tables de routage avec une route par défaut vers l'espace de noms réseau par défaut dans lequel est située l'interface veth0.

R3:~# ip netns exec green ip route add default via 10.1.3.1

R3:~# ip netns exec green ping -c1 ff02::2%veth1
PING ff02::2%veth1(ff02::2%veth1) 56 data bytes
64 bytes from fe80::8422:d2ff:fe14:5b4%veth1: icmp_seq=1 ttl=64 time=0.072 ms

--- ff02::2%veth1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms

R3:~# ip netns exec green ip -6 route add default via fe80::8422:d2ff:fe14:5b4 dev veth1

Les nouvelles tables de routage de l'espace de noms green font apparaître les routes par défaut

R3:~# ip netns exec green ip route ls
default via 10.1.3.1 dev veth1
10.1.3.0/30 dev veth1 proto kernel scope link src 10.1.3.2
R3:~# ip netns exec green ip -6 route ls
2001:678:3fc:f::/64 dev veth1 proto kernel metric 256 pref medium
fe80::/64 dev veth1 proto kernel metric 256 pref medium
default via fe80::8422:d2ff:fe14:5b4 dev veth1 metric 1024 pref medium

Les tests ICMP et ICMP6 de la question précédente montrent maintenant que les communications sont bien fonctionnelles. Les requêtes sont à nouveau émises depuis le routeur R1

R1:~# ping -c3 10.1.3.2
PING 10.1.3.2 (10.1.3.2) 56(84) bytes of data.
64 bytes from 10.1.3.2: icmp_seq=1 ttl=63 time=0.484 ms
64 bytes from 10.1.3.2: icmp_seq=2 ttl=63 time=0.068 ms
64 bytes from 10.1.3.2: icmp_seq=3 ttl=63 time=0.066 ms

--- 10.1.3.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 50ms
R1:~# ping -c3 2001:678:3fc:f::2
PING 2001:678:3fc:f::2(2001:678:3fc:f::2) 56 data bytes
64 bytes from 2001:678:3fc:f::2: icmp_seq=1 ttl=63 time=0.591 ms
64 bytes from 2001:678:3fc:f::2: icmp_seq=2 ttl=63 time=0.083 ms
64 bytes from 2001:678:3fc:f::2: icmp_seq=3 ttl=63 time=0.081 ms

--- 2001:678:3fc:f::2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 48ms

Q33.

Comment installer un service Web en écoute exclusivement sur les adresses IPv4 et IPv6 situées dans l'espace de noms réseau green ?

Pour aller au plus court, on installe le paquet lighttpd et on édite la configuration du service de façon à limiter l'accès aux adresses IP voulues.

R3:~# aptitude install lighttpd

On modifie ensuite le fichier de configuration /etc/lighttpd/lighttpd.conf de façon à limiter l'accès aux adresses IPv4 et IPv6 de l'interface veth1.

Voici une copie du correctif correspondant au routeur R3.

--- lighttpd.conf.orig  2018-10-15 15:42:12.345480008 +0000
+++ lighttpd.conf       2018-10-15 15:43:50.091036311 +0000
@@ -22,6 +22,9 @@
 compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

 # default listening port for IPv6 falls back to the IPv4 port
-include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
+#include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
 include_shell "/usr/share/lighttpd/create-mime.assign.pl"
 include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
+
+server.bind = "10.1.3.2"
+$SERVER["socket"] == "[2001:678:3fc:f::2]:80" { server.use-ipv6 = "enable" }

Relativement à une configuration classique, il faut lancer le serveur Web dans le contexte du nouvel espace de noms réseau. On commence donc par arrêter le démon lancé lors de l'installation du paquet.

R3:~# systemctl stop lighttpd

Là encore, pour aller au plus court on lance directement le démon dans le contexte de l'espace de noms réseau green.

R3:~# ip netns exec green lighttpd -f /etc/lighttpd/lighttpd.conf

R3:~# ip netns exec green ss -nlt '( src :80 )'
State      Recv-Q  Send-Q       Local Address:Port  Peer Address:Port
LISTEN     0       128               10.1.3.2:80         0.0.0.0:*
LISTEN     0       128    [2001:678:3fc:f::2]:80            [::]:*

Q34.

Comment valider l'accès au service Web situé dans l'espace de noms réseau green depuis un réseau distant ?

Comme la partie routage a été validée dans les questions précédentes, on passe directement à la couche application avec le chargement de la page Web par défaut du serveur.

Depuis le routeur R1, on obtient les résultats suivants.

R1:~# wget -O /dev/null http://10.1.3.2
--2018-10-16 14:32:06--  http://10.1.3.2/
Connexion à 10.1.3.2:80… connecté.
requête HTTP transmise, en attente de la réponse… 200 OK
Taille : 3378 (3,3K) [text/html]
Sauvegarde en : « /dev/null »

/dev/null       100%[===================>]   3,30K  --.-KB/s    ds 0s

2018-10-16 14:32:06 (209 MB/s) — « /dev/null » sauvegardé [3378/3378]
R1:~# wget -O /dev/null http://[2001:678:3fc:f::2]
--2018-10-16 14:34:39--  http://[2001:678:3fc:f::2]/
Connexion à [2001:678:3fc:f::2]:80… connecté.
requête HTTP transmise, en attente de la réponse… 200 OK
Taille : 3378 (3,3K) [text/html]
Sauvegarde en : « /dev/null »

/dev/null       100%[===================>]   3,30K  --.-KB/s    ds 0s

2018-10-16 14:34:39 (268 MB/s) — « /dev/null » sauvegardé [3378/3378]