Mindfuck Linux

Depuis que je suis développeur à temps plein je ne fait quasiment plus que de l’admin en dehors du boulot, et comme je n’ai que quelques machines à ma disposition on se retrouve vite dans la situation où tout marche bien et ça devient lassant.

En regardant la conférence Mindfuck NetBSD de sieur iMil j’ai eu moi aussi l’envie de monter un hotspot gratuit et de déléguer la responsabilité de ce qui sortira du réseau à des instance qui sont là pour ça, c’est à dire un VPN suédois pour le moment mais je réfléchis à monter un tunnel avec une assos de la FFDN.

J’ai oublié de préciser que je suis fibré symétrique chez Orange, et monnayant un tunnel gre j’ai à peu près du vrai 100Mbs symétrique, donc avec une vraie antenne je pourrais transporter pas mal de petits lutins dans mes morceaux de tuyaux. Mais c’est encore à l’état de draft pour le moment.

Donc voilà le sac de nœud que j’ai mis en place et qui tourne à peu près bien:

MINDFUCK Linux

On voit qu’il y a plusieurs chemins pour accèder au grand ternet et plusieurs routeurs de sortie:

  • Sur mon RB750GL avec OpenWrt, une fibre orange (pppoe).
  • Un dédié chez OVH, c’est un kimsufi 2G le moins cher, avec un tunnel GRE (gtun0) et un tunnel OpenVPN (vpn0) par dessus le GRE depuis chez moi.
  • Un vpn Suèdois connecté depuis le dédié (vpn1)

Ensuite il y a plusieurs sources:

  • Des machines chez moi dans mon LAN que nous appellerons LAN (192.168.31.0/24)
  • Des inconnus sur mon Wifi ouvert: LAN_WIFI (192.168.33.0/24)
  • Des machines virtuelles sur mon dédié: LAN_DEDIE (192.168.42.0/24)
  • Des machines à moi quand je ne suis pas chez moi (boulot, hotel etc): ROAMING (192.168.94.0/24)
  • Internet: NET
  • Mon tunnel gre pose un réseau 192.168.254.0/30 (192.168.254.1 sur le dédié et 192.168.254.2 chez moi).

L’idée est qu’à partir du couple (source, destination) d’altérer le routage sur mes deux routeurs pour que les paquets empruntent les bons chemins (pas forcément les plus rapide d’ailleurs).

Voilà à peu près mes contraintes suivant le couple (source, destination).

  • La Fibre orange est bridée par connexion tcp/udp, donc tout ce qui sort de chez moi (LAN, LAN_WIFI) passe au moins par le tunnel GRE (nettement plus rapide, à 4h du mat c’est quasiment du x10)
  • Contrainte 1: LAN <=> NET: par le tunnel GRE et sortie sur le dédié (rapide, mais pas chiffré).
  • Contrainte 2: LAN <=> LAN_DEDIE: par le tunnel OpenVPN sur le tunnel GRE (un chouilla moins rapide, mais chiffé).
  • Contrainte 3: WIFI <=> NET: par le tunnel OpenVPN sur le tunnel GRE puis par le tunnel OpenVPN et sortie en Suède (lent, chiffré, sans logs).
  • Contrainte 4: ROAMING <=> {NET, LAN_DEDIE}: Par le dédié en OpenVPN
  • Contrainte 5: ROAMING <=> LAN: Par le dédié en OpenVPN puis jusque chez moi en OpenVPN par dessus le GRE.

Mes deux routeurs sont sur Linux donc j’ai simplement fait du “source routing”. En gros il y a plusieurs tables de routages, avec en particulier des routes default différentes, et avec iproute2 on crée des rules qui matchent la source, la destination ou les deux et on les affecte la rule à une table de routage. Pour aller plus loin, matcher des ports ou même n’importe quoi qui se matche dans un paquet, on peut utiliser la cible MARK d’iptables et matcher les paquets marqués avec iproute2.

Je vous conseille si vous le pouvez, d’utiliser un système BSD avec pf qui intégre tout ça de manière beaucoup plus simple. Mais si aimez bien le claquement des fouets comme moi, let’s go avec iproute2.

Contrainte 1: LAN <=> NET: par le tunnel GRE et sortie sur le dédié

# Création d'une table de routage LAN sur mon routeur chez moi:
echo "200  LAN" >> /etc/iproute2/rt_tables
# Route par default via le tunnel GRE
ip route add default via 192.168.254.1 dev gtun0 table LAN
# Si on ne rajoute pas la route du lan on coupe l'accès entres les machines du LAN (oui c'est un peu pourri)
ip route add 192.168.31.0/24 dev br-lan table LAN
# Si la source est le LAN, on utilise la table de routage LAN
ip rule add from 192.168.31.0/24 table LAN

# Coté dédié il faut rajouter une route de retour
ip route add 192.168.31.0/24 via 192.168.254.2 dev gtun0
# Puis il faut FORWARD et NATPT le LAN en sortie sur le dédié
iptables -A FORWARD -i gtun0 -s 192.168.31.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.31.0/24 -o eth0 -j SNAT --to-source 176.31.121.189

Contrainte 2: LAN <=> LAN_DEDIE: par le tunnel OpenVPN sur le tunnel GRE

# Sur le routeur chez moi, j'ai rajouté le réseau OpenVPN du dédié
ip route add 192.168.94.0/24 dev vpn0 table LAN
# Puis une route vers le LAN_DEDIE qui passe par le vpn), 192.168.94.1 = le dédié
ip route add 192.168.42.0/24 via 192.168.94.1 dev vpn0 table LAN


# À ce moment là on a l'impression que ça marche, ERREUR: seuls les paquets
# LAN -> LAN_DEDIE passent par le vpn, les paquets LAN_DEDIE -> LAN passent directement sur le GRE !!
# On va donc créer une table de routage VPN sur le dédié et router LAN_DEDIE -> LAN par
# 192.168.94.2 (le routeur chez moi)
echo "200 VPN" >> /etc/iproute2/rt_tables
ip route add 192.168.31.0/24 via 192.168.94.2 dev vpn0 table VPN
ip rule add from 192.168.42.0/24 to 192.168.31.0/24 table VPN

Contrainte 3: WIFI <=> NET: par le tunnel OpenVPN sur le tunnel GRE puis par le tunnel OpenVPN et sortie en Suède

# Depuis chez moi je route WIFI vers 192.168.94.1 (dédié OpenVPN), il nous faut nouvelle table de routage
echo "201 VPN" >> /etc/iproute2/rt_tables
ip route add default via 192.168.94.1 dev vpn0 table VPN


# Sur le dédié je crée une nouvelle table de routage VPNSE avec comme route par default le
# tunnel OpenVPN vers la Suède et on oublie pas la route de retour
echo "201 VPNSE" >> /etc/iproute2/rt_tables
ip route add default dev vpn1 table VPNSE
ip route add 192.168.33.0/24 via 192.168.94.2 dev vpn0
# Toujours sur le dédié on fait du NATPT pour WIFI
iptables -A FORWARD -i vpn0 -s 192.168.33.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.33.0/24 -o vpn1 -j MASQUERADE

Contrainte 4: ROAMING <=> {NET, LAN_DEDIE}: Par le dédié en OpenVPN

# Rien de particulier ici, si ce n'est le NATPT
iptables -A FORWARD -i vpn0 -s 192.168.94.0/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.94.0/24 -o eth0 -j SNAT --to-source 176.31.121.189

Contrainte 5: ROAMING <=> LAN: Par le dédié en OpenVPN puis jusque chez moi en OpenVPN par dessus le GRE.

Vu qu’on est en OpenVPN bridgé, la route vers le LAN est directement sur l’IP de mon routeur chez moi (192.168.94.2) Donc ça marche tout seul (ouf) :)

Conclusion

J’espère que j’ai donné assez d’informations pour passer votre prochain hiver en mode Mindfuck, et si ça ne suffit pas:

  • Rajouter un proxy HTTP pour le WIFI
  • Authentifier les utilisateurs sur le WIFI pour les faire passer par d’autres routes que la Suède.
  • Faire en sorte que ça ne tombe pas en panne, si une interface disparait (gtun0, vpn0, vpn1), toutes les routes associés disparaissent, donc il faut faire des script up/down pour OpenVPN, pour le GRE etc.
  • Gérer la sécurité (par exemple en wifi on ne devrait pas avoir accès aux différents LANs sauf si on est authentifié).
  • Faire une extension sur votre $BROWSER pour choisir le point de sortie sur internet.