Dans cette troisième partie de la série sur Strongswan, nous allons étudier la liaison Internet vers le réseau à domicile par le VPN et ce dans les deux sens.
En gros : Internet -> réseau VM Dedibox -> Domicile
L’idée, c’est d’avoir la possibilité d’avoir :
- un service sur une VM à domicile, accessible par une IP de la Dedibox.
- une VM à domicile qui sort sur le Net par la Dedibox
I – Service à domicile, accessible depuis l’IP Dedibox
Pour la démonstration, on va utiliser Nginx, c’est rapide et simple à tester. Et on va faire en sorte que ce Nginx, installé sur une VM à domicile (10.168.1.0/24) soit accessible depuis l’IP de la Dedibox.
Si je fais http://IP.DEDIBOX, j’ai le nginx à domicile qui répond, à travers le VPN.
A – Mise en place
Sur une nouvelle machine de test sur 10.168.1.100 (réseau à domicile), on va juste installer un Nginx de base.
test# apt install nginx
On teste déjà en interne depuis le vpn B :
vpnB# wget http://10.168.1.100
Ok, on a bien un retour.
On teste alors depuis le routeur A, à travers le VPN donc :
routeurA# wget http://10.168.1.100
Nikel la aussi.
Bon, on se dit bêtement qu’en ajoutant ceci au niveau du routeur A, ça devrait marcher :
iptables -t nat -A PREROUTING -d IP.DEDIBOX -p tcp --dport 80 -j DNAT --to-destination 10.168.1.100 iptables -t filter -A FORWARD -p tcp -d 10.168.1.100 --dport 80 -j ACCEPT
Et la, si on teste depuis une bécane lambda :
xxx# wget http://IP.DEDIBOX
Ça ne fonctionne pas…. Mais pourquoi ?
Sur le routeur A, on va écouter pendant qu’on refait la requête :
routeurA# tcpdump port 80 -i any IP IP.DOMICILE.29796 > IP.DEDIBOX.80: Flags [S], ... IP IP.DOMICILE.29796 > 10.168.1.100.80: Flags [S], ...
Ça, c’est bon.
Sur le vpn A :
vpnA# tcpdump port 80 -i any IP IP.DOMICILE.29804 > 10.168.1.100.80: Flags [S], ... IP IP.DOMICILE.29804 > 10.168.1.100.80: Flags [S], ...
Ça aussi, c’est bon.
Et sur le VPN B :
vpnB# tcpdump port 80 -i any rien...
Il est la notre problème ! Pourquoi donc ça n’arrive pas sur le VpnB ? La destination est bonne pourtant…
Oui, mais petit rappel sur les policies en cours sur le VPN :
vpnA# ip xfrm policy src 10.168.1.0/24 dst 10.20.1.0/24 dir fwd priority 187712 ptype main tmpl src IP.DOMICILE dst 10.10.1.2 proto esp reqid 32 mode tunnel src 10.168.1.0/24 dst 10.20.1.0/24 dir in priority 187712 ptype main tmpl src IP.DOMICILE dst 10.10.1.2 proto esp reqid 32 mode tunnel src 10.20.1.0/24 dst 10.168.1.0/24 dir out priority 187712 ptype main tmpl src 10.10.1.2 dst IP.DOMICILE proto esp reqid 32 mode tunnel src 0.0.0.0/0 dst 0.0.0.0/0 socket in priority 0 ptype main src 0.0.0.0/0 dst 0.0.0.0/0 socket out priority 0 ptype main src 0.0.0.0/0 dst 0.0.0.0/0 socket in priority 0 ptype main src 0.0.0.0/0 dst 0.0.0.0/0 socket out priority 0 ptype main
Et si la destination est correcte, quelle est la source ?
Bah vi, IP.DOMICILE, et ça ne matche aucune régle XFRM.
On pourrait alors tout à faire se dire, et bien, sur le routeur, je « patch » ainsi :
routeurA# iptables -t nat -A POSTROUTING -d 10.168.1.100 -j SNAT --to 10.20.1.2
Tous les paquets à destination de 10.168.1.100 voit la source modifiée (SNAT) en 10.20.1.2.
Mais c’est crado, car on introduit alors un changement de source et, bien que cela fonctionne, sur le serveur Web, on a l’IP de notre VPN A en client…
Il faut trouver mieux !
B – Ouvrir les horizons !
Le hic se situe dans ce que le VPN offre comme réseaux.
On va l’élargir et lui faire proposer … tout.
Sur le VPN A, dans le fichier /etc/ipsec.conf, on modifie le leftsubnet :
leftsubnet=0.0.0.0/0
et cote VPN B, dans le fichier /etc/ipsec.conf, on modifile le righsubnet :
rightsubnet=0.0.0.0/0
On relance :
Sur les deux VPNS :
vpnX# ipsec stop
Puis, encore sur les deux :
vpnX# ipsec start
Et la, ha un moment…. si vous aviez pris la main sur le VPN B depuis une machine de son réseau avec par exemple :
xxx# ssh 10.168.1.2
je dois vous entendre dire :
Bah merde, j’ai plus la main sur mon VPN !?
Et oui, plus possible depuis le réseau B de le contacter. Ha, la machine tourne bien : on peut y accéder en mode console
hyperv# virsh console vpn
ou
hyperv# xen console vpn
par exemple…
On y arrive également depuis le réseau A et le tunnel VPN est toujours OK, les machines se voient toujours.
Pas de panique, on va régler ceci dans quelques instants.
En attendant, on peut déjà constater que notre Nginx devient bien accessible à travers l’IP de la box :
xxx# wget http://IP.DEDIBOX
nous retourne bien l’index du serveur web à domicile.
On peut zieuter son log pour bien voir l’ip source (qui du coup, sera celle aussi de votre domicile si vous le faites depuis chez vous… Logique…)
C – Passtrough
Maintenant, on va regarder pourquoi le VPN B ne répond plus depuis des machines de son réseau, à savoir 10.168.1.0/24.
Une fois connecté dessus (console ou ssh externe), regardons les policies en cours :
vpnB# ip xfrm policy src 0.0.0.0/0 dst 10.168.1.0/24 dir fwd priority 193856 ptype main tmpl src IP.DEDIBOX dst 10.168.1.2 proto esp reqid 10 mode tunnel src 0.0.0.0/0 dst 10.168.1.0/24 dir in priority 193856 ptype main tmpl src 212.83.183.204 dst 10.168.1.2 proto esp reqid 10 mode tunnel src 10.168.1.0/24 dst 0.0.0.0/0 dir out priority 193856 ptype main tmpl src 10.168.1.2 dst 212.83.183.204 proto esp reqid 10 mode tunnel [...]
Et oui, en élargissant à tous les réseaux (0.0.0.0/0) on inclue également notre réseau 10.168.1.0/24.
Du coup, ce qui s’adresse ou vient de 10.168.1.0/24, c’est le tunnel qui gère et évidement, ça ne fonctionne pas.
Il faut donc l’exclure et ceci se fait simplement.
Sur le VPN B dans le fichier /etc/ipsec.conf, à la suite vous rajoutez ceci :
conn passthrough-1 left=127.0.0.1 leftsubnet=10.168.1.0/24 rightsubnet=10.168.1.0/24 type=passthrough auto=route
On relance :
vpnB# ipsec restart
Et on constate que le VPN B est de nouveau visible depuis 10.168.1.0/24 et peut lui aussi à nouveau contacter les machines de ce réseau.
Les nouvelles policies :
root@vpn:~/scripts# ip xfrm policy src 0.0.0.0/0 dst 10.168.1.0/24 dir fwd priority 193856 ptype main tmpl src 212.83.183.204 dst 10.168.1.2 proto esp reqid 10 mode tunnel src 0.0.0.0/0 dst 10.168.1.0/24 dir in priority 193856 ptype main tmpl src 212.83.183.204 dst 10.168.1.2 proto esp reqid 10 mode tunnel src 10.168.1.0/24 dst 0.0.0.0/0 dir out priority 193856 ptype main tmpl src 10.168.1.2 dst 212.83.183.204 proto esp reqid 10 mode tunnel src 10.168.1.0/24 dst 10.168.1.0/24 dir fwd priority 87712 ptype main src 10.168.1.0/24 dst 10.168.1.0/24 dir in priority 87712 ptype main src 10.168.1.0/24 dst 10.168.1.0/24 dir out priority 87712 ptype main
II – VM à domicile, sortant par la box
La, on va chercher à faire un peu le contraire de tout à l’heure si je puis dire.
A savoir, avoir une VM à domicile qui, quand elle requête Internet ne sorte pas par la route classique et donc par ma box SFR, mais par la Dedibox.
A – Mise en place
Première constatation que l’on peut faire de nos précédentes bidouilles et elle est logique : si on cherche à savoir comment sort le VPN B sur Internet, il passe par le tunnel et donc un :
vpnB# curl ifconfig.co
nous retourne l’IP Publique de notre réseau Dedibox.
Alors qu’évidement, depuis une autre VM sur le réseau 10.168.1.0/24, vous devriez avoir votre IP FAI.
Du coup, pour faire en sorte qu’une VM utilise le tunnel, y’a plus grand chose à faire.
Ceci dit, cela peut être fait de deux façons et pour l’exemple on va reprendre notre VM test 10.168.1.100
Si on test :
vmtest# curl ifconfig.co
On obtient bien notre IP FAI … pour le moment.
Avant tout, il faudra p’tet préparer le terrain sur le routeur A en pensant au forward et postrouting avec par exemple :
# iptables -t filter -A FORWARD -d 10.168.1.0/24 -j ACCEPT # iptables -t filter -A FORWARD -s 10.168.1.0/24 -j ACCEPT # iptables -t nat -A POSTROUTING -s 10.168.1.0/24 ! -d 10.0.0.0/8 -j SNAT --to IP.DEDIBOX
B – Méthode 1 : Source routing
Cette méthode est celle que j’utilisais quand je faisais également du source routing dans le VPN « de base ».
Pour mémoire : c’est le routeur qui gérait tous les paquets sortant, qu’ils soient pour le net ou pour le tunnel. Par défaut, la route d’un paquet était ainsi :
VM A -> ROUTEUR A -> VPN A -> TUNNEL-> VPN B -> VM B
et pour avoir une symétrie, je faisais du source routing au niveau des VPNs pour forcer le passage par le routeur du réseau avant d’attaquer les VMs :
VM A -> ROUTEUR A -> VPN A -> TUNNEL-> VPN B -> ROUTEUR B -> VM B
Mais j’en suis revenu comme je l’explique dans la partie II.
Toutefois voila à toutes fins utiles la configuration qu’il faudrait :
Sur le routeur B (à domicile), on ajoute une nouvelle route par défaut vers le VPN B dans la table 1 :
routeurB# ip route add default via 10.168.1.2 table 1
Puis on dit que tout ce qui vient de la machine en question (10.168.1.100) vers l’extérieur passe par cette table :
routeurB# ip rule add priority 200 from 10.168.1.100 to 0.0.0.0/0 table 1
Cette regle est cependant un peu « trop », car la VM test ne peut plus contacter le routeur donc, on rajoute :
routeurB# ip rule add priority 190 from 10.168.1.100 to 10.168.1.1 table main
Bon, vous voyez, ca devient vite le bazar et c’est à ce moment dans la phase de test ou je me suis dis que pour une fois, je complexifiais pour par grand chose.
B – Méthode 2 : Changement de gateway
Méthode que j’utilise donc maintenant, qui simplifie grandement le réseau.
Sur la VM test, on va modifier ses routes :
vmtest# ip route del default via 10.168.1.1 vmtest# ip route add default via 10.168.1.2
On remplace le routeur par le VPN, tout bêtement et comme au niveau du VPN, on est pas encore restrictif au niveau FW, ça passe.
On peut tester :
vmtest# curl ifconfig.co
nous donne notre IP Dédibox
III – Conclusion
Et bien voila qui nous permet moult chose. Il nous reste encore quelques optimisations, et c’est ce qu’on va voir dans la quatrième partie.