Howto IKED
Documentation :
IKED est le démon utilisé sous OpenBSD pour mettre en place un VPN IPsec avec IKEv2.
Configuration
Configuration de base
On met en place un VPN entre 2 machines OpenBSD :
- GW1 avec l’IP publique 192.0.2.254 et le LAN 203.0.113.0/25 ;
- GW2 avec l’IP publique 198.51.100.254 et le LAN 203.0.113.128/25.
Sur GW1 :
Vérification de l’activation des paramètres sysctl :
# sysctl net.inet.esp.enable
net.inet.esp.enable=1
# sysctl net.inet.ah.enable
net.inet.ah.enable=1
# sysctl net.inet.ip.forwarding
net.inet.ip.forwarding=1
Configuration de /etc/pf.conf
:
set skip on {lo0, enc0}
# Autorisations IPsec
VPN_PEERS="198.51.100.254"
pass in quick on $ext_if proto esp from $VPN_PEERS to ($ext_if)
pass in quick on $ext_if proto udp from $VPN_PEERS to ($ext_if) port {isakmp, ipsec-nat-t}
Et application les modifications :
# pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
On peut aussi autoriser toutes les interfaces enc*
:
set skip on {lo0, enc}
Ou même avoir un filtrage spécifique (pas de skip
mais
du pass
selon le trafic).
S’il y a un firewall global en amont, y configurer
/etc/pf.conf
avec une
table <serveurs_ipsec>
contenant les IP des serveurs
IPsec locaux (pas de filtrage sur les serveurs IPsec distants ici, le
filtrage est fait sur la machine finale comme vu au-dessus) :
table <serveurs_ipsec> { 198.51.100.254 192.0.2.254 203.0.113.254 }
# Autorisation des peers ipsec externes
pass in quick on $ext_if proto esp from any to <serveurs_ipsec> keep state (pflow)
pass in quick on $ext_if proto udp from any to <serveurs_ipsec> port 500 keep state (pflow)
Et application les modifications :
# pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
Configuration de /etc/iked.conf
:
local_ip="192.0.2.254"
local_network="203.0.113.0/25"
remote_ip="198.51.100.254"
remote_network="203.0.113.128/25"
ikev2 nom_vpn active esp \
from $local_network to $remote_network \
local $local_ip peer $remote_ip \
ikesa auth hmac-sha2-256 enc aes-256 group modp4096 prf hmac-sha2-256 \
childsa auth hmac-sha1 enc aes-256 group modp4096 \
srcid $local_ip dstid $remote_ip \
ikelifetime 86400 lifetime 3600 \
psk "PSK-TO-CONFIGURE"
Les paramètres ikesa
et ikelifetime
correspondants à la phase 1, childsa
et
lifetime
à la phase 2. nom_vpn
est un nom
facultatif et facilitant l’identification du VPN, notamment dans les
logs, et doit être unique.
Test de la configuration :
# iked -nf /etc/iked.conf
configuration OK
Activation de iked :
# rcctl enable iked
Désactivation complète du NAT-Traversal (il peut parfois être utilisé même si non configuré, pouvant causer des soucis) et augmentation de la verbosité :
# rcctl set iked flags -Tv
Enfin, démarrage de iked :
# rcctl start iked
Puis effectuer les mêmes actions sur l’autre passerelle.
Pour une meilleure stabilité du VPN, on met un ping permanent en cron qui passe par le VPN en question :
# Maintenir les tunnels ouverts
* * * * * ping -q -I 203.0.113.1 -c 60 -w 1 203.0.113.254 >/dev/null 2>&1
Avec en source (option -I
) une IP du serveur IPsec local
faisant partie de local_network
, et en destination une IP
distante faisant partie de remote_network
(celle-ci doit
être configuré pour répondre au ping).
Configurer plusieurs sous-réseaux dans un tunnel
Dans le cas où l’on veut atteindre plusieurs réseaux locaux distants,
il faut ajouter une ligne
from $local_network to $remote_network_second \
, ce qui
donne :
local_ip="192.0.2.254"
local_network="203.0.113.0/25"
remote_ip="198.51.100.254"
remote_network="203.0.113.128/26"
remote_network_second="203.0.113.192/26"
ikev2 nom_vpn active esp \
from $local_network to $remote_network \
from $local_network to $remote_network_second \
local $local_ip peer $remote_ip \
ikesa auth hmac-sha2-256 enc aes-256 prf hmac-sha2-256 group modp4096 \
childsa auth hmac-sha1 enc aes-256 group modp4096 \
ikelifetime 86400 lifetime 3600 \
psk "PSK-TO-CONFIGURE"
Si ce sont les réseaux locaux qui sont multiples, il faut ajouter une ligne par réseau local distinct.
Note : Attention cependant, il y a visiblement des soucis avec OpenBSD lorsque l’on veut monter plusieurs sous-réseaux en IKEv2 : un seul sous-réseau est fonctionnel. Il vaut mieux pour ce cas passer à IKEv1.
Utiliser une interface d’encapsulation différente
Par défaut, c’est l’interface d’encapsulation enc0
qui
est utilisée. On peut vouloir utiliser une interface distincte pour un
ou plusieurs tunnels montés. Ça donne plusieurs avantages, tels que la
mesure du débit indépendante pour chaque tunnel, un filtrage plus précis
via PacketFilter, ou encore du debug plus simple avec tcpdump.
Il faut ajouter le mot-clé tap
suivi du nom de
l’interface à la fin de la configuration :
local_ip="192.0.2.254"
local_network="203.0.113.0/25"
remote_ip="198.51.100.254"
remote_network="203.0.113.128/25"
ikev2 nom_vpn active esp \
from $local_network to $remote_network \
local $local_ip peer $remote_ip \
ikesa auth hmac-sha2-256 enc aes-256 group modp4096 prf hmac-sha2-256 \
childsa auth hmac-sha1 enc aes-256 group modp4096 \
srcid $local_ip dstid $remote_ip \
ikelifetime 86400 lifetime 3600 \
psk "PSK-TO-CONFIGURE" \
tap enc1
Ne pas oublier d’échapper le saut de ligne après la PSK.
Créer ensuite l’interface :
# echo up > /etc/hostname.enc1
# sh /etc/netstart enc1
Et adapter la configuration de /etc/pf.conf
:
set skip on {lo0, enc0, enc1}
Avant d’appliquer les modifications :
# pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
Administration
Gérer plusieurs VPN : ajout, suppression, redémarrage
Gestion globale
Pour gérer plusieurs VPN, il est plus simple d’avoir un fichier par
VPN inclus dans /etc/iked.conf
:
include "/etc/iked/vpn1.conf"
include "/etc/iked/vpn2.conf"
Couper un seul VPN
On peut couper chaque VPN indépendamment en commentant le VPN
souhaité dans /etc/iked.conf
, puis en rechargeant la
configuration :
include "/etc/iked/vpn1.conf"
#include "/etc/iked/vpn2.conf"
# ikectl reload
La configuration /etc/iked.conf
sera rechargée, les VPN
toujours présents n’auront aucune coupure, et ceux commentés seront
supprimés.
Ajouter un nouveau VPN
De la même manière que pour couper un seul VPN, on peut en ajouter un
nouveau en l’ajoutant dans les fichiers inclus dans
/etc/iked.conf
et en exécutant à nouveau
ikectl reload
:
include "/etc/iked/vpn1.conf"
include "/etc/iked/vpn2.conf"
include "/etc/iked/newvpn.conf"
# ikectl reload
Redémarrer un seul VPN
Il suffit de jouer séquentiellement les actions pour couper puis ajouter un seul VPN.
Redémarrer tous les VPN
# ikectl reset all
# ikectl load /etc/iked.conf
Consulter les logs
# tail -f /var/log/daemon | grep iked
Voir les associations VPN
# ipsecctl -sa
Debug
Couper iked et le relancer :
# rcctl stop iked
# iked -dvvv -f /etc/iked.conf
FAQ
« ikev2_add_error: CHILD_SA_NOT_FOUND »
iked[14317]: spi=0xXXXXXX: ikev2_add_error: CHILD_SA_NOT_FOUND
Cette erreur arrive lorsque le peer et nous tentons de renouveler la phase 2 en même temps, créant un conflit (https://datatracker.ietf.org/doc/html/rfc5996#section-2.25). Le plus simple est de réduire ou d’augmenter la durée de vie de notre côté : si on la réduit, notre équipement sera toujours le premier à faire le renouvellement ; si on l’augmente, c’est le peer qui sera toujours le premier à faire le renouvellement ; évitant le conflit dans les 2 cas.
« sa_free: retransmit limit reached »
iked[73389]: spi=0x[…]: sa_free: retransmit limit reached
Un message a été retransmis à plusieurs reprises au peer, et la limite de retransmission de ce message a été atteinte sans recevoir de réponse. Le type de message transmis est indiqué dans les lignes précédentes :
iked[73389]: spi=0x[…]: retransmit 1 INFORMATIONAL req 8 peer 198.51.100.254:500 local 192.0.2.254:500
iked[73389]: spi=0x[…]: retransmit 2 INFORMATIONAL req 8 peer 198.51.100.254:500 local 192.0.2.254:500
iked[73389]: spi=0x[…]: retransmit 3 INFORMATIONAL req 8 peer 198.51.100.254:500 local 192.0.2.254:500
iked[73389]: spi=0x[…]: retransmit 4 INFORMATIONAL req 8 peer 198.51.100.254:500 local 192.0.2.254:500
iked[73389]: spi=0x[…]: retransmit 5 INFORMATIONAL req 8 peer 198.51.100.254:500 local 192.0.2.254:500
Ici, c’est un message INFORMATIONAL
, lié au DPD (Dead
Peer Detection). Si on ne reçoit pas de réponse, c’est soit que le peer
est down, soit que le DPD est désactivé chez le peer. Dans le 2e cas, il
faut alors le désactiver de notre côté également :
# cat iked.conf
set dpd_check_interval 0
Le VPN monte mais le trafic ne passe pas
Lorsque plusieurs phases 2 sont configurées, il arrive que seule une phase ne monte, et que le trafic sur une seule phase reste fonctionnel. Aucune solution n’a été trouvée pour l’instant.