Installer et configurer un tunnel VPN L2TP/IPsec sur Debian
Coupler un tunnel L2TP à un tunnel IPsec est une solution VPN sécurisée très répandue dans les entreprises (grâce notamment à son support par les routeurs Cisco). Cette solution permet de mettre en place un VPN sur iPhone.
Ce guide est testé sur:
- Debian 6.0 Squeeze
- Debian 7.0 Wheezy
Ce guide est testé dans les configurations suivantes:
- Serveur VPN <- Routeur NAT <- Internet <- Routeur NAT <- iPhone 5 + iOS 6.0.1
- Serveur VPN <- Routeur NAT <- Internet <- Routeur NAT <- Mac OS X Mountain Lion 10.8.2
Prérequis
Sur Debian 6.0 Squeeze et antérieure, ce guide nécessite:
- l'ajout des dépôts de sources testing, comme décrit par Configurer les dépôts de sources Testing sur Debian stable.
Ce guide recommande:
- la mise en place d'un serveur Bind autorisant les requêtes pour le réseau local, comme décrit par Configurer un serveur DNS Bind sur Debian.
Paramètres
Renseignez le nom de domaine du VPN:
DOMAIN="domain.vpn"
Renseignez le nom de l'interface réseau connectée au réseau public (Internet):
TARGET_INTERFACE="eth0"
Déterminez une plage d'adresse IP aléatoire pour les clients du VPN:
VPN_IP_RANGE="10.$((${RANDOM}%256)).$((${RANDOM}%256))"
Installation
Détectez l'adresse IPv4 de l'interface cible:
TARGET_INTERFACE_IP=$(command ifconfig ${TARGET_INTERFACE} \
| command grep "inet " \
| command sed -e 's/^.*inet [^:]*:\([^ ]*\) .*$/\1/')
echo ${TARGET_INTERFACE_IP}
Détectez la plage d'adresses IPv4 de l'interface cible:
TARGET_INTERFACE_RANGE="$(command echo "${TARGET_INTERFACE_IP}" \
| command cut --delimiter="." --fields=1-3)"
Détectez l'adresse IPv4 de la passerelle de l'interface cible:
TARGET_INTERFACE_GATEWAY="$(command netstat -nr \
| command grep " UG " \
| command grep "${TARGET_INTERFACE_RANGE}" \
| command cut --characters=17-32 \
| command sed -e 's/[ ]*//g')"
echo ${TARGET_INTERFACE_GATEWAY}
Installation d'une version récente d'OpenSwan
Attention: ceci n'est nécessaire que si vous utilisez Debian 6.0 Squeeze ou antérieure.
La version présente dans Debian 6.0 Squeeze présente des bugs bloquant pour un bon fonctionnement avec iOS.
Installez les dépendances de construction du paquet OpenSwan:
command apt-get install build-essential dpkg-dev \
debhelper libgmp3-dev libssl-dev ppp \
htmldoc man2html libopensc2-dev dpatch \
libcurl4-openssl-dev libldap2-dev libpam0g-dev \
libkrb5-dev bison flex bzip2 po-debconf
Assurez-vous que toutes les dépendances sont présentes
command apt-get build-dep openswan
Placez-vous dans le dossier des sources:
command pushd '/usr/src'
Obtenez les sources de la version testing d'OpenSwan:
command apt-get source -t testing openswan
Placez-vous dans le dossier des sources:
command cd "$(command find '/usr/src' -maxdepth 1 -type d -name 'openswan-*' | command sort | command tail -n 1)"
Corrigez les erreurs de compatibilité avec Debian 6.0 Squeeze:
command sed -i -e 's/^.*buildflags.mk/#&/' 'debian/rules'
command sed -i -e 's/dpkg-dev[^,]*/dpkg-dev,/g' 'debian/control'
Lancez la construction du paquet:
command dpkg-buildpackage
Installez OpenSwan:
DEBIAN_FRONTEND='noninteractive' command dpkg -i "$(command find '/usr/src' -maxdepth 1 -type f -name 'openswan_*.deb' | command sort | command tail -n 1)"
Quittez le dossier des sources:
command popd
Installation d'une version récente de xl2tpd
Attention: ceci n'est nécessaire que si vous utilisez Debian 6.0 Squeeze ou antérieure.
La version présente dans Debian 6.0 Squeeze présente des bugs bloquant pour un bon fonctionnement avec iOS.
Installez les dépendances de construction du paquet OpenSwan:
command apt-get build-dep xl2tpd
Placez-vous dans le dossier des sources:
command pushd '/usr/src'
Obtenez les sources de la version testing d'OpenSwan:
command apt-get source -t testing xl2tpd
Placez-vous dans le dossier des sources:
command cd "$(command find '/usr/src' -maxdepth 1 -type d -name 'xl2tpd-*' | command sort | command tail -n 1)"
Lancez la construction du paquet:
command dpkg-buildpackage
Installez les paquets obtenus:
DEBIAN_FRONTEND='noninteractive' command dpkg -i "$(command find '/usr/src' -maxdepth 1 -type f -name 'xl2tpd_*.deb' | command sort | command tail -n 1)"
Quittez le dossier des sources:
command popd
Préparation de l'environnement
Installez les logiciels nécessaires:
DEBIAN_FRONTEND='noninteractive' command apt-get install apg ppp xl2tpd openswan openswan-modules-dkms
Activez les options IPv4 nécessaires au bon fonctionnement du tunnel (Attention: ne pas appliquer sur un routeur !):
echo "# Allowing nat translation for VPN clients.
net.ipv4.ip_forward=1
# Openswan security options
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0" \
>> "/etc/sysctl.conf"
Rechargez la configuration système:
command sysctl -p
Appliquez la configuration aux interfaces réseau existantes:
command find '/proc/sys/net/ipv4/conf' -mindepth 1 -type d \
| while read INTERFACE_SYS; do
command echo "0" > "${INTERFACE_SYS}/send_redirects"
command echo "0" > "${INTERFACE_SYS}/accept_redirects"
done
Configuration d'OpenSwan (IPSec)
Forcez l'utilisation de la pile netkey:
command sed -i -e 's/protostack=.*/protostack=netkey/g' '/etc/ipsec.conf'
Interdisez l'utilisation de la plage d'adresse IP du réseau local et du réseau VPN L2TP:
command sed -i \
-e "s|,%v4:\!192\.168\.1\.[^,]*||" \
-e "s|virtual_private=.*|&,%v4:\!${TARGET_INTERFACE_RANGE}.0/24,%v4:\!${VPN_IP_RANGE}.0/24|" \
"/etc/ipsec.conf"
Créez un fichier de configuration depuis le modèles:
command cp "/etc/ipsec.d/examples/l2tp-psk.conf" "/etc/ipsec.d/${DOMAIN/\./-}.conf"
Renommez les connections:
command sed -i \
-e "s/L2TP-PSK/${DOMAIN/\./-}-&/" \
-e "s/passthrough-for-non-l2tp/${DOMAIN/\./-}-&/" \
"/etc/ipsec.d/${DOMAIN/\./-}.conf"
Configurez l'adresse IP du serveur et de la passerelle:
command sed -i \
-e "s/YourServerIP/${TARGET_INTERFACE_IP}/g" \
-e "s/YourGwIP/${TARGET_INTERFACE_GATEWAY}/g" \
-e "s/YourGatewayIP/${TARGET_INTERFACE_IP}/g" \
"/etc/ipsec.d/${DOMAIN/\./-}.conf"
Ajoutez les paramètres nécessaires aux clients iOS (iPhone, iPad):
command sed -i -e "/rightprotoport=17\/%any/a\\
\t# Apple iOS doesnt send delete notify so we need dead peer detection\\
\t# to detect vanishing clients\\
\t#dpddelay=30\\
\t#dpdtimeout=120\\
\t#dpdaction=clear\\
\t# force all to be nated. because of ios\\
\tforceencaps=yes\\
\t# provide leftsubnet, mandatory for double nat setup.\\
\tleftsubnet=${TARGET_INTERFACE_RANGE}.0/24" \
"/etc/ipsec.d/${DOMAIN/\./-}.conf"
Activez la configuration:
echo "include /etc/ipsec.d/${DOMAIN/\./-}.conf" >> '/etc/ipsec.conf'
Créez la clef partagée (ici de longueur 128):
SHARED_KEY="$(command apg -q -m 128 -a 1 -n 1 -M NCLS -E '"')"
Configurez la clef partagée:
command sed -i -e "/${TARGET_INTERFACE_IP}[ \t]*%any:/d" '/etc/ipsec.secrets'
command echo "${TARGET_INTERFACE_IP} %any: PSK \"${SHARED_KEY}\"" >> '/etc/ipsec.secrets'
Protégez le fichier des secrets:
command chmod go-rwx '/etc/ipsec.secrets'
Configuration de xl2tpd (L2TP)
Ajoutez la configuration du tunnel à xl2tpd.conf:
echo "
; ${DOMAIN} L2TP/IPsec tunnel configuration.
[global]
;force userspace = yes
ipsec saref = yes
access control = no
auth file = /etc/xl2tpd/${DOMAIN/\./-}-secrets
listen-addr = ${TARGET_INTERFACE_IP}
;debug network = yes
;debug tunnel = yes
;debug avp = yes
;debug state = yes
[lns default]
ip range = ${VPN_IP_RANGE}.2-${VPN_IP_RANGE}.253
local ip = ${VPN_IP_RANGE}.1
assign ip = yes
require chap = yes
refuse pap = yes
require authentication = yes
name = ${DOMAIN}
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd.${DOMAIN/\./-}
length bit = yes
" \
>> '/etc/xl2tpd/xl2tpd.conf'
Remarque: la section [lns default] est obligatoire pour le bon fonctionnement de xl2tpd.
Configuration de ppp (PPTP)
Déterminez l'adresse des DNS Internet s'il y en a:
DNS_SERVERS="$(command grep "^nameserver" "/etc/resolv.conf" | command grep -v "127.0.0.1" | command sed -e 's/nameserver/ms-dns/g')"
Déterminez s'il y a un server Bind local et autorisez le réseau L2TP à l'utiliser:
if [ -x '/etc/init.d/bind9' ]; then
DNS_SERVERS="ms-dns ${VPN_IP_RANGE}.1
${DNS_SERVERS}"
command sed -i -e "/acl local-networks/a\\
\t${VPN_IP_RANGE}.1/24;" \
'/etc/bind/named.conf.options'
/etc/init.d/bind9 reload
fi
Créez le fichier de configuration du tunnel PPTP mise en place par xl2tp:
echo "# ${DOMAIN} IPsec/L2TP VPN PPTP setup.
name ${DOMAIN}
require-mschap-v2
ipcp-accept-local
ipcp-accept-remote
${DNS_SERVERS}
noccp
auth
crtscts
idle 1800
mtu 1200
mru 1200
nodefaultroute
#debug
lock
proxyarp
connect-delay 5000" \
> "/etc/ppp/options.xl2tpd.${DOMAIN/\./-}"
Configuration de l'accès au réseau local et à Internet pour les clients du VPN
Activez la règle NAT qui permet aux clients du VPN d'accéder à Internet en passant par le VPN:
command echo "#"\!"/bin/bash
command iptables -t nat -C POSTROUTING -s ${VPN_IP_RANGE}.0/24 -o eth0 -j MASQUERADE 2>'/dev/null' \\
|| command iptables -t nat -A POSTROUTING -s ${VPN_IP_RANGE}.0/24 -o eth0 -j MASQUERADE" \
> "/etc/network/if-up.d/iptables-l2tp-${DOMAIN/\./-}"
command chmod +x "/etc/network/if-up.d/iptables-l2tp-${DOMAIN/\./-}"
Chargez la règle:
/etc/network/if-up.d/iptables-l2tp-${DOMAIN/\./-}
Configuration des comptes utilisateurs pour ppp
Renseignez le nom de l'utilisateur:
PPP_USERNAME="my-account"
Déterminez un mot de passe pour l'utilisateur:
PPP_PASSWORD="$(command apg -q -m 128 -a 1 -n 1 -M NCL -E '"')"
Ajoutez le compte au fichier chap-secrets:
echo "${PPP_USERNAME} ${DOMAIN} ${PPP_PASSWORD} *" >> '/etc/ppp/chap-secrets'
echo "${PPP_USERNAME} * ${PPP_PASSWORD}" >> "/etc/xl2tpd/${DOMAIN/\./-}-secrets"
Affichez les paramètres de connexion au VPN pour l'utilisateur et notez-les:
echo "# Use the following to connect:
# Username:
${PPP_USERNAME}
# User password (secret key):
${PPP_PASSWORD}
# VPN shared key
${SHARED_KEY}"
Lancement du VPN
Démarrez le VPN:
/etc/init.d/ipsec restart
/etc/init.d/xl2tpd stop
/etc/init.d/xl2tpd start
Vérifiez la configuration IPsec (ignorez les alertes sur "Opportunistic Encryption Support" et "NAT and MASQUERADEing"):
command ipsec verify
Ajoutez le VPN au démarrage du système:
command update-rc.d ipsec defaults
command update-rc.d xl2tpd defaults
Configuration du pare-feu
Les ports suivant doivent être ouverts sur le pare-feu:
- port 500 UDP (protocole IKE)
- port 4500 UDP (protocole NAT-T)
- le protocole n°50
- le protocole n°51
Pour générer automatiquement les règles NAT iptables, renseignez l'adresse IP du serveur VPN sur le réseau local:
VPN_SERVER_IP="192.168.1.10"
Renseignez l'adresse IP de la connexion Internet du routeur (ici déterminée automatiquement):
PUBLIC_IP=$(command wget --quiet http://www.monip.org/ -O- \ | command grep "IP :" \
| command cut --characters=-80 \ | command sed -e 's/^.* \(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*$/\1/')
echo "${PUBLIC_IP}"
Le script suivant crée la configuration iptables nécessaire au serveur VPN L2TP/IPsec:
echo "#"\!"/bin/bash
# open protocol 50
command iptables -A PREROUTING -t nat -p 50 \\
-d ${PUBLIC_IP} \\
-j DNAT --to ${VPN_SERVER_IP}
# open protocol 51
command iptables -A PREROUTING -t nat -p 51 \\
-d ${PUBLIC_IP} \\
-j DNAT --to ${VPN_SERVER_IP}
# open port 500 udp
command iptables -A PREROUTING -t nat -p udp \
-d ${PUBLIC_IP} --dport 500 \\
-j DNAT --to ${VPN_SERVER_IP}:500
# open port 4500 UDP
command iptables -A PREROUTING -t nat -p udp \\
-d ${PUBLIC_IP} --dport 4500 \\
-j DNAT --to ${VPN_SERVER_IP}:4500
" >> '/etc/network/if-up.d/l2tp-ipsec-vpn'
command chmod +x '/etc/network/if-up.d/l2tp-ipsec-vpn'
Chargez les règles avec:
/etc/network/if-up.d/l2tp-ipsec-vpn
Les règles seront automatiquement chargées au démarrage du système.
Détecter les problèmes
IPsec (OpenSwan)
Vérifiez la connectivité IPsec avec:
command ipsec verify
Affichez l'état des connexions IPsec avec:
command ipsec auto --status
Visualisez les messages générés par IPsec dans le fichier auth.log:
command tail -f '/var/log/auth.log'
L2TP (xl2tpd)
Visualisez les messages générés par xl2tpd dans syslog:
command tail -f '/var/log/syslog'
Activez le mode de débogage de xl2tpd, et affichez les messages de débogage dans la console:
command sed -i -e 's/;debug/debug/' '/etc/xl2tpd/xl2tpd.conf'
command sed -i -e 's/#debug/debug/' /etc/ppp/options.xl2tpd.*
/etc/init.d/xl2tpd stop
command xl2tpd -D
Désactivez le mode de débogage de xl2tpd et relancez le fonctionnement standard:
command sed -i -e 's/^debug/;debug/' '/etc/xl2tpd/xl2tpd.conf'
command sed -i -e 's/^debug/#debug/' /etc/ppp/options.xl2tpd.*
/etc/init.d/xl2tpd stop
/etc/init.d/xl2tpd start
Remerciements
- Merci à #a&a asterisk for Setting up an L2TP/IPSec server on Debian.
- Merci au blog technique de Laurent Besson pour Serveur VPN L2TP IPsec Linux avec authentification Radius couplée avec LDAP.
- Merci au Wiki Linux SMH pour Créer un VPN L2TP/IPSec.
- Merci à Riobard Zhan pour Configure L2TP/IPSec VPN on Ubuntu.
- Merci à The gadget blog pour Debian squeeze l2tp/IPSec vpn server with an iOS road warrior.