Monter un tunnel IPSec sous Linux

Ce billet détaille comment monter un tunnel IPSec sous Linux. C’est à mon sens un must have, principalement parce qu’IPSec est une merde ignoble sous Linux.
Mais avant de procéder plus avant, une question se pose.

Pourquoi IPSec ?

Actuellement je souhaite relier :

  • plusieurs serveurs sur Internet
  • plusieurs réseau locaux (celui du bureau et ceux des machines virtuelles derrières le routeur qui détient l’IP publique)

Voici mes possibilités pour réaliser ce « gros » réseau :

  • créer plein de règles nat sur chaque routeurs.
    • c’est pénible à maintenir
    • oblige à reconfigurer les services pour n’utiliser que certaines plages de ports, et sans chevauchement d’une machine/vm à l’autre
    • oblige à avoir une feuille avec la table de mapping et utiliser des ports non standards
      Pas géniale comme solution, et les tuyaux ne sont pas sécurisés.
      On peut alors reconfigurer tous les services pour protéger chaque flux, mais la manière de faire et la possibilité dépendent du service. Désormais on a la plupart des tuyaux qui sont sécurisés et encore plus de maintenance.
  • mettre en place OpenVPN qui répond entièrement à la problématique, mais :
    • il est architecturé en étoile (1 serveur, plusieurs clients). On peut aussi installer OpenVPN sur chaque routeur en mode serveur, mais c’est pas mal de configuration.
    • il fonctionne en faisant le transport sur la couche applicative du modèle OSI (les paquets sont encapsulé dans un flux SSL sur du TCP ou UDP), cela induit un peu d’overhead
      C’est la solution qui est actuellement en place chez moi.

Par rapport à OpenVPN, voici les avantages d’IPSec :

  • c’est du P2P, il n’y a pas de notion « serveur », les routeurs se connectent donc en direct
  • comme OpenVPN, la communication entre les 2 pairs est chiffrée
  • il est kernel-space sous Linux et Windows, il est donc moins lourd qu’OpenVPN et ne nécessite aucune installation sous Windows
  • son intégration aux protocoles IPs lui permet d’avoir un overhead plus faible qu’avec OpenVPN, donc une bande passante plus large
  • les tunnels d’OpenVPN semblent saturer vite vers 10Mbps chez moi

Quelle implémentation d’IPSec ?

C’est une question qui ne se pose que pour le monde Unix. Avoir le choix c’est bien, mais dans le cas d’IPSec, c’est un peu compliqué. Côté logiciel, il y a eu FreeSwan, puis OpenSwan, puis StrongSwan ; côté noyau également, il a existé plusieurs implémentations : klips et netkey.
Aujourd’hui, j’ai jeté mon dévolu sur strongswan. Klips n’existe plus et les autres logiciels ne sont plus maintenus depuis plusieurs années, c’est donc quasiment un choix par défaut, mais également pour la négociation par certificats que strongswan est le seul à proposer (et que je trouve beaucoup plus simple à configurer que le Pre-Shared Key).

La conf !

Elle est très simple. Voici un exemple fonctionnel ci-dessous qui utilise l’authentification mutuelle par certificat, pour le détail: RTFM, ce dernier est plutôt à jour et bien réalisé.
Je ne détaille pas comment générer les certificats, ce n’est pas le but du billet, et puis j’ai déjà traité ça ici.

config setup
cachecrls=yes
# uniqueids = no

# Add connections here.
conn %default
auto=start
compress=no # ne fonctionne pas
dpdaction=restart
esp=aes128-sha1!
ike=aes128-sha1-modp2048,aes128-sha1-modp1024!
rightallowany=yes
left=2001:41d0:fe1c:1300:20c:29ff:fe99:fbf
#left=%any
leftauth=pubkey
rightauth=pubkey
leftid="C=FR, O=Kveer, OU=Kveer IPSec Services, CN=Tefnout"
leftca="C=FR, O=Kveer, OU=Kveer IPSec Services, CN=Kveer IPSec CA"
rightca=%same
leftcert=tefnout.crt
leftfirewall=no
mobike=no
keyexchange=ikev2

conn illidan
right=illidan.kveer.fr
rightid="C=FR, O=Kveer, OU=Kveer IPSec Services, CN=Illidan"
leftsubnet=192.168.3.0/24
rightsubnet=192.168.14.128/27
# les règles iptables à ajouter.
iptables -A INPUT -p udp -m multiport --dport isakmp,ipsec-nat-t -m comment --comment ipsec -j ACCEPT
iptables -A INPUT -p esp -j ACCEPT
iptables -t nat -I POSTROUTING 1 -m policy --dir out --pol ipsec -j ACCEPT

La dernière règle iptables est à ne pas oublier si l’on souhaite faire fonctionner le tunnel pour les routeurs eux-mêmes. Dans le cas d’un tunnel IPv4, ça ne marchera pas, dans le cas d’un tunnel IPv6, le kernel va générer un Oops (la règle est obligatoire sous peine de non-sens, mais cela n’autorise pas le kernel à planter, c’est bien un bug, en attente de correction)

Intégration des modules vmware à linux

Il n’y a pas si longtemps, j’avais écrit un billet permettant de compiler soit-même les quelques modules VMware fournit dans les VMware Tools.
J’ai pu tester ce script à plusieurs reprises d’ailleurs, à chaque mise à jour de kernel en fait, et ça dépanne bien.
Il y a juste un patch, celui concernant le module vmci , qui est à faire manuellement. Pour une raison qui m’échappe encore (je n’ai pas trop cherché non plus, mais je penche vers un problème d’espaces), le copier/coller depuis le script ne fonctionne pas.

Et bien ce billet annonce la bonne nouvelle : ce script va faire partie des vieilleries car depuis la branche 3.9 du noyau Linux, ces modules font désormais partie intégrante du noyau.
Voici le nom des modules (j’en profite également pour rappeler l’existence du pilote vmxnet3 ):

  • CONIG_VMWARE_VSOCKETS
  • CONFIG_VMWARE_VMCI_VSOCKETS
  • CONFIG_VMWARE_BALLOON
  • CONFIG_VMWARE_VMCI
  • CONFIG_VMXNET3

Les re-voici dans le menuconfig, pour vous faciliter la recherche :

 

* Device Drivers --->
** Misc Devices --->
*** \[*\] VMware Balloon Driver
*** \[*\] VMware VMCI Driver
** \[*\] Network device support --->
*** VMware VMXNET3 ethernet driver
* \[*\] Networking support --->
** Networking options --->
*** <*> Virtual Socket protocol
*** <*> VMware VMCI transport for Virtual Sockets

Adieu les vmware tools sous Linux (et sans regrets) !