---
layout: post
slug: l2tp
status: published
title: Tunnel L2TP
description: Créer un tunnel avec la commande ip
disqus: true
categories:
- linux
tags:
- projet
---

J'utilise assez couramment OpenVPN afin de contourner le filtrage de certains pare feu, ou pour changer d'adresse IP, particulièrement dans le cas de serveurs de jeux un peu tatillon lors des lans, qui refusent plus de X connexions depuis la même adresse IP.

En lisant le man de la commande ``ip``, je suis tombé sur un passage sur l2tp, une autre façon de faire du VPN. Pour ceux qui voudraient la documentation technique, je vous inviter à faire un petit ``man ip-l2tp``. Ici, nous verrons la partie pratique.

Tout d'abord il faut savoir que l'implémentation de L2TP dans la commande ip pose des contraintes particulières. En effet, le tunnel est "static" ou "unmanaged". Il n'y a pas de protocole de controle L2TP, pas de daemon, tous les paramètres doivent être entrés à la main. Enfin, on ne peut faire passer que des frames ethernet.

##L2TP et Debian

J'ai actuellement deux versions de Debian en serveur. Une Jessie (Testing) et une Wheezy. J'ai aussi une Fedora 20 en client. La Wheezy ne semble pas vouloir l2tp de base. Notons aussi que la doc ``ip-l2tp`` est absente. Au moment de lancer la commande, j'ai un magnifique :

```bash
RTNETLINK answers: No such file or directory
Error talking to the kernel
```

Quant à ma Fedora, tout semblait aller bien, jusqu'à l'ajout d'une session dans mon tunnel, où j'ai eu cette erreur :

```bash
RTNETLINK answers: Protocol not supported
```

Dans les deux cas, la solution est simple, quoique pas facile à trouver : il faut charger le bon module noyau :

```bash
sudo modprobe l2tp_eth
```

Je n'ai pas fais les tests jusqu'au bout avec Jessie, je suppose que ça marche. A vous d'adapter !

_Je vous met le lien du thread OpenStack au cas où [l2tpV3 on Ubuntu Precise](https://ask.openstack.org/en/question/3881/l2tpv3-on-ubuntu-precise/)_
Bref, nous voilà prêt à en découdre avec L2TP !

##Commençons par créer un tunnel

On va d'abord établir la liaison entre les deux machines avant d'attaquer autre chose.

####Le PC-A

```bash
ip l2tp add tunnel tunnel_id 1337 peer_tunnel_id 1338 \
encap udp local 192.168.1.12 remote 192.168.1.38 \
udp_sport 5000 udp_dport 5001
```

On ajoute un tunnel avec pour id 1337 en local et 1338 sur l'ordinateur distant.  
On encapsule les données en UDP (possibilité d'utiliser l'IP si pas de NAT ou de passerelle).  
On donne notre adresse IP locale et l'adresse IP du serveur distant.  
On précise les ports UDP à utiliser (sport = local et dport = distant)

####Le PC-B

On tape la commande en "miroir" du coté client (on inverse les id, les adresses ip et les ports) :

```bash
ip l2tp add tunnel tunnel_id 1338 peer_tunnel_id 1337 encap udp local 192.168.1.38 remote 192.168.1.12 udp_sport 5001 udp_dport 5000
```

####Des commandes utiles

Vous pouvez aussi supprimer et voir les tunnels existants :

```bash
ip l2tp del tunnel tunnel_id 1337
ip l2tp show tunnel
```

_Attention, vous devez avoir supprimé toutes les sessions du tunnel avant de pouvoir le supprimer._

##Ajoutons une session dans le tunnel

####Le PC-A

```bash
ip l2tp add session tunnel_id 1337 session_id 337 peer_session_id 338
```

On ajoute une session dans le tunnel 1337
Son identifiant en local est 337 et sur l'ordinateur distant 338

Enfin pour activer l'interface (recommandé dans le man) :

```bash
ip link set l2tpeth0 up mtu 1488
```

####Le PC-B

Comme d'habitude, on fait ça en miroir :

```bash
ip l2tp add session tunnel_id 1338 peer_session_id 337 session_id 338
```

Idem, pour activer l'interface :

```bash
ip link set l2tpeth0 up mtu 1488
```

####Des commandes utiles

Plus ou moins le même schéma que tout à l'heure, avec quelques ajouts :

```bash
ip l2tp del session tunnel_id 1337 session_id 337
ip l2tp show session
ip addr
```
La dernière commande vous permet de voir qu'une interface l2tpeth0 a été ajoutée à vos interfaces.

##Configurons l'interface en IP

####Le PC-A

```bash
ip addr add 10.42.1.1 peer 10.42.1.2 dev l2tpeth0
```
On assigne l'adresse IP 10.42.1.1 a l'interface l2tpeth0 et on informe que l'interface distante a pour adresse 10.42.1.2.

####Le PC-B

```bash
ip addr add 10.42.1.2 peer 10.42.1.1 dev l2tpeth0
```
La même chose en miroir (pour changer).

####Les tests

Tout d'abord vérifiez que les interfaces soient bien configurées et UP :

```
ip addr
```

Un petit coup d'oeil aux routes ne fait pas de mal :

```
ip route
```

On peut se lancer dans le grand bain en pingant l'ordinateur distant. Depuis PC-A, on fait :

```
ping 10.42.1.2
```

Si le ping passe, c'est que vous avez réussi ! Sinon, n'hésitez pas à utiliser tout l'arsenal d'outils à votre disposition : wireshark, etc.

Pour moi, ça a marché, à vous de jouer !

##Problèmes

 * Il semble nécessaire de créer un tunnel par couple de PC avec cette implémentation de L2TP.
 * Si vous êtes derrière un NAT, vous devez pouvoir changer sa configuration des DEUX cotés.

##Explorons !

Il reste encore bien des possibilités. Ainsi, nous verrons prochainement comment bridger les interfaces en L2TP pour faire passer autre chose que de l'IP ainsi que quelques rudiments de routage avec ``ip route``
