Problème à tique

Le VPN, c'est bien. Ça permet de faire des choses sales sur les réseaux P2P sans se faire gauler, mais surtout ça permet aux entreprises d'étendre leur réseau à moindre coût en se servant de l'Interwebz. Le souci, c'est que tant qu'on a un réseau simple, le VPN est simple, dès que le réseau devient plus compliqué, tu commences à pleurer ta maman.

Illustration. Dans un monde idéal, le siège de l'entreprise a une IP publique et est relié à un bureau détaché par un tunnel. L'ensemble des réseaux privés entre A et B est complètement cohérent et ne se recoupe évidemment jamais :

Le VPN qui ne peut pas exister parce qu'on vit dans la réalité

Dans ce cas idyllique, il n'y a qu'un seul tunnel ESP à gérer de chaque côté : celui qui va du réseau 192.168.0.0/24 vers le réseau 10.0.0.0/22 dans un sens et inversement pour l'autre routeur. Maintenant, on ne vit pas au pays des Teletubbies sous LSD et ce genre de cas n'arrive pour ainsi dire jamais. Dans la réalité, on a des trucs comme ça :

WTF !?!

Même si on pourrait s'amuser à faire quelques optimisations, il faut se rendre à l'évidence : la discontinuité des plages d'adresses va être une plaie ouverte, béante, infectée et purulente. 5 réseaux d'un côté, 10 de l'autre, ça nous fait 50 tunnels ESP. Et on ne parle ici que de deux sites, je te laisse imaginer le résultat quand on en vient à gérer plusieurs bureaux distants.

Il serait grand temps de mettre du routage à moteur dans toute ce merdier histoire d'optimiser tes performances à Tetris en toute quiétude.

YATTAAAAAAAAAA

Comme je ne suis pas chaud pour le faire à la brute sur un OpenBSD, je te propose de faire un petit exemple de configuration avec Vyatta et deux routeurs.

On va donc faire un truc qui ressemble vaguement au schéma du dessus. Je te passe les subtilités sans intérêt concernant la configuration du VPN à proprement parler, sache simplement qu'on ne crée qu'un seul tunnel ESP entre deux hôtes gérés par une interface de loopback des deux côtés.

vpn {
    ipsec {
[…]
        site-to-site {
            peer 202.156.82.2 {
[…]
                local-ip 202.156.82.1
                tunnel 1 {
                    esp-group ESP_STD
                    local-subnet 169.254.0.1/32
                    remote-subnet 169.254.0.2/32
                }
            }
        }
    }
}

Et on obtient ça :

Un seul tunnel ESP

vyatta@vttr1:~$ /bin/ping -I 169.254.0.1 169.254.0.2 -c3
PING 169.254.0.2 (169.254.0.2) from 169.254.0.1 : 56(84) bytes of data.
64 bytes from 169.254.0.2: icmp_seq=1 ttl=64 time=1.99 ms
64 bytes from 169.254.0.2: icmp_seq=2 ttl=64 time=3.19 ms
64 bytes from 169.254.0.2: icmp_seq=3 ttl=64 time=2.70 ms

--- 169.254.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.994/2.631/3.198/0.497 ms

Bref, ça marche tout simplement. Le seul problème, c'est qu'il s'agit de deux hôtes différents, par définition ils ne sont pas dans le même réseau. Impossible donc de faire tourner un service type OSPF entre nos deux routeurs sans ajouter une petite couche supplémentaire.

IP dans IP, c'est un truc sexuel ça non ?

On va donc monter un tunnel GRE (ou SIT si on veut faire de l'IPv6) pour faire passer une plage d'adresses partagée (169.254.1.0/30) entre les deux routeurs en s'appuyant sur les adresses virtuelles de notre tunnel IPSEC.

vyatta@vttr1:~$ configure
[edit]
vyatta@vttr1# set interfaces tunnel tun0 encapsulation gre
[edit]
vyatta@vttr1# set interfaces tunnel tun0 address 169.254.1.1/30
[edit]
vyatta@vttr1# set interfaces tunnel tun0 local-ip 169.254.0.1
[edit]
vyatta@vttr1# set interfaces tunnel tun0 remote-ip 169.254.0.2
[…]
vyatta@vttr1:~$ show interfaces tunnel
Interface    IP Address         State       Link   Description
tun0         169.254.1.1/30     up          up

On applique la même configuration miroir sur l'autre routeur et on obtient un domaine de broadcast qui s'étend entre les deux routeurs parfaitement à l'abri à l'intérieur d'un tunnel IPSEC :

vyatta@vttr1:~$ ping 169.254.1.2
PING 169.254.1.2 (169.254.1.2) 56(84) bytes of data.
PING 169.254.1.2 (169.254.1.2) 56(84) bytes of data.
64 bytes from 169.254.1.2: icmp_seq=1 ttl=64 time=0.792 ms

--- 169.254.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.792/0.792/0.792/0.000 ms

Oly Shit Per Fuck

La plupart du temps, quand on parle d'OSPF, une partie non-négligeable de l'audience commence à vomir de manière incontrôlée. Aussi, comme je tiens à ton estomac, je ne vais pas te faire l'affront d'entrer dans des détails glauques, on va se contenter de quelques lignes sur nos routeurs, juste pour voir le principe :

protocols {
    ospf {
        area 0.0.0.0 {
            network 169.254.1.0/30
        }
        redistribute {
            static {
            }
        }
    }
}
[…]
vyatta@vttr1:~$ show ip ospf neighbor

    Neighbor ID Pri State           Dead Time Address         Interface            RXmtL RqstL DBsmL
192.168.56.101    1 Full/DROther      33.937s 169.254.1.2     tun0:169.254.1.1         0     0     0

Il suffit alors de déclarer des routes statiques sur une interface active d'un côté pour les voir magiquement apparaître de l'autre ! En supposant que je déclare un réseau d'interconnexion 192.168.0.0/24 sur le routeur vttr1, je peux déclarer la route statique suivante :

vyatta@vttr1# set protocols static route 10.0.0.0/22 next-hop 192.168.0.2
[edit]

Et la voir apparaître aussitôt sur vttr2 :

vyatta@vttr2:~$ show ip route ospf
[…]
O>* 10.0.0.0/22 [110/20] via 169.254.1.1, tun0, 00:01:55
O   169.254.1.0/30 [110/10] is directly connected, tun0, 00:07:59

Foutaises

Moyennant donc un petit effort de configuration et en sacrifiant quelques moutons et plages d'adresses IP (un gag s'est d'ailleurs dissimulé dans ce billet, si tu es capable de le trouver, je te donne un carambar), on peut simplifier considérablement le déploiement d'un réseau VPN à grande échelle avec des plans d'adressage chaotique entre différents sites distants. Cela va également simplifier, dans une moindre mesure, les interconnexions VPN maillés entre plusieurs sites, même si le risque de se retrouver avec un gros bordel est beaucoup plus important qu'avec une architecture comprenant simplement un hub central.