Un VPN avec OpenIKED

OpenIKED est une implémentation libre du protocole IKEv2 qui permet de mettre en place des VPN de type IPSec.

OpenIKED

Ce protocole permet, comme Wireguard, de s'assurer des éléments de sécurité suivants :

Sous OpenBSD, le nom du démon qui gère les connexions IKEv2 s'appelle iked.

Vous pouvez dores et déjà consulter la FAQ17 qui couvre officiellement le sujet, puisque cette partie en suit les grandes lignes en guise de traduction détaillée.

FAQ17

Configuration des paires de clés

Par défaut, iked utilise une identification par jeton de clés (publique/privée), un peu comme pour ssh. Vous pouvez les stocker dans des dossiers bien précis pour faciliter l'organisation (au format PEM), iked les prendra automatiquement en charge. Selon si les sources (srcid) et les destinations (dstid) sont écrites sous la forme d'adresses IP ou de noms de domaines, les clés publiques seront à enregistrer sous :

Ce qui est génial, c'est qu'iked saura les retrouver comme un grand.

Dans le cadre de ce tutoriel, nous allons présenter la méthode la plus simple, à savoir se servir des clés publiques présentes par défaut sur une installation d'OpenBSD. Libre à vous de créer de nouvelles paires de clés avec la commande openssl si vous le souhaitez afin de changer l'algorithme de chiffrement. La partie privée des clés générées sera dans /etc/iked/private, mais vous l'auriez deviné tout seul 😉.

Pour l'exemple, nous allons copier les clés déjà prêtes. C'est facile de les trouver, il s'agit du fichier /etc/iked/local.pub.

Configuration réseau pour iked

Sur le serveur et le client, activez l'interface enc0 :

# echo up > /etc/hostname.enc0
# sh /etc/netstart enc0

Ensuite, insérez dans le fichier /etc/sysctl.conf les lignes suivantes, toujours sur le serveur et le client.

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

Sur le serveur et le client, vous ajouterez :

net.inet.ipcomp.enable=1

Activez directement ces fonctionnalités sans avoir à redémarrer :

# while read -r line; do sysctl $line; done < /etc/sysctl.conf

Configuration du pare-feu pour iked

Afin de pouvoir établir la liaison entre le client et le serveur, vous devez ouvrir et rediriger ports 500 (isakmp) et 4500 (ipsec-nat-t) sur le serveur.

De plus, on redirige le traffic passant par le VPN en sortie pour qu'il apparaisse avec l'IP du serveur et non celle du client. Ce flux est repéré par l'étiquette "ROADW" définie plus loin dans la configuration d'OpenIKED. Le fichier /etc/pf.conf du serveur ressemblera à ceci (lisez les commentaires) :

# On rassemble les paquets
set reassemble yes
# Petite precaution
antispoof quick for enc0

# On laisse entrer le traffic IKE et IKE NAT-Traversal pour l'authentification
pass in log on egress proto udp from any to <ip-du-serveur> port {isakmp, ipsec-nat-t} tag IKED
pass in log on egress proto esp from any to <ip-du-serveur> tag IKED
# On laisse passer le traffic encapsule avec l'etiquette ROADW
pass log on enc0 tagged ROADW
# On redirige le traffic avec l'etiquette ROADW vers la sortie
match out log on egress inet tagged ROADW nat-to (egress)

Configuration d'IKED

Tous les fichiers iked.conf doivent avoir des droits bien choisis. Que ce soit sur le client ou le serveur, vous entrerez :

# touch /etc/iked.conf
# chmod 600 /etc/iked.conf

Sur le serveur

Voici le contenu du fichier /etc/iked.conf sur le serveur :

ikev2 "warrior" passive ipcomp esp \
from 0.0.0.0/0 to 10.0.5.0/24 \
peer any local <ip.publique.du.serveur> \
srcid "chezmoi.tld" \
tag "ROADW"

Ce dernier crée un flux à partir du traffic venant de n'importe où (0.0.0.0) et le redirige vers le réseau 10.0.5.0/24 auquel appartiendront les clients. Au passage, il donne l'étiquette "ROADW" à ce flux pour le repérer ensuite.

Pensez à bien modifier l'IP publique du serveur et le nom de domaine. Le paramètre srcid servira à identifier le certificat à utiliser pour l'authentification (ça peut donc aussi être une adresse IP selon ce que vous avez préféré.

Tu crois t'en sortir comme ça ? Nous on veut savoir ce que ça veut dire ces trucs bizarres dans la configuration.

Et c'est parti pour des détails, ligne par ligne :

Sur le client

La configuration est quasiment identique, mais inversée 😉

ikev2 "warrior" active ipcomp esp \
from 0.0.0.0/0 to 0.0.0.0/0 \
peer "<ip.publique.du.serveur>" \
srcid "batman@cacahuete.tld" \
dstid "chezmoi.tld"

Les paramètres auxquels vous devez être attentifs sont srcid et dstid :

Si vous êtes perdus, retournez lire la partie sur les clés un peu plus haut. 😉

Le client doit aussi configurer son IP pour qu'elle appartienne au réseau 10.0.5.0/24. Vous pouvez le faire ainsi en éditant sur le client le fichier de configuration /etc/pf.conf :

match out log on enc0 inet all nat-to 10.0.5.2

Cela associe tout le flux sortant sur l'interface enc0 à l'adresse 10.0.5.2. Si vous utilisez plusieurs client, vous devrez modifier cette adresse. N'oubliez pas de recharger le parefeu.

Attention : tout le flux du client passe désormais par le tunnel chiffré. Cela peut être embêtant notamment pour la résolution de domaine, ou si vous utilisez des démons locaux. Ajoutez seulement cette ligne au fichier /etc/ipsec.conf :

flow from 127.0.0.1/32 to 127.0.0.1/32 type bypass

Activez cette règle avec la commande

# ipsecctl -f /etc/ipsec.conf

En cas d'erreur concernant les permissions, entrez :

# chmod 600 /etc/ipsec.conf

Afin de ne pas avoir à lancer cette commande lors d'un redémarrage, entrez :

rcctl enable ipsec

Attention 2 : La résolution de noms (DNS) ne pourra pas se faire en local. Idéalement, il faudrait indiquer dans le fichier /etc/resolv.conf un résolveur accessible via le VPN, et dans l'idéal le serveur. Dans le doute, indiquez dans /etc/resolv.conf un résolveur publique :

nameserver 9.9.9.9

Mise en route

C'est parti ! 😊

Sur le serveur, rechargez le parefeu et activez/démarrez iked :

# pfctl -f /etc/pf.conf
# rcctl enable iked
# rcctl start iked

Sur le client, lancez pour commencer iked sans le mettre en arrière-plan :

# iked -vvd

Vous allez voir un tas de choses s'afficher. Si vous voyez une ligne qui ressemble à la suivante, c'est tout bon 😉 :

sa_state: VALID -> ESTABLISHED from 46.23.92.147:4500 to 192.168.100.122:4500 policy 'warrior'

Par la suite, vous pourrez activer iked sur le client avec rcctl.

Pour vérifier que cela fonctionne, vous pouvez consulter un des sites permettant de connaître son IP publique. Si elle est différente de d'habitude et correspond à celle du serveur, c'est réussi 😊. Vous pouvez plus simplement le vérifier avec la commande suivante :

# ipsecctl -sa
FLOWS:
flow esp in from 0.0.0.0/0 to 192.168.0.0/16 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type use
flow esp out from 192.168.0.0/16 to 0.0.0.0/0 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type require
flow esp out from ::/0 to ::/0 type deny

SAD:
esp tunnel from 46.23.92.147 to 192.168.100.122 spi 0x7958b1de auth hmac-sha2-256 enc aes-256
esp tunnel from 192.168.100.122 to 46.23.92.147 spi 0xe7d244a8 auth hmac-sha2-256 enc aes-256

En cas de problème, avant d'arrêter le processus iked, lancez la commande suivante pour fermer le tunnel :

# ikectl decouple

Gérer le VPN

À partir du client:

Utilisation avec des clients n'utilisant pas OpenBSD

Sous Linux ou avec un smartphone android, vous aurez besoin d'utiliser l'application strongswan pour configurer la connexion à votre VPN. Il faudra toutefois configurer un accès par certificats.

Strongswan
Configurer un accès par certificats

Sinon, MacOS et Windows peuvent le gérer nativement, mais il faudra demander à leurs experts.

Ressources sur Openiked

FAQ 17
puffysecurity
huxtable.ca
man iked.conf
man ikectl
leadership