VPN avec FreeBSD

Ce document est une aide à la création de VPN avec FreeBSD, les how-to et man existant étant un peu trop succints à mon gout.

Un VPN permet de relier 2 sous-réseaux ensemble, via l'internet. On peut ainsi relier 2 réseaux privatifs comme s'ils étaient en local. On y adjoint un cryptage afin de rendre le transfert des donnés sécurisé.

Cette installation nécessite une version 4.4 de FreeBSD, ou plus récente. Quelques changements ont été introduits dans l'administration du device gif que nous utiliserons pour le tunnel depuis la version 4.3.

Configuration du noyau

Il est nécessaire de recompiler le noyau pour y inclure IPSEC, que nous utiliserons pour le cryptage. IPSEC se manipule avec setkey(8) et permet 2 types de sécurisation: le mode AH, qui garantit l'authenticité des paquets mais pas leur contenu, et le mode ESP qui crypte le contenu data des paquets IP, mais ne garantit pas leur authenticité.

La première étape consiste donc à recompiler le noyau avec les options suivantes:

      options   IPSEC
      options   IPSEC_ESP
    

Assurez-vous également que le pseudo-device gif est bien présent dans le noyau, c'est le cas si vous partez du fichier de configuration GENERIC.

Il nous faut également installer racoon via les ports pour l'échange de clés (/usr/ports/security/racoon).

Création du tunnel

Nous allons maintenant créer le tunnel à proprement parler, sans nous occuper du cryptage. Ceci se fait facilement grace au pseudo-device gif, qui se configure (maintenant) avec ifconfig.
Imaginons d'abord le schema de notre réseau:

      sous-réseau A -- gateway A <------> gateway B -- sous-réseau B
       10.0.1.0/24    123.34.56.78       231.12.23.45   10.0.2.0/24
    

123.34.56.78 et 231.12.23.45 sont les adresses publiques de nos 2 réseaux. Nous allons avec le tunnel joindre les réseaux 10.0.1.0/24 et 10.0.2.0/24. La gateway A possède 2 interfaces, 1 vers l'extérieure en 123.34.56.78 et une vers le sous-réseau en 10.0.1.1.

De chaque coté du VPN, sur les gateway, il va falloir router le sous-réseau vers la gateway de l'autre réseau. Ainsi sur la gateway A, on définit le routage suivant (à rajouter dans /etc/rc à la fin) (avant le exit 0 quand meme :P):

      /sbin/ifconfig gif0 create
      /sbin/ifconfig gif0 tunnel 123.34.56.78 231.12.23.45
      /sbin/ifconfig gif0 inet 10.0.1.1 10.0.2.1 netmask 255.255.255.255
      route add -net 10.0.2.0/24 10.0.2.1
    

La dernière ligne de routage est importante (et les autres how-to l'oublient pourtant...), c'est grace à elle que les paquets du sous-réseau A sont routés vers la gateway B.

De façon symétrique, sur la gateway B, on rajoute à /etc/rc:

      /sbin/ifconfig gif0 create
      /sbin/ifconfig gif0 tunnel 231.12.23.45 123.34.56.78
      /sbin/ifconfig gif0 inet 10.0.2.1 10.0.1.1 netmask 255.255.255.255
      route add -net 10.0.1.0/24 10.0.1.1
    

Pour finir, il faut activer le forwarding IP en rajoutant dans /etc/rc.conf

      gateway_enable="YES"
    

Sécurisation du tunnel

Si on ne fait que router les paquets par le tunnel que l'on vient de créer, les données transitent en clair sur internet, il suffit d'observer les paquets en faisant un tcpdump sur une machine entre vos 2 gateway pour s'en convaincre. Hors il y a fort à parier que si votre installation était composée de sous-réseau auparavant, c'est que les données y transitant étaient plutot confidentielles... Nous allons donc nous servir d'IPSEC pour crypter ces données.

De manière similaire à la création du tunnel, nous allons configurer IPSEC pour que les paquets transitant d'un sous-réseau à l'autre soient cryptés. Créons le fichier /etc/ipsec.conf, tout d'abord au niveau de la gateway A:

      flush;
      spdflush;
      spdadd 10.0.1.0/24 10.0.2.0/24 any -P out ipsec esp/tunnel/123.34.56.78-231.12.23.45/require;
      spdadd 10.0.2.0/24 10.0.1.0/24 any -P in ipsec esp/tunnel/231.12.23.34-123.34.56.78/require;
    

Les 2 premières lignes nettoient les éventuelles règles déjà présentent. Les 2 lignes suivantes définissent les règles de sécurisation, la syntaxe pour spdadd étant:
spdadd [sous-réseau source] [sous réseau destination] [les protocoles, dans notre cas tous, any] [-P [la direction du paquet, in ou out si entrant ou sortant] ipsec [le protocole de cryptage, grosso modo ah ou esp (il en existe d'autres présents pour des raisons de compatibilité)/le mode, transport ou tunnel/l'IP source-l'IP destination, les gateway en l'occurence/le niveau, require signifiant qu'une sécurisation est nécessaire dès qu'un paquet obéit aux règles énoncées]

IPSEC est également utilisé pour sécuriser le trafic entre 2 machines sans pour autant créer de tunnel, on appelle alors cette sécurisation le mode transport, mais je ne m'y attarderais pas car ce n'est pas le propos de cette documentation. C'est pour cette raison que la syntaxe de setkey est assez complexe.

Pour activer IPSEC au démarrage, on rajoute dans /etc/rc.conf:

      ipsec_enable="YES"
    

Toujours de manière symétrique, on configure /etc/ipsec.conf sur la gateway B:

      flush;
      spdflush;
      spdadd 10.0.2.0/24 10.0.1.0/24 any -P out ipsec esp/tunnel/231.12.23.34-123.34.56.78/require;
      spdadd 10.0.1.0/24 10.0.2.0/24 any -P in ipsec esp/tunnel/123.34.56.78-231.12.23.45/require;
    

Configuration des clés

La dernière étape consiste à définir les clés qui seront utilisées lors du cryptage. Ceci se fait grace à racoon que nous avons installé via les ports.

Le fichier de configuration de base de racoon suffira à nos besoins. On copiera le fichier /usr/local/etc/racoon/racoon.conf.dist en racoon.conf. Il reste à définir la clé d'échange, dans le fichier /usr/local/etc/racoon/psk.txt. On y indique l'IP de la machine avec laquelle se fait l'authentification, suivi de la clé, ce qui nous donne au niveau de la gateway A:

      231.12.23.45 macledetest
    

et sur la gateway B:

      123.34.56.78 macledetest
    

Attention: le fichier psk.txt doit être lisible seulement par root (chmod 600 psk.txt) et appartenir à root (chown root:wheel psk.txt). Il ne reste plus qu'à ajouter racoon au fichier de démarrage /etc/rc:

      /usr/local/sbin/racoon -f /usr/local/etc/racoon/racoon.conf
    

Le VPN est maintenant configuré, les 2 sous-réseaux sont accessibles depuis l'un ou l'autre. A la première connexion, une légère attente se manifestera, liée à l'échange des clés.


Fabien Menemenlis
Last modified: Tue Apr 15 11:23:37 CEST 2003