This page is also available in English.

Aujourd’hui, je vous embarque dans une petite aventure que j’ai vécue récemment dans mon LAB perso. Comme beaucoup d’entre nous, j’aime expérimenter, tester, et parfois… me compliquer un peu la vie pour apprendre de nouvelles choses. Mon dernier défi : mettre en place un tunnel VPN IPSec site-à-site un peu particulier entre ma passerelle UniFi et un serveur Ubuntu distant, le tout en mode route-based et avec la petite difficulté supplémentaire que mon serveur Ubuntu se cache derrière un NAT.

Pourquoi diable un VPN Site-à-Site ? Le contexte de mon LAB

Tout a commencé par un besoin assez simple : certaines de mes machines virtuelles et conteneurs sur mon réseau principal (Site A), géré par une passerelle UniFi (UniFi OS), avaient besoin d’une seconde adresse IP publique pour sortir sur Internet. Mon Site A, c’est un petit monde avec plusieurs sous-réseaux (de 10.0.0.0/16 à 10.3.0.0/16).

J’avais exploré plusieurs pistes :

  1. Le WAN2 physique ? Pas possible, une seule fibre arrive à la maison. J’avais bien un bricolage à base de MikroTik CHR virtualisé qui injectait une connexion L2TP, mais franchement, ça manquait d’élégance et j’aimais pas l’idée que mes paquets fassent des détours inutiles.
  2. Le client VPN intégré à UniFi ? WireGuard ou OpenVPN, c’est sympa. J’ai testé avec un serveur WireGuard sur mon site distant (Site B). Ça marchait pour faire sortir mes machines du Site A via l’IP du Site B. Mais voilà, la curiosité m’a piqué : et si je voulais que mes conteneurs LXC sur le serveur Ubuntu du Site B puissent attaquer des services sur mon Site A ? L’interface UniFi ne me laissait pas configurer les routes comme je le voulais pour cette communication bidirectionnelle. Frustrant !

Restait donc la dernière option avant d’envisager des solutions plus radicales : le bon vieux VPN site-à-site. UniFi OS propose IPSec ou OpenVPN. Ayant une petite aversion personnelle pour OpenVPN (souvent gourmand et pas le plus véloce), mon choix s’est naturellement porté sur IPSec.

L’objectif était donc clair :

  • Permettre à certaines machines du Site A de surfer via l’IP publique du Site B.
  • Ouvrir la porte pour que les machines du Site B (sur Ubuntu) puissent discuter avec celles du Site A.
  • Et en bonus, pouvoir faire de la redirection de port depuis l’IP du Site B vers des services du Site A.

Le petit “twist” : sur le Site B, je ne contrôle pas la passerelle Internet. Mon point de terminaison VPN devait être mon serveur Ubuntu (10.100.0.2), lui-même derrière le NAT de la box du FAI. Ça promettait d’être intéressant !

UniFi et StrongSwan

Avant de plonger tête baissée dans la configuration, un petit détail qui a son importance : UniFi OS (en tout cas la v4.x basée sur Debian 11) utilise en arrière-plan une implémentation bien connue du monde open-source pour IPSec : StrongSwan (dans une version autour de 5.9.x à l’heure où j’écris). L’interface graphique, si jolie soit-elle, ne fait que générer des fichiers de configuration standards pour StrongSwan. Savoir ça, c’est déjà comprendre un peu mieux comment la bête fonctionne et comment configurer l’autre bout du tunnel.

Le dilemme : Policy-Based ou Route-Based ?

IPSec peut décider quel trafic chiffrer de deux manières principales :

  1. Policy-Based : On définit des règles strictes : tel réseau source peut parler à tel réseau destination via le tunnel. Simple en apparence, mais vite limité si on veut faire du routage un peu plus fin.
  2. Route-Based : On crée une interface réseau virtuelle dédiée au tunnel (une VTI, Virtual Tunnel Interface, ou via XFRM sous Linux). Ensuite, c’est le routage classique du système qui décide quel trafic envoyer dans cette interface. Tout ce qui y entre est chiffré. Beaucoup plus souple !

J’avoue, j’ai d’abord tenté la facilité avec le mode policy-based côté Ubuntu. Grosse déception : impossible de faire fonctionner correctement le routage du trafic Internet (0.0.0.0/0) depuis le Site A vers le Site B. Ça coinçait méchamment. Même si UniFi était configuré en route-based, il semblait attendre une configuration de routage compatible de l’autre côté pour que tout circule bien, surtout le trafic retour.

Pas le choix, il fallait se retrousser les manches et passer en mode route-based des deux côtés. Ça signifiait configurer StrongSwan avec une VTI sur Ubuntu, le tout derrière NAT… Challenge accepté !

Les prérequis

Avant de mettre les mains dans le cambouis, vérifions qu’on a tout ce qu’il faut :

  • Une passerelle UniFi sous UniFi OS v4.1 ou plus récent.
  • Un serveur Linux, ici Ubuntu 24.04.2 LTS, avec StrongSwan et ses plugins installés (sudo apt update && sudo apt install strongswan strongswan-pki libstrongswan-extra-plugins).
  • Les accès administrateur sur les deux machines, évidemment.
  • Des adresses IP publiques fixes (ou des noms DNS dynamiques bien configurés) pour chaque site.
  • Pare-feu : C’est crucial ! Il faut ouvrir les bons ports et protocoles sur l’IP publique de chaque site (directement sur la passerelle UniFi au Site A, et sur la passerelle du Site B avec redirection vers l’IP locale 10.100.0.2 du serveur Ubuntu) :
    • UDP/500 : Pour l’échange initial des clés (ISAKMP / IKE).
    • UDP/4500 : Pour le NAT-Traversal (NAT-T), qui encapsule IPSec dans de l’UDP quand un des participants est derrière NAT.
    • Protocole IP 50 (ESP) : C’est lui qui transporte les données chiffrées. Note : Avec NAT-T actif, ESP passe dans l’UDP/4500, donc ouvrir le protocole 50 n’est pas toujours strictement nécessaire, mais dans le doute, mieux vaut l’autoriser.

L’Architecture réseau cible

Pour y voir plus clair, voici à quoi ressemble notre installation :

AS2027
80.67.160.0/19
SITE A
.1
.2
.1
.2
45.13.104.0/22
AS20766
.1
.2
10.100.0.0/16
enp0s6
.1
.2
192.168.255.0/30
vti0
10.0.0.0/16
10.1.0.0/16
10.2.0.0/16
10.3.0.0/16
SITE B
10.101.0.0/16
.1
VMs

Site A

  • IP public : 80.67.160.2/19
  • 4 sous-réseaux :
    • 10.0.0.0/16
    • 10.1.0.0/16
    • 10.2.0.0/16
    • 10.3.0.0/16
  • IP de tunnel : 192.168.255.1/30

Site B

  • IP Public : 45.13.104.2/22
  • 2 sous-réseaux :
    • 10.100.0.0/16
    • 10.101.0.0/16
  • IP Locale du serveur VPN : 10.100.0.2/16
  • IP de tunnel : 192.168.255.2/30

Je n'ai malheureusement pas la chance d'avoir les IPs finissant en .2 attribué sur chacun des sites et l'ensemble des IPs présenté ici sont inspiré de faits réels

La configuration : Au cœur des tunnels

1. Côté Site A : La passerelle UniFi

Direction l’interface Web d’UniFi Network Application > Settings > VPN > Site-to-Site VPN :

30Route DistanceMaximum Transmission UnitAutoBytes1419Remote Authentication IDAuto45.13.104.2Local Authentication IDAuto80.67.160.2Perfect Forward Secrecy (PFS)AES-256EncryptionSHA256Hash14DH Group3600LifetimeESPAES-256EncryptionSHA256Hash14DH Group28800LifetimeIKEIKEv2Key Exchange VersionAutoManualAdvancedRemote Network(s)DynamicStaticSubnet10.100.0.0/1610.101.0.0/16EditAdd MultipleAddTunnel IP192.168.255.1IPv4 Address30NetmaskVPN MethodRoute BasedPolicy BasedNetwork ConfigurationRemote IP / Hostname45.13.104.280.67.160.2 (WAN1)Enter IP Address manuallyLocal IPPre-Shared KeybmcCJdIBH1yi6JLOckjJhDHdYACBfvwdUnifi - Ubuntu VPNNameOpenVPNIPsecVPN Type

On sauvegarde. UniFi OS va alors traduire tout ça en fichiers de configuration pour StrongSwan dans les entrailles du système. Ce qu’il faut retenir, c’est qu’en mode route-based, UniFi utilise des mark (marques) pour identifier les paquets du tunnel et les router correctement, sans que StrongSwan n’ait à installer de routes lui-même (install_routes = no).

2. Côté Site B : Le Serveur Ubuntu et StrongSwan

Ici, on sort l’éditeur de texte et on configure tout à la main.

a) Configuration générale de StrongSwan

Premier fichier, on s’assure que StrongSwan charge bien tous ses outils modernes.

/etc/strongswan.conf
charon {
  # On laisse le système gérer les routes, pas StrongSwan directement
  install_routes = no
  routing_table = 0
 
  # Options standard
  delete_rekeyed = yes
  make_before_break = no
 
  # Très important : charger les plugins !
  load_modular = yes
  plugins {
    include strongswan.d/charon/*.conf
  }
 
  # Pour le débogage, on peut activer les logs ici si besoin
  # filelog { ... }
}

Le load_modular = yes est crucial pour que les plugins comme kernel-netlink (qui parle au noyau pour VTI/XFRM) et updown (qui lance notre script magique) soient actifs. Sans ça, on risque de se retrouver avec des méthodes dépassées.

b) Fichier principal IPSec

Celui-ci est très simple, il dit juste où trouver les configurations des tunnels.

/etc/ipsec.conf
config setup
  # Logs de débogage pour charon (mettre à 0 en prod)
  charondebug="ike 0, knl 0, cfg 0, net 0"
 
# On inclut toutes les configs du répertoire tunnels
include /etc/ipsec.d/tunnels/*.config

c) Le secret partagé

D’abord, le fichier global qui inclut les secrets spécifiques :

/etc/ipsec.secrets
include /etc/ipsec.d/tunnels/*.secret

Puis, le fichier contenant notre clé secrète pour ce tunnel précis :

/etc/ipsec.d/tunnels/unifi.secret
# Format: <ID Local> <ID Distant> : PSK "VotreCleSecreteSuperSolide"
 
# On utilise les IPs publiques comme identifiants pour la négociation IKE
45.13.104.2 80.67.160.2 : PSK "bmcCJdIBH1yi6JLOckjJhDHdYACBfvwd"

Attention, les identifiants ici (45.13.104.2 et 80.67.160.2) doivent correspondre aux leftid et rightid définis dans la configuration de la connexion juste après.

d) La configuration de la Connexion

C’est le cœur du réacteur côté Ubuntu.

/etc/ipsec.d/tunnels/unifi.config
conn unifi-to-ubuntu  # Un nom pour notre connexion
    ## Les bases ##
    auto=start             # Démarrer le tunnel dès que StrongSwan se lance
    authby=secret          # On utilise notre clé secrète (PSK)
    type=tunnel            # C'est un tunnel IPSec
 
    ## Détection de l'autre bout (DPD) ##
    dpdaction=restart      # Si UniFi ne répond plus, on relance la connexion
    dpddelay=30s           # On vérifie toutes les 30s
    dpdtimeout=120s        # On attend 120s avant de déclarer forfait
 
    ## Les adresses ##
    # 'left' est l'IP d'écoute locale (notre IP privée)
    left=10.100.0.2
    # 'right' est l'IP destination (l'IP publique d'UniFi)
    right=80.67.160.2
    # 'mark' : La marque magique ! Doit être identique à la 'key' dans le script VTI.
    # C'est ce qui lie la politique IPSec à l'interface virtuelle dans le noyau.
    mark=6
 
    ## Le trafic à chiffrer (Traffic Selectors) ##
    # 'leftsubnet' : Quel trafic venant du Site B peut passer par le tunnel ?
    # 0.0.0.0/0 = tout trafic initié localement peut potentiellement l'utiliser.
    # On pourrait restreindre à 10.100.0.0/16,10.101.0.0/16 si besoin.
    leftsubnet=0.0.0.0/0
 
    # 'rightsubnet' : Quels réseaux distants (Site A) sont joignables via ce tunnel ?
    # !! Important !! Contrairement à UniFi, mettre 0.0.0.0/0 ici m'a causé des soucis.
    # En spécifiant les réseaux exacts, ça fonctionne nickel.
    rightsubnet=192.168.255.0/30,10.0.0.0/16,10.1.0.0/16,10.2.0.0/16,10.3.0.0/16
 
    fragmentation=yes      # On autorise la fragmentation, ça peut aider
    compress=no            # La compression IPSec est rarement utile
 
    ## Phase 1 (IKEv2) : Négociation sécurisée ##
    # 'leftid' : Comment notre serveur Ubuntu s'identifie (son IP publique, même si 'left' est privée à cause du NAT)
    leftid=45.13.104.2
    # 'rightid' : Comment UniFi s'identifie (son IP publique)
    rightid=80.67.160.2
    keyexchange=ikev2      # On utilise IKEv2
    aggressive=no          # Surtout pas de mode agressif (vieux et moins sûr)
    # La recette crypto IKE (doit être IDENTIQUE à celle d'UniFi)
    ike=aes256-sha256-modp2048! # Chiffrement-Intégrité-GroupeDH
    reauth=yes             # On permet la ré-authentification
    ikelifetime=28800s     # Durée de vie de la clé IKE (8h)
 
    ## Phase 2 (ESP) : Chiffrement des données ##
    # La recette crypto ESP (doit aussi être IDENTIQUE à UniFi et IKE ici)
    esp=aes256-sha256-modp2048! # Chiffrement-Intégrité-GroupeDH(PFS)
    rekey=yes              # On renouvelle la clé ESP régulièrement
    keylife=3600s          # Durée de vie de la clé ESP (1h)
    keyingtries=%forever   # On réessaie sans fin si ça échoue
    # forceencaps=no       # Forcer NAT-T ? Bonne surprise, 'no' a suffi, la détection auto a marché.
                           # Mettre 'yes' si vous avez des soucis de NAT.
 
    ## Le script magique ##
    # Ce script sera lancé quand le tunnel monte ou descend
    leftupdown=/etc/ipsec.d/vti-up-down

Quelques points à retenir ici :

  • La différence entre left (IP privée locale) et leftid (IP publique d’identification) est typique du NAT.
  • Le mark=6 est le lien vital entre cette configuration IPSec et l’interface vti0 qu’on va créer.
  • Le rightsubnet spécifique (pas 0.0.0.0/0) était la clé pour que StrongSwan crée les bonnes politiques XFRM et que le routage fonctionne sur Ubuntu. Mystères des implémentations…
  • Le leftupdown pointe vers notre script qui va orchestrer toute la partie réseau.

e) Le script Chef d’Orchestre

Ce script Bash est celui qui va vraiment configurer le réseau quand le tunnel IPSec monte ou descend. N’oubliez pas de le rendre exécutable : sudo chmod +x /etc/ipsec.d/vti-up-down.

/etc/ipsec.d/vti-up-down
#!/bin/bash
# Script pour gérer l'interface VTI et le routage pour StrongSwan
 
# Fonction pour afficher des messages de debug (utiles dans /var/log/syslog ou strongswan.log)
debug_echo() { echo "[VTI SCRIPT DEBUG] $1" >&2; }
 
# --- Nos variables (adaptez WAN_IF !) ---
VTI_IF="vti0"                 # Nom de notre interface tunnel virtuelle
WAN_IF="enp0s6"               # !! Adaptez au nom de VOTRE interface WAN sur Ubuntu !!
LOCAL_VTI_TUNNEL_ENDPOINT="10.100.0.2" # IP privée de notre serveur Ubuntu
REMOTE_TUNNEL_ENDPOINT="80.67.160.2" # IP publique de la passerelle UniFi
MARK="6"                      # La même marque que dans unifi.config !
MTU="1419"                    # MTU pour VTI (souvent un peu moins de 1500 avec IPSec)
TUNNEL_NETWORK="192.168.255.0/30" # Le réseau du tunnel
LOCAL_TUNNEL_IP="192.168.255.2/30" # IP de vti0 sur Ubuntu
REMOTE_TUNNEL_IP="192.168.255.1"   # IP de vti0 côté UniFi
REMOTE_NETWORKS="10.0.0.0/16 10.1.0.0/16 10.2.0.0/16 10.3.0.0/16" # Les réseaux du Site A
 
debug_echo "Script démarré. Action: ${PLUTO_VERB}" # PLUTO_VERB contient up-client, down-client etc.
 
case "${PLUTO_VERB}" in
    up-client|up-host) # Le tunnel monte !
        debug_echo "--- Phase UP ---"
 
        # 1. Créer l'interface VTI : la magie opère ici !
        # 'ip tunnel add ... mode vti key ${MARK}' lie l'interface à la marque IPSec.
        debug_echo "Création VTI: ip tunnel add ${VTI_IF} local ${LOCAL_VTI_TUNNEL_ENDPOINT} remote ${REMOTE_TUNNEL_ENDPOINT} mode vti key ${MARK}"
        ip tunnel add ${VTI_IF} local ${LOCAL_VTI_TUNNEL_ENDPOINT} remote ${REMOTE_TUNNEL_ENDPOINT} mode vti key ${MARK}
 
        # 2. Réglages sysctl recommandés pour VTI
        debug_echo "Configuration sysctl pour ${VTI_IF}"
        sysctl -w net.ipv4.conf.${VTI_IF}.disable_policy=1 # Important pour le marquage
 
        # 3. Donner une IP à notre VTI
        debug_echo "Assignation IP: ip addr add ${LOCAL_TUNNEL_IP} dev ${VTI_IF}"
        ip addr add ${LOCAL_TUNNEL_IP} dev ${VTI_IF}
 
        # 4. Activer l'interface VTI
        debug_echo "Activation interface: ip link set ${VTI_IF} up mtu ${MTU}"
        ip link set ${VTI_IF} up mtu ${MTU}
 
        # 5. Ajouter les routes vers le Site A via la VTI
        # Tout trafic vers ces réseaux passera par vti0 -> marquage -> chiffrement IPSec
        for net in ${REMOTE_NETWORKS}; do
            debug_echo "Ajout route: ip route add ${net} dev ${VTI_IF}"
            ip route add ${net} dev ${VTI_IF}
        done
 
        # 6. Activer le routage sur le serveur Ubuntu (si pas déjà fait)
        debug_echo "Activation IP Forwarding"
        sysctl -w net.ipv4.ip_forward=1
 
        # 7. Configurer le NAT (Masquerade) pour le trafic venant du Site A via VTI et sortant sur Internet
        # C'est ce qui permet aux machines du Site A d'utiliser l'IP du Site B !
        debug_echo "Configuration NAT pour ${REMOTE_NETWORKS} sortant par ${WAN_IF}"
        for net in ${REMOTE_NETWORKS}; do
            # On ajoute la règle seulement si elle n'existe pas déjà
            iptables -t nat -C POSTROUTING -s ${net} -o ${WAN_IF} -j MASQUERADE &>/dev/null || \
            (debug_echo "Ajout règle NAT pour ${net}"; iptables -t nat -A POSTROUTING -s ${net} -o ${WAN_IF} -j MASQUERADE)
        done
        # On fait pareil pour le réseau du tunnel lui-même, au cas où
        iptables -t nat -C POSTROUTING -s ${TUNNEL_NETWORK} -o ${WAN_IF} -j MASQUERADE &>/dev/null || \
        (debug_echo "Ajout règle NAT pour ${TUNNEL_NETWORK}"; iptables -t nat -A POSTROUTING -s ${TUNNEL_NETWORK} -o ${WAN_IF} -j MASQUERADE)
 
        # 8. Autoriser le trafic à traverser le pare-feu (chaîne FORWARD)
        # Permettre au trafic d'entrer PAR vti0 et de sortir PAR vti0
        iptables -C FORWARD -i ${VTI_IF} -j ACCEPT &>/dev/null || \
        (debug_echo "Ajout règle FORWARD entrant depuis ${VTI_IF}"; iptables -A FORWARD -i ${VTI_IF} -j ACCEPT)
        iptables -C FORWARD -o ${VTI_IF} -j ACCEPT &>/dev/null || \
        (debug_echo "Ajout règle FORWARD sortant vers ${VTI_IF}"; iptables -A FORWARD -o ${VTI_IF} -j ACCEPT)
 
        debug_echo "--- Phase UP terminée ---"
        ;;
 
    down-client|down-host) # Le tunnel tombe ! On nettoie tout.
        debug_echo "--- Phase DOWN ---"
        # On fait les opérations inverses, en ignorant les erreurs si ça n'existe plus
 
        # 1. Supprimer règles FORWARD
        iptables -D FORWARD -i ${VTI_IF} -j ACCEPT &>/dev/null || true
        iptables -D FORWARD -o ${VTI_IF} -j ACCEPT &>/dev/null || true
 
        # 2. Supprimer règles NAT
        for net in ${REMOTE_NETWORKS}; do
            iptables -t nat -D POSTROUTING -s ${net} -o ${WAN_IF} -j MASQUERADE &>/dev/null || true
        done
        iptables -t nat -D POSTROUTING -s ${TUNNEL_NETWORK} -o ${WAN_IF} -j MASQUERADE &>/dev/null || true
 
        # 3. Supprimer les routes
        for net in ${REMOTE_NETWORKS}; do
            ip route del ${net} dev ${VTI_IF} &>/dev/null || true
        done
 
        # 4. Désactiver et supprimer l'interface VTI
        ip link set ${VTI_IF} down || true
        ip tunnel del ${VTI_IF} || true
 
        debug_echo "--- Phase DOWN terminée ---"
        ;;
esac
 
debug_echo "Script terminé."
exit 0

Ce script est vraiment le cœur de l’automatisation côté Ubuntu. Il crée l’interface vti0 en la liant à la mark=6, configure l’IP, monte l’interface, ajoute les routes vers le Site A, et met en place le NAT (Masquerade) et les règles de pare-feu nécessaires pour que le trafic puisse circuler et que les machines du Site A puissent sortir sur Internet via le Site B.

f) On applique et on démarre !

Après avoir créé/modifié tous ces fichiers :

# On dit à StrongSwan de relire ses configurations
sudo ipsec reload
 
# On redémarre le service pour être sûr et pour lancer les connexions auto=start
sudo systemctl restart strongswan-starter # ou juste strongswan selon votre système voir rien comme moi sur Ubuntu
 
# On vérifie que le service tourne bien
sudo systemctl status strongswan-starter

Analyse : Les petits “Aha!” et les mystères

Alors, qu’est-ce qu’on a appris dans cette aventure ?

  • Le 0.0.0.0/0 d’UniFi vs Ubuntu : Le fait qu’UniFi utilise leftsubnet=0.0.0.0/0 et rightsubnet=0.0.0.0/0 dans sa conf StrongSwan mais que ça ne marche pas si on copie ça tel quel sur Ubuntu avec une VTI manuelle reste un peu mystérieux. UniFi OS a sûrement sa propre logique de routage interne qui s’appuie sur la mark pour ne chiffrer que le trafic pertinent. Sur Ubuntu, spécifier les rightsubnet exacts a été la solution pour que les politiques XFRM soient créées correctement avec la mark=6 et que le noyau sache quoi faire.
  • VTI et XFRM : L’interface VTI est une abstraction pratique au-dessus du framework XFRM du noyau Linux. Elle nous donne une interface réseau classique (vti0) sur laquelle on peut router. La commande ip tunnel add ... key ${MARK} fait le lien entre cette interface et la marque IPSec, qui elle-même est liée aux politiques de chiffrement définies dans StrongSwan. C’est un trio gagnant !
  • LibreSwan, la fausse piste : J’avais aussi tenté LibreSwan, une alternative à StrongSwan, qui propose un support VTI un peu plus intégré dans sa config. Mais impossible de faire correspondre les propositions de chiffrement avec l’UniFi (NO_PROPOSAL_CHOSEN). Ça montre bien qu’il faut une correspondance parfaite des algos IKE et ESP entre les deux bouts.
  • load_modular = yes : Ne pas oublier cette ligne dans strongswan.conf ! Sans elle, StrongSwan risque de ne pas charger les plugins modernes et de retomber sur des méthodes moins flexibles (type interface TUN ipsec0 monté par défault…).
  • NAT-Traversal : Bonne surprise, le NAT-T a fonctionné automatiquement (forceencaps=no) malgré mon serveur Ubuntu derrière le NAT. StrongSwan et UniFi ont bien détecté la situation et sont passés en encapsulation UDP/4500.
  • La mark : Je le redis, la cohérence de la mark entre la config conn de StrongSwan et la commande ip tunnel add ... key est absolument vitale. C’est la colle qui tient tout ensemble.

Vérifications : Est-ce que ça marche ?

Le moment de vérité ! Comment savoir si notre tunnel est bien établi et fonctionnel ?

  1. Statut StrongSwan (sur Ubuntu) :

    sudo ipsec status
    # Cherchez la ligne "ESTABLISHED" pour votre connexion unifi-to-ubuntu.
     
    sudo ipsec statusall
    # Pour les détails : les algos négociés, les SPIs, les octets transférés...
    # Vérifiez que les réseaux listés après "===" correspondent bien à votre rightsubnet.
  2. Interface VTI et Routage (sur Ubuntu) :

    ip link show vti0
    # Doit être UP, avec le bon MTU.
     
    ip addr show vti0
    # Doit afficher l'IP 192.168.255.2/30.
     
    ip route show dev vti0
    # Doit lister les routes vers les réseaux 10.x.x.x/16 du Site A.
  3. Politiques XFRM (sur Ubuntu) :

    sudo ip xfrm policy
    # Vérifiez les politiques 'dir out' vers les réseaux du Site A : elles doivent avoir la 'mark 0x6'.
    # Vérifiez aussi les politiques 'dir in' et 'dir fwd' venant de ces réseaux.
     
    sudo ip xfrm state
    # Doit montrer les associations de sécurité ESP actives.
  4. Statut VPN (sur UniFi) :

    • L’interface graphique d’UniFi devrait ==afficher un beau cercle vert à côté de votre VPN site-to-site.==
    • En SSH sur la passerelle UniFi, les commandes ipsec status, ip link, ip route peuvent aussi donner des infos.
  5. Les tests finaux (le plus important !) :

    • Depuis Ubuntu (Site B), essayez de ping une machine du Site A (ex: ping 10.0.1.10).
    • Depuis une machine du Site A, essayez de ping l’IP tunnel d’Ubuntu (ping 192.168.255.2) ou son IP locale (ping 10.100.0.2).
    • Le test ultime : Sur une machine du Site A, configurez temporairement sa passerelle par défaut pour pointer vers l’IP tunnel d’Ubuntu (192.168.255.2). Puis, vérifiez votre IP publique de sortie (par exemple avec curl ipinfo.io). Vous devriez voir l’IP publique du Site B (45.13.104.2) ! Si c’est le cas, le routage et le NAT fonctionnent ! (N’oubliez pas de remettre la passerelle par défaut après le test, ou mieux, configurez du routage basé sur la source/politique sur votre passerelle UniFi pour ne router que certaines machines via le tunnel).

Conclusion : Mission accomplie !

Et voilà ! Ce n’était pas une mince affaire, surtout avec le NAT et les subtilités du mode route-based entre UniFi OS et une configuration StrongSwan/VTI manuelle sur Ubuntu. Mais quelle satisfaction quand on voit les paquets circuler comme on le souhaite !

La clé a vraiment été de comprendre l’interaction entre StrongSwan, le marquage des paquets (mark/key), l’interface VTI, et le routage système, sans oublier l’importance cruciale de faire correspondre les paramètres cryptographiques et d’adapter la configuration rightsubnet côté Ubuntu.

Maintenant, j’ai un tunnel robuste et flexible qui me permet non seulement d’interconnecter mes sites mais aussi de choisir finement comment mon trafic sort sur Internet. J’espère que ce partage d’expérience pourra aider certains d’entre vous qui se lanceraient dans une configuration similaire.