Blog

Monter un serveur L2TP/IPsec sur debian

Écrit le 03 05 2013 par Kévin MET _

On va voir comment mettre en place un serveur L2TP/IPsec sur une debian Squeeze en utilisant Openswan (IPsec) et Xl2tpd (l2tp). Ensuite, nous allons voir comment y connecter un client Linux. Et enfin nous allons voir comment superviser avec des scripts Bash notre VPN. En fait je vais faire un deuxième article qui expliquera la partie client et supervision car la partie installation du serveur est déjà trop longue. Cet exemple peut-être utiliser pour monter un lien VPN entre deux serveurs. Dans mon cas, il me sert à maintenir un lien entre le LAN à mon domicile et un de mes serveurs chez OVH. Je donne cet exemple car il arrive que la connexion tombe ou ne soit pas très stable et c'est pour cela que les scripts qui maintiennent la connexion peuvent s'avérer très utile. Le VPN sert également à de nombreux ordinateurs et mobiles, il doit donc être compatible avec tous les OS et tous les mobiles.

Un peu de théorie sur IPsec

Avant de commencer, nous allons faire un tout petit peu de théorie sur IPsec. IPsec permet de chiffrer les données et de les authentifier. Il peut fonctionner en utilisant une clé partagée, c'est ce que nous allons utiliser, ou en utilisant des certificats. Il peut s'utiliser de deux façons :

  • En mode transport, c'est ce que nous utiliserons, IPsec va uniquement chiffrer la partie donnée des paquets. Cela va donc permettre de conserver le routage des paquets. Dans notre cas nous allons créer un tunnel entre le port 1701 (port par défaut de xl2tpd et un port au hasard). Ainsi même si quelqu'un sniffe notre réseau il ne verra que les entêtes des paquets mais ne pourra pas en lire le contenu.
  • En mode tunnel, Ipsec va chiffrer et encapsuler le paquet dans un autre paquet. Tous le transit est chiffré. IPsec peut donc a lui tout seul servir de VPN. Le seule avantage d'utiliser L2TP via IPsec est qu'il est compatible avec tous les OS et tous les téléphones disponibles. Si votre VPN ne doit servir qu'entre deux serveurs, n'hésitez pas une seconde, utilisez IPsec en mode tunnel uniquement

Installation et configuration d'OpenSwan

Dans notre exemple on va utiliser l'adresse 66.66.66.66 pour le serveur.

Nous allons commencer par l'installation d'OpenSwan qui va gérer la partie IPsec du VPN. Pour cela nous allons compiler la dernière version qui semble mieux fonctionner avec les différents appareils que j'ai pu tester (ceci reste à confirmer).


wget --no-check-certificate https://s3-ap-northeast-1.amazonaws.com/openswanjp/openswan-2.6.38.tar.gz
tar xvzf openswan-2.6.38.tar.gz
cd openswan-2.6.38/
make programs
make install

Durant la compilation (make programs) vous pourriez rencontrer les erreurs suivantes :


In file included from /root/openswan-2.6.38/include/certs.h:24,
                 from /root/openswan-2.6.38/lib/libopenswan/id.c:39:
/root/openswan-2.6.38/include/secrets.h:20:41: error: gmp.h: No such file or directory
In file included from /root/openswan-2.6.38/include/certs.h:24,
                 from /root/openswan-2.6.38/lib/libopenswan/id.c:39:
/root/openswan-2.6.38/include/secrets.h:43: error: expected specifier-qualifier-list before 'MP_INT'
/root/openswan-2.6.38/include/secrets.h:54: error: expected specifier-qualifier-list before 'MP_INT'
make[3]: *** [id.o] Error 1
make[3]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib/libopenswan'
make[2]: *** [programs] Error 1
make[2]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib'
make[1]: *** [programs] Error 1
make[1]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64'
make: *** [programs] Error 2

Dans ce cas il faut installer la lib gmp de dev :


aptitude install libgmp3-dev

Dans le cas d'un problème de bison 😃


/bin/bash: bison: command not found
make[3]: *** [parser.tab.h] Error 127
make[3]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib/libipsecconf'
make[2]: *** [programs] Error 1
make[2]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib'
make[1]: *** [programs] Error 1
make[1]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64'
make: *** [programs] Error 2

Il suffit d'installer bison :


aptitude install bison

Et dans le cas ou c'est flex qui fait défaut


/bin/bash: flex: command not found
make[3]: *** [lex.yy.c] Error 127
make[3]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib/libipsecconf'
make[2]: *** [programs] Error 1
make[2]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64/lib'
make[1]: *** [programs] Error 1
make[1]: Leaving directory `/root/openswan-2.6.38/OBJ.linux.x86_64'
make: *** [programs] Error 2

Il suffit de l'installer :


aptitude install flex

Nous pouvons passer à la configuration d'OpenSwan. La configuration va tenir sur deux fichiers :

  • /etc/ipsec.conf qui va contenir la configuration d'OpenSwan. Attention ce fichier utilise des tabulations pour différencier les catégories. Il faut impérativement utiliser des tabulations sous peine de ne pas pouvoir faire fonctionner IPsec.
  • /etc/ipsec.secrets qui va simplement contenir la clé pré-partagé qui permettra de chiffrer les données transmis via le VPN. L'échange de la clé se fera d'ailleurs via le port 500 en udp tandis ce que les données transiteront sur le port 4500 toujours en udp.

Je balance la conf et ensuite j'explique :


# /etc/ipsec.conf - Openswan IPsec configuration file
# Manual:     ipsec.conf.5
version 2.0     # conforms to second version of ipsec.conf specification
config setup
	nat_traversal=yes
	virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,!%v4:192.168.1.0/24
	oe=off
	protostack=netkey
	plutoopts="--interface=eth0"
# Add connections here
conn L2TP-PSK-NAT
	rightsubnet=vhost:%priv
	also=L2TP-PSK-noNAT
conn L2TP-PSK-noNAT
	authby=secret
	pfs=no
	auto=add
	keyingtries=3
	rekey=no
	ikelifetime=8h
	keylife=1h
	type=transport
	left=66.66.66.66
	leftprotoport=17/1701
	leftnexthop=%defaultroute
	right=%any
	rightprotoport=17/%any
	# Evite un bug a la déconnexion empêchant la reconnexion avec OSX et iOs
	dpddelay=15
	dpdtimeout=30
	dpdaction=clear

ATTENTION : je me répète mais faites attention à ces putains de tabulations !!! Elles sont absolument vitales pour qu'OpenSwan fonctionne. Vous êtes doublement prévenu 😉

Je vais passer en revue les options les plus importantes. On commence par nat_traversal qui va permettre d'utiliser l'encapsulation NAT-T. Mais qu'est ce que c'est que ça me direz vous ? Et bien c'est ce qui va permettre à vos paquets traversant un NAT et donc ayant une entête IP modifiée par votre routeur modifiant le hash AH généré par OpenSwan de ne pas se faire jeter. virtual_private définit les réseaux privés qui peuvent être autoiser à se connecter au serveur VPN via un NAT. Si votre serveur VPN va servir à donner accès au sous-réseau 192.168.66.0/24 il faudrait donc utiliser :


virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,!%v4:192.168.66.0/24

On va finir avec plutoopts pour la conf globale qui permet de spécifier sur quelle interface vous voulez que ipsec écoute.

Ensuite on va commencer par conn L2TP-PSK-noNAT et finir avec conn L2TP-PSK-NAT. Il faut savoir que pour OpenSwan left = nous et right = l'autre. Il faut donc renseigner l'adresse ip de notre serveur dans left. Pour right on peut mettre %any car on veut autoriser les gens à se connecter depuis n'importe quelle adresse IP. Pour leftprotoport on indique 17/1701 ce qui revient à dire qu'on autorise le traffic udp sur le port 1701 (ce qui va nous servir pour l2tp). authby=secret signifie que l'on va utiliser une clé pré-partagée pour le chiffrement des données. Pour le reste, je vous laisse faire un man ipsec.conf.

On va ensuite s'occuper de ipsec.secrets


# RCSID $Id: ipsec.secrets.proto,v 1.3.6.1 2005/09/28 13:59:14 paul Exp $
# This file holds shared secrets or RSA private keys for inter-Pluto
# authentication.  See ipsec_pluto(8) manpage, and HTML documentation.

# RSA private key for this host, authenticating it to any other host
# which knows the public part.  Suitable public keys, for ipsec.conf, DNS,
# or configuration of other implementations, can be extracted conveniently
# with "ipsec showhostkey".

# this file is managed with debconf and will contain the automatically created RSA keys
66.66.66.66 %any: PSK "monpasswordrandomquitue"

Il suffit de changer l'adresse ip de votre serveur et d'indiquer un mot de passe. Le %any signifie que cette clé pourra être utilisée par n'importe quelle adresse IP.

On peut démarrer IPsec :


/etc/init.d/openswan start

Il faut maintenant vérifier que IPsec peut fonctionner correctement. Pour cela on utilise cette commande :


ipsec verify

Dans mon cas j'obtiens ce résultat :


Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                             	[OK]
Linux Openswan U2.6.34/K2.6.32-5-xen-amd64 (netkey)
Checking for IPsec support in kernel                        	[OK]
 SAref kernel support                                       	[N/A]
 NETKEY:  Testing XFRM related proc values                  	[FAILED]

  Please disable /proc/sys/net/ipv4/conf/*/send_redirects
  or NETKEY will cause the sending of bogus ICMP redirects!

	[FAILED]

  Please disable /proc/sys/net/ipv4/conf/*/accept_redirects
  or NETKEY will accept bogus ICMP redirects!

	[OK]
Checking that pluto is running                              	[OK]
 Pluto listening for IKE on udp 500                         	[OK]
 Pluto listening for NAT-T on udp 4500                      	[OK]
Two or more interfaces found, checking IP forwarding        	[OK]
Checking NAT and MASQUERADEing                              
Checking for 'ip' command                                   	[OK]
Checking /bin/sh is not /bin/dash                           	[OK]
Checking for 'iptables' command                             	[OK]
Opportunistic Encryption Support                            	[DISABLED]

Pour résoudre ce problème, il faut simplement faire un :


for each in /proc/sys/net/ipv4/conf/*; do echo 0 > $each/accept_redirects && echo 0 > $each/send_redirects; done

Maintenant c'est tout bon :


Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                             	[OK]
Linux Openswan U2.6.34/K2.6.32-5-xen-amd64 (netkey)
Checking for IPsec support in kernel                        	[OK]
 SAref kernel support                                       	[N/A]
 NETKEY:  Testing XFRM related proc values                  	[OK]
	[OK]
	[OK]
Checking that pluto is running                              	[OK]
 Pluto listening for IKE on udp 500                         	[OK]
 Pluto listening for NAT-T on udp 4500                      	[OK]
Two or more interfaces found, checking IP forwarding        	[OK]
Checking NAT and MASQUERADEing                              
Checking for 'ip' command                                   	[OK]
Checking /bin/sh is not /bin/dash                           	[OK]
Checking for 'iptables' command                             	[OK]
Opportunistic Encryption Support                            	[DISABLED]

C'est fini pour la partie Openswan (mais vous n'êtes pas encore au boute de votre peine 😐)

Installation et configuration de Xl2tpd

Pour l'installation de xl2tpd on va simplement utiliser notre bon vieux pote aptitude :


aptitude install xl2tpd

On va ensuite le configurer via le fichier /etc/xl2tpd/xl2tpd.conf. Comme d'habitude je balance la conf et j'explique après :


[global]
listen-addr = 66.66.66.66
[lns default]
ip range = 10.0.1.1-10.0.1.30
local ip = 10.0.1.200
length bit = yes
require chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd

C'est assez limpide comme configuration. On écoute sur notre adresse publique 66.66.66.66. On va utiliser le subnet 10.0.1.0/27 pour les adresses de nos clients VPN. Cela veut dire que l'on va pouvoir utiliser de l'adresse 10.0.1.1 à l'adresse 10.0.1.30. On indique l'adresse de l'interface ppp locale (10.0.1.200) qui doit être en dehors du subnet choisit précédemment. Et on indique que les options ppp sont définit dans le fichier /etc/ppp/options.xl2tpd. Pour le reste, il y a l'ami man 😉

On va donc voir la tête de notre fichier /etc/ppp/options.xl2tpd :


require-mschap-v2
ms-dns 10.0.1.200
asyncmap 0
auth
crtscts
mtu 1400
mru 1400
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

Dans cette conf on indique que l'on pousse comme DNS l'adresse de notre interface ppp locale (Il faudra donc faire attention à ce que bind écoute bien sur cette interface si vous suivez cette configuration. Pour le reste, voir avec man 😉

Les mots de passe de xl2tpd sont stockés dans le fichier /etc/ppp/chap-secrets. En voici un exemple :


# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
  user1		l2tpd	passworddetueurrrr	10.0.1.1
  user2 	l2tpd	passworddekiller	10.0.1.2

Il suffit d'ajouter nos utilisateurs dans ce fichiers en faisant attention de leur attribuer une ip dans le subnet qu'on a choisi précédemment.

Partie iptables

Pour finir, nous allons devoir autoriser les connexions sur les ports 500 et 4500 en udp et faire un masquerade de 10.0.1.0/27 pour l'autoriser à sortir sur le net ou à visiter un éventuel LAN se trouvant derrière notre serveur VPN. Pour cela on va faire :


iptables -t nat -A POSTROUTING -s 10.0.1.0/27 -j MASQUERADE
iptables -A INPUT -p tcp --dport 500 -j ACCEPT
iptables -A INPUT -p tcp --dport 4500 -j ACCEPT

C'est fini pour l’installation de la partie serveur. Je vais vous donner quelques trucs pour débugger d'éventuels problèmes.

Trucs & Astuces

  • Si jamais vous avez merdé avec votre conf xl2tpd, vous pouvez vérifier que celui-ci est bien lancé via :

ps aux | grep xl2
  • Si il ne tourne pas, vous pouvez le lancez en mode debug pour voir qu'est qui le fait planté en faisant :

xl2tpd -D
  • Cela peut également servir en cas de problème sur la partie xl2tpd
  • Vous pouvez vérifier la partie ipsec avec :

ipsec auto --status
  • Les logs d'IPsec sont dans /var/log/auth.log et les logs de xl2tpd sont dans /var/log/debug
  • Vous pouvez ajouter un compte VPN sans relancer xl2tpd, il suffit d'ajouter une entrée dans le fichier /etc/ppp/chap-secrets

La suite au prochain épisode...

Et le prochain épisode se trouve ici : client l2tp/ipsec sous linux

♥ Partage sur tes réseaux sociaux ♥
Kévin MET
Kévin MET

Auteur de ce blog et gérant de la société MNT-TECH, je publie sur ce blog lorsque le temps me le permet et lorsqu'un sujet qui me parait intéressant n'a pas encore été abordé en français. Toutes les informations techniques présentes sur cette page peuvent être réutilisées moyennant le fait de citer la source.