28 mars 2024

Tuto Strongswan, partie II : Communications entre VMs

Deuxième partie de la série de tutoriels sur la mise en place d’un lien IPSEC avec Strongswan.

Dans cette partie, nous allons faire en sorte que les machines d’un réseau puissent contacter  les machines d’un autre réseau et vice-versa.

 

I – Un peu de réseau

A – Problématique

Avançons un peu dans la mise en place de notre architecture.
Si nous testons un ping d’un vpn vers une machine de l’autre coté, celui ci ne donnera rien…

Pourquoi ?

Tout d’abord, sur nos deux vpns, il faut activer le forward vu qu’ils doivent faire transiter des paquets.

Dans le fichier /etc/sysctl.conf,  modifiez la ligne :

net.ipv4.ip_forward=1

Puis pour la prise en compte :

# systctl -p

Ensuite, on va utiliser tcpdump sur la VM Test B (10.168.1.69) :

testB# tcpdump icmp -i any

Et depuis le VPN A :

vpnA# ping 10.168.1.69

Cas classique qu’on voit avec tcpdump : Le ping arrive bien, mais le retour ne se fait pas…

Problème de route manquante.

B – Solution

Pour cette route on a deux possibilités : soit celle-ci est ajoutée sur chaque machine,  soit on ne touche à rien et on ajoute la route uniquement sur le routeur (qui est je rappelle la gateway par défaut).

C’est ce que je faisais avant (pendant la phase de test).

  • Côté réseau A, pour aller vers B, cela faisait : VM A/Routeur A/ VPN A —> VPN B/ VM B
  • Côté réseau B, pour aller vers A, cela faisait : VM B/Routeur B/ VPN B —> VPN B/ VM B

Le côté asymétrique me déplaisait, j’avais donc rajouté au niveau de chaque VPN en entrée, du source routing, pour forcer ainsi :

  • A -> B : VM A/Routeur A/ VPN A —> VPN B/ Routeur B/ VM B
  • B -> A : VM B/Routeur B/ VPN B —> VPN A/ Routeur A/ VM A

Le source routing sur le VPN A par exemple :

ip route add default via 10.10.1.1 table 1
ip rule add priority 200 from 10.168.1.0/24 to 10.20.1.0/24 table 1

Mais au final, cela complexifie le réseau inutilement.

J’ai donc décidé de revenir à quelque chose de plus simple :

  • A -> B : VM A / VPN A —> VPN B/ VM B
  • B -> A : VM B/ VPN B —> VPN A/  VM A

Et ce donc, en mettant la nouvelle route sur chaque machine.

Le faire sur chaque machines n’est pas si problématique.
Mes machines sont connues, pas de machines qui arrivent ou qui partent, et éventuellement, si je veux qu’une ne puisse pas communiquer avec l’autre réseau, je peux.

Et si vraiment, y’a un côté dynamique sur qui est sur le réseau, un DHCP peut tout à fait ajouter la route a qui il faut.

 

Bref, sur chaque machine du réseau A, je rajouterais la route :

ip route add 10.168.1.0/24 via 10.20.1.2

et sur chaque machine du réseau B :

ip route add 10.20.1.0/24 via 10.168.1.2

Je rappelle, c’est un choix volontaire et réfléchi.

Chacun après peut faire comme il le sent.

II – Mise en place

A – On y croit !

Donc, sur la VM Test A, on ajoute un route vers le réseau 10.168.1.0/24 en indiquant que la passerelle est le VPN 10.20.1.2 :

TestA# ip route add 10.168.1.0/24 via 10.20.1.2

et sur la VM Test B, on ajoute :

TestB# ip route add 10.20.1.0/24 via 10.168.1.2

Maintenant qu’on a ceci, on se dit que tout est OK et qu’on est le roi du monde !

Mais une fois encore, mes configurations réseaux apportent leurs lots d’effets de bords.

B – Encore un problème

1 – A vers B

Depuis la VM Test A (10.20.169), on va faire quelques vérifications.

Tout d’abord :

testA# traceroute 10.168.1.69

traceroute to 10.168.1.69(10.168.1.69), 30 hops max, 60 byte packets
1 10.20.1.2 (10.20.1.2)
2 10.168.1.2 (10.168.1.2)
3 10.168.1.69(10.168.1.69)

Ça, c’est bon.

On confirme la route :

testA# ip route get 10.168.1.69

10.168.1.69 via 10.20.1.2 dev eth1 src 10.20.1.69
     cache

Ça aussi c’est bon.

Bon, bah plus qu’à pinguer alors !

Mais avant, sur le VPN B, on va écouter un peu :

vpnB# tcpdump icmp -i any

Ensuite, on revient sur la VM Test A et on lance :

testA# ping 10.168.1.69

PING 10.168.1.69(10.168.1.69) 56(84) bytes of data.
64 bytes from 10.168.1.240: icmp_seq=1 ttl=62 time=11.1 ms
......................

Et rien d’autres !? Juste un ping ?

En vérifiant sur le VPN B, on voit passer cela :

IP 10.168.1.2 > 10.168.1.69: ICMP redirect 10.20.1.69 to host 10.168.1.1, length 92

Gné ? Un ICMP redirect ?

Le VPN B dit à Test B qu’il faut mieux passer par Routeur B.

Avant d’expliquer, on va tester dans l’autre sens.

Mais avant, sur VM Test B, on va flusher le cache de routage (c’est elle qui a une mauvaise route)

testB# ip route flush cache
2 – B vers A

Maintenant, depuis la VM Test B (10.168.169) :

testB# traceroute 10.20.1.69

traceroute to 10.20.1.69 (10.20.1.69 ), 30 hops max, 60 byte packets
1 10.168.1.2 (10.168.1.2)
2 10.20.1.2 (10.20.1.2)
3 10.20.1.69(10.20.1.69)

Ras.

testB# ip route get 10.20.1.69

10.20.1.69 via 10.168.1.2 dev eth1 src 10.168.1.69
    cache

La aussi ras.

Sur le VPN B, on va refaire l’espion :

vpnB# tcpdump icmp -i any

Puis on pingue :

testB# ping 10.20.1.69

PING 10.20.1.69(10.20.1.69) 56(84) bytes of data.
64 bytes from 10.20.1.69: icmp_seq=1 ttl=62 time=12.7 ms
From 10.168.1.2: icmp_seq=2 Redirect Host(New nexthop: 10.168.1.1)
64 bytes from 10.20.1.69: icmp_seq=2 ttl=62 time=11.5 ms
...............................

Et c’est tout. Ce coup ci, on voit le nexthop.

Sur le VpnB, on voit toujours :

IP 10.168.1.2 > 10.168.1.69: ICMP redirect 10.20.1.69 to host 10.168.1.1, length 92

Le ICMP redirect indique à TestB de passer par 10.168.1.1. Ce que lui fait en mettant à jour ses tables.

On le voit maintenant avec :

testB# ip route get 10.20.1.69

10.20.1.69 via 10.168.1.1 dev eth1 src 10.168.1.69
    cache <redirected> expires 292sec

Ce que confirme :

testB# traceroute 10.20.1.69
traceroute to 10.20.1.69(10.20.1.69), 30 hops max, 60 byte packets
1 10.168.1.1 (10.168.1.1)
2..........................................

 

C – Pourquoi ?

Mais pourquoi le VPN B fait donc ce redirect ?

Et bien à cause de sa table de routage :

default via 10.168.1.1 dev eth0 onlink
10.168.1.0/24 dev eth0 proto kernel scope link src 10.168.1.2

Pour lui, la route par défaut c’est 10.168.1.1.
Pour 10.20.1.0/24 ? Et bah il considère que la meilleure route c’est 10.168.1.1.

Et comme il reçoit un paquet à destination « d’ailleurs » d’une machine sur le même réseau et qui peut donc en théorie causer à 10.168.1.1 (masque identique), il considérè qu’il se doit de l’en avertir.

 

D – Comment !

La solution est simple : il faut désactiver l’icmp redirect, sur le VPN B :

vpnB# echo 0 | tee /proc/sys/net/ipv4/conf/*/send_redirects

On peut aussi le faire dans le fichier /etc/sysctl.conf, mais j’ai observé que cela ne marchait pas forcement à tout les coups.

Le forcer comme je le fais marche au poil.

Pour terminer, on purge une dernière fois le cache de routage sur TestB :

testB# ip route flush cache

On peut tester à nouveau depuis Test A :

testA# ping 10.168.1.69

64 bytes from 10.168.1.69: icmp_seq=1 ttl=62 time=12.1 ms
From 10.20.1.2: icmp_seq=2 Redirect Host(New nexthop: 10.20.1.2)

Tiens, celui ci est marrant. Le Vpn A indique qu’il faut plutôt utiliser…. le Vpn A.

En fait, ce ICMP redirect découle de la route que nous avons ajoutée précédemment sur le Vpn A :

# ip route add 10.168.1.0/24 via 10.20.1.2

Une espèce de boucle en quelque sorte.

Du coup, pour Vpn A, on désactive aussi l’ICMP redirect :

vpnA# echo 0 | tee /proc/sys/net/ipv4/conf/*/send_redirects

Sur Tes tA on flushe :

testA# ip route flush cache

Et on peut retester :

testA# ping 10.168.1.69

 

III – Et enfin !

Maintenant, on teste tout :

vpnA# ping 10.168.1.2
vpnA# ping 10.168.1.69

vpnB# ping 10.20.1.2
vpnB# ping 10.20.1.69

testA# ping 10.168.1.2
testA# Ping 10.168.1.69

testB# ping 10.20.1.2
testB# ping 10.20.1.69

Tout doit bien passer sans encombre !

Félicitations ! Le tunnel est UP et opérationnel.

 

IV – Conclusion

Voila, nos machines peuvent communiquer entre elles.

On retiendra surtout que le fait de ne pas positionner les serveurs sur les gateways implique la prise en compte des icmp redirect en fonction de l’architecture réseau.

Dans l’article suivant, nous allons faire en sorte que notre réseau 10.168.1.0 puisse communiquer avec le net en passant par la Dedibox.

 


Envie de me soutenir et de me payer un café ? C’est sur la page Don !

2 réflexions sur « Tuto Strongswan, partie II : Communications entre VMs »

  1. Bonjour,
    je trouve votre article très intéressant, et je m’en suis inspiré pour faire un essai de VPN site à site avec pfsense d’un coté et ubuntu de l’autre (j’ai pris ce que j’avais sous la main). J’ai ajouté deux machines pour simuler un vpn site à site crédible, la machine derrière pfsense voit bien la machine derrière le ubuntu, mais dans le sens contraire rien ne passe, c’est inexplicable pour moi…

    Je ne comprend pas comment vous faite pour déterminer quelle route est en cause et pourquoi cela ne fonctionne pas. Si vous avez une idée ça m’intéresse beaucoup…

    1. Bonjour G 🙂

      Tes pfsense et Ubuntu sont routeurs et gateway vpn ?
      Un traceroute d’un côté, un traceroute de l’autre. Tu devrais reperer le point de blocage.
      Pour debuger, du ping de ta becane derrière ubuntu vers la becane derrière pfsense et du tcpdump sur tout le monde (tcpdump -i any icmp)
      Il se peut que ce soit juste un pb de FW qq part

      Un petit schéma avec les ips ?

Laisser un commentaire

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