SwordArMor

Mise en place d’un tunnel L2TP chiffré avec IPsec autentifié avec radius

Cette infrastructure a été mise en œuvre au sein de grifon afin de fournir un VPN le plus proche possible de la collecte ADSL.

Côté serveur

Le radius

Le radius sert à authentifier les utilisateurs et à donner les autorisations qui leur sont relatives (comme par exemple, quelle adresse IP untel a le droit d’utiliser).

Pour que le serveur radius fonctionne, il faut commencer par changer le mot de passe dans /etc/freeradius/clients.conf (directive secret). Ensuite, les utilisateurs s’ajoutent dans /etc/freeradius/users selon le canevas

monuser Cleartext-Password := "monmotdepasse"
	Service-Type = Framed-User,
	Framed-Protocol = PPP,
	Framed-IP-Address = $ipv4,
	Framed-IP-Netmask = 255.255.255.255,
	Framed-IPv6-Prefix = $ipv6_interco,
	Framed-IPv6-Address = $ipv6_interco::1,
	Framed-Interface-Id = 0:0:0:$3,
	Delegated-IPv6-Prefix = $ipv6_deleg
Je vous conseille de vider ce fichier avant, il y a pas mal d’exemples qui ne sont pas commentés et qui peuvent perturber les utilisateurs que vous créerez.
Ensuite, il faut aussi mettre le mot de passe dans /etc/radiusclient/servers précédé de localhost car le client et le serveur tournent sur la même machine.

Le L2TP

Nous avons choisi l’implémentation openl2tp car tout le travail est fait au niveau du kernel. Ça évite les allers/retours entre l’espace utilisateur et le noyau.
Il n’est pas dans les dépôts de debian, il faut donc télécharger le .deb (version 64-bit, version 32-bit) directement sur leur site, puis l’installer avec dpkg.


root@judicael:~# wget ftp://ftp.openl2tp.org/releases/openl2tp-1.8/debian-squeeze/openl2tp_1.8-1_amd64.deb
root@judicael:~# dpkg -i openl2tp_1.8-1_amd64.deb
root@judicael:~# apt-get -f install # pour installer les dépendances

Il faut maintenant configurer openl2tpd.
Il faut savoir que les tunnels L2TP se montent dans des sessions L2TP. Il peut y avoir plusieurs tunnels par session, même si ce n’est pas le cas le plus répendu.
C’est dans ce fichier que nous disons quel est le port UDP depuis lequel nous allons répondre, où aller authentifier les clients, ainsi que notre endpoint IPv4. L’IPv6 se configure directement dans ppp.
Celà nous donne donc un fichier de conf du genre de

# system

# peer profiles

# tunnel profiles
tunnel profile modify profile_name=default \
       our_udp_port=1701 \

# session profiles

# ppp profiles
ppp profile modify profile_name=default \
       use_radius=yes \
       radius_hint=/etc/radiusclient/radiusclient.conf \
       auth_pap=no \
       auth_mschapv1=no \
       auth_mschapv2=no \
       auth_eap=no \
       auth_none=no \
       local_ipaddr=89.234.186.4 \

# locally created tunnels and sessions

Le PPP

Nous voulons de l’IPv6, il faut donc ajouter l’option +ipv6 à la fin de /etc/ppp/options. Ceci va activer le support d’IPv6 dans PPP (vous aurez une fe80 sur vos interfaces ppp) mais ce n’est pas pour autant que tout va fonctionner. Il faut ajouter des scripts dans /etc/ppp/ipv6-up.d/ et dans /etc/ppp/ipv6-down.d/, et ne pas oublier de les rendre exécutables.
L’IPv6 fonctionne avec du SLAAC, nous installons radvd afin d’envoyer des RA sur les interfaces ppp.
Le PPP remonte les informations qu’il obtient du radius et les place dans /run/radattr.$PPP_IFACE, nous allons parser ce fichier afin de configurer le radvd en conséquence.
Les scripts que nous utilisons sont les suivants :


root@judicael:~# cat /etc/ppp/ipv6-up.d/vpn 
#!/bin/sh

prefix_interco=$(awk '$1 == "Framed-IPv6-Prefix" { print $2 }' /run/radattr.$PPP_IFACE)
prefix_deleg=$(awk '$1 == "Delegated-IPv6-Prefix" { print $2 }' /run/radattr.$PPP_IFACE)

ip -6 route add $prefix_interco dev $PPP_IFACE

echo "
interface $PPP_IFACE
{
	AdvSendAdvert on;
	IgnoreIfMissing on;

	prefix $prefix_interco {};
};
# $PPP_LOCAL $PPP_REMOTE
" > /run/vpn/radvd-user.${PPP_IFACE}.conf
echo "interface lo {};" > /run/vpn/radvd-vpn.conf
cat /run/vpn/radvd-user.*.conf >> /run/vpn/radvd-vpn.conf

kill -HUP $(cat /run/radvd/radvd.pid)

ip -6 route add $prefix_deleg via $PPP_REMOTE dev $PPP_IFACE
root@judicael:~# cat /etc/ppp/ipv6-down.d/vpn 
#!/bin/sh

rm -f /run/vpn/radvd-user.${PPP_IFACE}.conf
echo "interface lo {};" > /run/vpn/radvd-vpn.conf
cat /run/vpn/radvd-user.*.conf >> /run/vpn/radvd-vpn.conf
kill -HUP $(/run/radvd/radvd.pid)

ip -6 route del $prefix dev $PPP_IFACE
Il faut aussi vérifier que les attributs sont des mêmes types dans /etc/radiusclient/dictionary et /usr/share/freeradius/dictionary*, le second faisant foi.

L’IPsec

Si vous trouviez ça difficile jusqu’ici, ça va devenir encore pire :p
Avant de continuer, assurez vous que le openl2tp et ppp fonctionnent, l’IPsec ne va pas les faire marcher miraculeusement, il ne sert qu’à chiffrer ce qui passe dans le tunnel L2TP.

Pour l’IPsec, nous avons choisi strongswan. La version dans les dépôts de wheezy est très vielle, je vous conseille d’utiliser la version des backports. Il se base sur le modèle X509 pour chiffrer et authentifier.

Nous devons commencer par corriger les certificats. On a besoin d’un certificat d’une AC quelconque. On place le certificat de l’autorité dans un fichier .pem dans le dossier /etc/ipsec.d/cacerts. On place notre certificat obtenu dans /etc/ipsec.d/aacerts et dans /etc/ipsec.d/certs. On place la clef privée dans /etc/ipsec.d/private.
Il faut dire quelle est la clé privée utilisé pour chiffrer les connexion. On spécifie cette option dans /etc/ipsec.secrets avec : RSA "vpn.grifon.fr.key" (les deux-points sont inclus). Les mots de passe seront à mettre à la suite dans ce fichier.
Une fois ceci fait, il faut préparer notre strongswan à recevoir des connexions depuis les clients VPN, on met donc ceci dans /etc/ipsec.conf :


conn %default
	ikelifetime=60m
	keylife=20m
	rekeymargin=3m
	keyingtries=1
	keyexchange=ikev2

conn client
	left=%any
	leftid=*@vpn.grifon.fr
	leftauth=eap-ttls
	leftfirewall=yes
	right=vpn.grifon.fr
	rightid="C=FR, ST=Bretagne, L=Cesson Sevigne, O=GRIFON, OU=VPN, CN=vpn.grifon.fr"
	rightauth=eap
	rightsendcert=never
	type=transport
	auto=add
	mobike=yes

include /var/lib/strongswan/ipsec.conf.inc

Côté client

L’IPsec

Nous commençons par mettre en place l’IPsec afin d’éviter que les identifiants se baladent en clair sur Internet.

Il faut également installer strongswan, de la même manière que pour le serveur. Par contre la configuration est différente :


config setup
       plutostart=no

conn %default
       ikelifetime=60m
       keylife=20m
       rekeymargin=3m
       keyingtries=1
       keyexchange=ikev2

conn grifon
       leftid=$utilisateur@vpn.grifon.fr
       leftfirewall=yes
       leftauth=eap-ttls
       right=vpn.grifon.fr #ici l'IPv4 de la machine de grifon
       rightid="C=FR, ST=Bretagne, L=Cesson Sevigne, O=GRIFON, OU=VPN, CN=vpn.grifon.fr"
       rightsendcert=never
       rightauth=eap
       type=transport
       auto=start
       closeaction=restart
Le mot de passe doit également être mis dans /etc/ipsec.secrets sous la forme $utilisateur@vpn.grifon.fr : EAP "motdepasseutilisateur".

Le L2TP

Tout comme pour l’IPsec, le programme est le même, seule la configuration diffère.

Dans /etc/openl2tp.conf :

# system

# peer profiles

# tunnel profiles

# session profiles

# ppp profiles
ppp profile create profile_name=grifon
ppp profile modify profile_name=grifon \
       auth_chap=yes \


# locally created tunnels and sessions
tunnel create tunnel_name=l2tp17507 dest_ipaddr=89.234.186.3 \

session create tunnel_name=l2tp17507 \
       ppp_profile_name=grifon \
       user_name=monuser \
       user_password=monmotdepasse
Il faut également utiliser des scripts ppp afin d’avoir de l’IPv6 et de faire passer tout les flux (v4 et v6) au travers du VPN.
alarig@debian-backports:~$ cat /etc/ppp/ip-up.d/grifon 
#!/bin/sh

defaultroute="$(ip route list | grep default | cut -d ' ' -f 3)"

ip route add 89.234.186.3/32 via $defaultroute

ip route add 0.0.0.0/1 dev ppp0
ip route add 128.0.0.0/1 dev ppp0

ip route add 10.0.0.0/8 via $defaultroute
ip route add 172.16.0.0/12 via $defaultroute
ip route add 192.168.0.0/16 via $defaultroute
alarig@debian-backports:~$ cat /etc/ppp/ip-down.d/grifon 
#!/bin/sh

ip route del 0.0.0.0/1 dev ppp0
ip route del 128.0.0.0/1 dev ppp0
alarig@debian-backports:~$ cat /etc/ppp/ipv6-up.d/grifon 
#!/bin/sh

prefix="$(ip -6 addr show ppp0 | grep global | cut -d ' ' -f 6 | cut -d ':' -f 1,2,3,4)"

ip -6 route add 2000::/3 dev ppp0
ip -6 addr add $prefix::1/64 dev ppp0
alarig@debian-backports:~$ cat /etc/ppp/ipv6-down.d/grifon 
#!/bin/sh

ip -6 route del 2000::/3 dev ppp0
Notons qu’il est également possible d’utiliser une autre table de routage pour que le VPN ne soit utilisé que si l’on veut joindre l’IP du VPN et que tout le reste du trafic passe par la route par défaut. Il faut alors utiliser les commandes suivantes :

echo "200 grifon" >> /etc/iproute2/rt_tables
ip route add default via 89.234.186.4 table grifon
ip route add 89.234.186.0 dev ppp0 src $votreipgrifon table grifon
ip rule add from $votreipgrifon table grifon
Pour finir, on charge le fichier de conf de openl2tp et ça devrait marcher.
root@ # service ipsec restart
root@ # service openl2tp restart
root@ # l2tpconfig
l2tp>config restore file=/etc/openl2tp.conf
l2tp>exit