Pour le premier article de ce blog nous allons voir comment mettre en place un VPN avec OpenVPN et comment router non pas tout votre trafic vers ce tunnel VPN (je suppose que vous savez déjà le faire) mais uniquement une partie que vous pourrez choisir.
Nous allons pour cela mettre en place une politique de routage permettant qu’un certain utilisateur (on va l’appeler « vpn » pour faire original) ait tout son traffic rerouté vers le VPN.
Tout d’abord installez OpenVPN et resolvconf :
apt-get install openvpn resolvconf
Récupérez ensuite sur le site de votre provider VPN les fichiers de configuration d’OpenVPN. Placez les dans le dossier
/etc/openvpn/
Dans le fichier votrevpn.ovpn, assurez vous d’avoir les lignes suivantes (et surtout celle en rouge qui permet de ne pas modifier notre routage des paquets !) :
client
dev tun
resolv-retry infinite
persist-key
persist-tun
daemon openvpn
route-nopull
Toujours dans le dossier /etc/openvpn/, créez le fichier update-resolv-conf et rendez le executable :
cd /etc/openvpn/
touch update-resolv-conf
chmod +x update-resolv-conf
Editez le fichier comme suit :
#!/bin/bash
#
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood <jdthood@yahoo.co.uk>
# and Chris Hanson
# Licensed under the GNU GPL. See /usr/share/common-licenses/GPL.
#
# 05/2006 chlauber@bnc.ch
#
# Example envs set from openvpn:
# foreign_option_1='dhcp-option DNS 193.43.27.132'
# foreign_option_2='dhcp-option DNS 193.43.27.133'
# foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
[ -x /sbin/resolvconf ] || exit 0
case $script_type in
up)
for optionname in ${!foreign_option_*} ; do
option="${!optionname}"
echo $option
part1=$(echo "$option" | cut -d " " -f 1)
if [ "$part1" == "dhcp-option" ] ; then
part2=$(echo "$option" | cut -d " " -f 2)
part3=$(echo "$option" | cut -d " " -f 3)
if [ "$part2" == "DNS" ] ; then
IF_DNS_NAMESERVERS="$IF_DNS_NAMESERVERS $part3"
fi
if [ "$part2" == "DOMAIN" ] ; then
IF_DNS_SEARCH="$IF_DNS_SEARCH $part3"
fi
fi
done
R=""
for SS in $IF_DNS_SEARCH ; do
R="${R}search $SS
"
done
for NS in $IF_DNS_NAMESERVERS ; do
R="${R}nameserver $NS
"
done
echo -n "$R" | /sbin/resolvconf -a "${dev}.inet"
;;
down)
/sbin/resolvconf -d "${dev}.inet"
;;
esac
Editez le fichier /etc/iproute2/rt_tables :
echo "200 vpn" >> /etc/iproute2/rt_tables
Créez l’utilisateur vpn :
adduser vpn
Revenez dans le dossier /etc/openvpn/, créez le fichier « firewall.sh » et rendez le executable. Editez le comme suit :
#! /bin/bash
# L'interface du tunnel
export INTERFACE="tun0"
# L'interface locale (RJ45)
export NETIF="eth0"
# L'interface dite de loopback
export LOOPBACK="lo"
# L'utilisateur vpn
export VPNUSER="vpn"
# Tous les IP du réseau local
export LANIP="192.168.0.0/24"
# On vide les tables
iptables -F
iptables -F -t nat
iptables -F -t mangle
iptables -F -t filter
#
# CHAINES OUTPUT
#
# On marque les paquets que l'on va rerouter vers le VPN
# Tous les paquets provenants de l'utilisateur vpn sont routés vers le VPN
iptables -t mangle -A OUTPUT -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
# Les paquets sortants par le ports xxx proviennent de l'utilisateur vpn mais ils
# ne seront pas routés vers le VPN
iptables -t mangle -A OUTPUT -p tcp --sport xxx -j MARK --set-mark 0x2
# On rejette les connnections avec une IP de réseau local sur le VPN
iptables -A OUTPUT ! --src $LANIP -o $NETIF -j REJECT
# On autorise l access a lo et a la connexion classique pour l utilisateur $VPNUSER
iptables -A OUTPUT -o $LOOPBACK -m owner --uid-owner $VPNUSER -j ACCEPT
iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT
#
# CHAINES POSTROUTING
#
# Tout les paquets sur $INTERFACE doivent être flagués MASQUERADE
iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE
#
# CHAINES INPUT
#
# On autorise les réponses
iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT
# On autorise via la connexion classique
# SSH
iptables -A INPUT -i $NETIF -p tcp --dport 22 -j ACCEPT
# HTTP
iptables -A INPUT -i $NETIF -p tcp --dport 80 -j ACCEPT
# HTTPS
iptables -A INPUT -i $NETIF -p tcp --dport 443 -j ACCEPT
# On bloque tout le reste qui arrive sur le VPN
iptables -A INPUT -i $INTERFACE -j REJECT
Toujours dans le dossier /etc/openvpn/, créez le fichier « up.sh » et rendez le executable. Editez le comme suit :
#!/bin/sh
sh /etc/openvpn/firewall.sh
VPNIF="tun0"
VPNUSER="vpn"
GATEWAYIP=`ifconfig $VPNIF | egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' | egrep -v '255|(127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})' | tail -n1`
ip rule add from all fwmark 0x1 lookup $VPNUSER
ip route replace default via $GATEWAYIP table $VPNUSER
ip route append default via 127.0.0.1 dev lo table $VPNUSER
ip route flush cache
/etc/openvpn/update-resolv-conf
On arrive à la fin (oui c’est long, courage) !!
On va créer un script se lançant au démarrage et permettant de nous connecter à notre VPN.
Allez dans le dossier /etc/init.d/, créez un fichier vpn.sh et rendez le exécutable. Editez le comme suit :
#!/bin/sh
## Script de lancement du VPN ##
### BEGIN INIT INFO
# Provides: inso_startVPN.sh
# Required-Start: $remote_fs $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: script perso VPN
# Description: script de lancement du VPN
#
### END INIT INFO
openvpn --config /etc/openvpn/votrevpn.ovpn --script-security 2 --up /etc/openvpn/up.sh
Et ajoutez le au démarrage :
update-rc.d vpn.sh defaults
On peut redémarrer, on va enfin tester tout ça !
reboot
Au redémarrage, si tout s’est bien passé vous devriez avoir une nouvelle interface (tun0, on peut lister les interfaces avec la commande « ifconfig »).
Tous les paquets provenant de l’utilisateur vpn sont routés vers cette interface.
Testons !
ins0@mars:~ curl ifconfig.co
82.68.103.132
ins0@mars:~ su vpn -c "curl ifconfig.co"
Password:
35.49.113.82
NB: les adresses IP données dans le test final sont fictives ^^