28 janvier 2021

Tuto Strongswan, partie III : Liaison Internet – VPN

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.

 

 

Laisser un commentaire

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