Voila un probleme sur lequel je m'étais penché il y a quelques mois (une douzaine?) de cela et que j'ai pu résoudre seulement récemment. Avec les 3-Strikes laws votées dans les différents pays[1], les services de VPN anonymes sont de plus a la mode. En particulier avec la sortie de Ipredator, service de VPN anonyme fourni par les créateurs et administrateur de ThePirateBay. Citons aussi UltraVPN et BlackVPN.
Comment ca marche ?
Le principe de ces services et de vous fournir un accès a un serveur OpenVPN ce qui vous permez d'avoir vos communication chiffrée de votre poste au serveur VPN et un anonymat garanti car ils[2] ne stockent pas de log ainsi la relation entre votre IP VPN et votre IP public ne peux-etre faite.
Cependant, lorsque vous faites passer tout votre trafic par un VPN, vous gagnez en latence et perdez en débit du haut de l'ajout d'un intermédiaire et du chiffrement des données. De plus vous vous trouvez avec une IP étrangere ce qui peut-etre genant dans certains cas.
Router seulement certaines applications
Ce que l'on souhaite, c'est pouvoir choisir quelles applications faire
passer par le VPN (navigateur webs...) et quelles applications utilisent la
connexion directe (ssh...). Pour cela on va utiliser une seconde table de
routage, le module owner accompagnée de quelques regles
iptables et les capacités de scripting d'openvpn.
La configuration
La box est une ubuntu, n'importe quelle distribution Linux fera l'affaire, il est possible de faire la même avec pf sur des systèmes *BSD (c'est meme plus facile) mais cela ne sera pas traité ici.
OpenVPN
Il s'agit d'une connexion a un serveur OpenVPN. On reprend le fichier de configuration par le prestataire en y ajoutant quelques lignes :
... # On stock le user/password dans un fichier externe # Login sur la première ligne, password sur la deuxième auth-user-pass <nomvpn>_userpass # On ne récupère pas les routes fournies # Car on ne souhaite pas utiliser le VPN comme default gateway sur la main table de routage route-nopull # On autorise l'exécution de scripts perso script-security 2 # On utilise des scripts a exécuter au démarrage et a l'arrêt de la connexion up /usr/local/vpn/<nomvpn>-up down /usr/local/vpn/<nomvpn>-down
Ne pas oublier de générer le fichier d'authentification, user et password sont fournis par le prestataire :
echo -e "<user>\n<password>" > /etc/openvpn/<nomvpn>_userpass
Routage
La c'est la grosse manipulation qui permet de configurer une table de routage spécifique a ce VPN et de faire passer le trafic d'un gid donné a travers le VPN.
Script de up
ce script sera exécuté par OpenVPN a l'établissement de la connexion avec le serveur distant. Les scripts sont appelés avec les arguments suivants par OpenVPN (voir le man) :
cmd tun_dev tun_mtu link_mtu ifconfig_local_ip ifconfig_remote_ip [ init | restart ]
#!/bin/bash
TUNDEV=$1
TUNIP=$4
# Ici on met le réseau du VPN, pour le connaitre veuillez vous connecter au VPN avec la
# configuration fournie sans le "route-nopull" et faire un ifconfig sur l'interface tun créée
# Faites pareil pour la gateway avec un `route`
VPNNET="10.8.0.0/24"
VPNGW="108.0.1"
EXTIF=eth0
VPNNAME=<nomvpn>
MARK=100 # spécifique a ce VPN, vous choisissez, mettez en un différent par vpn
# On commence par nettoyer au cas ou OpenVPN aurait violemment redémarré dans le passé
echo "- Flushing iptables"
iptables -t mangle -D OUTPUT -o $EXTIF -m owner --uid-owner $VPNNAME -j MARK --set-mark $MARK
iptables -t nat -D POSTROUTING -m mark --mark $MARK -j MASQUERADE
iptables -t nat -D POSTROUTING -m mark --mark $MARK -j SNAT --to-source $TUNIP
echo "- Flushing iproutes"
ip route flush table $VPNNAME
ip rule del fwmark $MARK
echo "- Flushing rp_filter"
for f in all $TUNDEV
do echo 1 > /proc/sys/net/ipv4/conf/$f/rp_filter ; done
echo "+ adding iptables"
# On marque tous les paquets appartenant au group $VPNNAME
iptables -t mangle -A OUTPUT -o $EXTIF -m owner --gid-owner $VPNNAME -j MARK --set-mark $MARK
iptables -t nat -A POSTROUTING -m mark --mark $MARK -j MASQUERADE
# L'IP source des paquets doit etre changée vu que l'on va les faire passer par l'interface VPN tun
iptables -t nat -A POSTROUTING -m mark --mark $MARK -j SNAT --to-source $TUNIP
echo "+ adding iproutes"
echo " + net ${NET} on main table"
ip route add $VPNNET dev $TUNDEV proto kernel scope link src $TUNIP
echo " + net ${NET} on ${VPNNAME} table"
ip route add $VPNNET dev $TUNDEV proto kernel scope link src $TUNIP table ${VPNNAME}
echo " + gw"
ip route add default via $VPNGW dev $TUNDEV table ${VPNNAME}
ip rule add fwmark $MARK table ${VPNNAME}
ip route flush cache table ${VPNNAME}
ip route flush cache
echo "+ adding rp_filter" # ca c'est la commande magique
for f in all $TUNDEV
do echo 0 > /proc/sys/net/ipv4/conf/$f/rp_filter ; done
echo "+ adding dns" # On utilise les DNS de google qui ont une meilleure latence quelque soit la position du serveur VPN
echo "nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 213.186.33.99
" > /etc/resolv.conf
Script de down
#!/bin/bash TUNDEV=$1 TUNIP=$4 VPNNET="10.8.0.0/16" VPNGW="10.8.0.1" EXTIF=eth0 VPNNAME=<nomvpn> MARK=100 # spécifique au vpn, meme que pour le up echo "- Flushing iptables" iptables -t mangle -D OUTPUT -o $EXTIF -m owner --gid-owner $VPNNAME -j MARK --set-mark $MARK iptables -t nat -D POSTROUTING -m mark --mark $MARK -j MASQUERADE iptables -t nat -D POSTROUTING -m mark --mark $MARK -j SNAT --to-source $TUNIP echo "- Flushing iproutes" ip route flush table $VPNNAME ip rule del fwmark $MARK echo "- Flushing rp_filter" for f in all $TUNDEV do echo 1 > /proc/sys/net/ipv4/conf/$f/rp_filter ; done echo "+ flushing dns" echo "nameserve XXX.XXX.XXX.XXX # votre nameserver habituel, au choix " > /etc/resolv.conf
L'utilisation
Ainsi, tout les processus lancés avec le gid <vpnname> se
verront routés a travers le VPN. Pour lancer une telle application, vous pouvez
paramétrer le groupid dans le configuration de votre application, comme pour
tinyproxy par exemple avec Group <vpnname> dans le fichier
tinyproxy.conf.
Ou vous pouvez directement aller sur http://mire.ipadsl.net/ avec links et sudo:
sudo -g <vpnname> links mire.ipadsl.net
Cependant n'oubliez pas de modifier votre fichier sudoers pour
autoriser dante a executer des programmes avec le gid
<vpnname>:
visudo ... dante ALL=(:<vpnname>) NOPASSWD: ALL




