MikroTik : éviter le routage asymétrique entre le FAI et le VPN
Marquer les connexions entrantes, forcer leurs réponses vers le même accès Internet et préserver le policy routing VPN sans casser les services publiés.
Un tunnel VPN et un accès Internet classique peuvent parfaitement cohabiter sur un MikroTik. La difficulté apparaît lorsqu’un serveur du réseau local est publié sur l’adresse du fournisseur d’accès alors qu’une règle de policy routing envoie une partie du trafic sortant dans le VPN. La requête arrive bien par le FAI, mais la réponse peut repartir par le tunnel. Le client voit alors deux chemins différents, et la connexion échoue.
Le symptôme est trompeur : le site, le serveur de messagerie, la caméra ou le NAS répond à certains clients, mais pas à d’autres. Le dst-nat semble correct, les ports sont ouverts et le service écoute. Pourtant, le premier paquet SYN entre par le WAN public tandis que le SYN-ACK emprunte le VPN. Le remède consiste à mémoriser l’origine de la connexion, puis à imposer le même accès Internet à tous ses paquets de retour.
Pourquoi une route par défaut ne suffit pas
RouterOS choisit une route pour chaque paquet. Si le routeur possède une règle qui dirige un serveur, un VLAN ou certaines destinations vers une table VPN, cette règle peut aussi s’appliquer à la réponse d’un service publié. Une route par défaut valide dans main n’empêche donc pas une règle mangle plus précise d’envoyer le paquet ailleurs.
Le suivi des connexions, ou conntrack, offre la mémoire nécessaire. Le premier paquet reçu sur le WAN est associé à une connexion. Une marque de connexion reste attachée aux deux sens de ce flux. Lorsque le serveur répond, RouterOS retrouve cette marque et peut appliquer une marque de routage qui sélectionne une table dédiée au FAI.
| Élément | Rôle | Durée |
|---|---|---|
connection-mark=from-isp | Identifie le flux entré par le FAI, dans les deux sens | Toute la durée de la connexion suivie |
routing-mark=via-isp | Demande une recherche de route dans la table via-isp | Le paquet traité |
Table via-isp | Contient le chemin de sortie imposé vers le FAI | Tant que la route est active |
Scénario et noms utilisés
Les commandes suivantes ciblent RouterOS 7. Adaptez les noms avant de les coller. Les adresses 192.0.2.0/24 appartiennent à un bloc réservé à la documentation et ne doivent pas être utilisées comme véritable configuration.
| Nom dans le guide | Signification | Exemple à remplacer |
|---|---|---|
ether1 | Interface physique reliée au FAI | WAN, SFP ou modem |
LAN | Liste d’interfaces internes | bridge, VLAN ou liste existante |
from-isp | Marque des connexions reçues du FAI | Nom libre et unique |
via-isp | Table de routage réservée au retour par le FAI | Nom libre et unique |
192.0.2.1 | Passerelle du FAI dans l’exemple statique | Passerelle réellement fournie |
Le serveur publié doit déjà fonctionner avec une règle dst-nat. Le guide ne modifie ni cette traduction, ni les règles qui sélectionnent le trafic autorisé à emprunter le VPN.
Avant de commencer : sauvegarde et observation
Une mauvaise marque de routage peut interrompre l’accès au routeur. Travaillez depuis le LAN, activez le Safe Mode dans WinBox ou avec Ctrl+X, puis exportez la configuration.
/export file=avant-routage-symetrique
/system backup save name=avant-routage-symetrique
Repérez ensuite les routes, les règles mangle et l’ordre du pare-feu. Une règle générale placée avant les nouvelles règles peut intercepter le paquet en premier.
/ip route print detail
/routing rule print detail
/ip firewall mangle print detail
/ip firewall filter print detail
/interface list member print
Vérifiez notamment que ether1 est bien le WAN du FAI et que les interfaces internes appartiennent à la liste LAN. Si vous utilisez déjà des marques nommées from-isp ou via-isp, choisissez d’autres noms.
1. Créer la table de routage du FAI
Dans RouterOS 7, une table personnalisée doit être déclarée avant d’être utilisée comme new-routing-mark. L’option fib permet son emploi pour le transfert effectif des paquets.
/routing table
add fib name=via-isp
Avec une passerelle statique, ajoutez une route par défaut dans cette table. Le suffixe @main indique que la passerelle doit être résolue à l’aide de la table principale.
/ip route
add dst-address=0.0.0.0/0 gateway=192.0.2.1@main \
routing-table=via-isp distance=1 \
comment="Symetrie: retour par le FAI"
Ne conservez pas 192.0.2.1 : remplacez-le par la passerelle réellement visible dans /ip route print detail. Si le WAN reçoit sa passerelle par DHCP, utilisez plutôt le script présenté plus loin.
2. Marquer les connexions entrantes
La première règle s’applique uniquement à une nouvelle connexion non encore marquée qui entre par le WAN du FAI. Elle pose from-isp sur la connexion entière. Elle ne décide pas encore de la route.
/ip firewall mangle
add chain=prerouting action=mark-connection \
in-interface=ether1 connection-state=new connection-mark=no-mark \
new-connection-mark=from-isp passthrough=yes \
comment="Symetrie: connexions recues du FAI"
Si plusieurs accès Internet sont actifs, créez une marque distincte par accès. Évitez une règle trop large fondée seulement sur in-interface-list=WAN : elle ne permettrait plus de savoir quel WAN doit porter la réponse.
3. Renvoyer les réponses du LAN par le FAI
La deuxième règle ne correspond qu’aux paquets qui reviennent depuis le LAN et appartiennent à une connexion marquée. Le premier paquet entrant, arrivé sur ether1, ne peut donc pas être envoyé accidentellement vers la table de retour. L’exclusion dst-address-type=!local évite aussi de marquer le trafic destiné au routeur lui-même.
/ip firewall mangle
add chain=prerouting action=mark-routing \
in-interface-list=LAN connection-mark=from-isp \
dst-address-type=!local new-routing-mark=via-isp passthrough=no \
comment="Symetrie: reponses LAN via le FAI"
Cette règle couvre les réponses d’un serveur derrière dst-nat. Les règles mangle de policy routing vers le VPN doivent venir après cette exception ou exclure explicitement connection-mark=from-isp.
4. Couvrir les services hébergés sur le routeur
Un service terminé sur le MikroTik lui-même — par exemple un serveur VPN — ne traverse pas prerouting au retour. Son paquet est créé localement et passe par la chaîne output. Ajoutez donc cette règle si le routeur répond lui-même à des connexions reçues du FAI.
/ip firewall mangle
add chain=output action=mark-routing \
connection-mark=from-isp dst-address-type=!local \
new-routing-mark=via-isp passthrough=no \
comment="Symetrie: reponses du routeur via le FAI"
Cette règle n’autorise aucun nouveau service. Le pare-feu input reste responsable des accès au routeur, et l’administration ne devrait pas être exposée directement sur Internet.
5. Empêcher FastTrack d’ignorer la table personnalisée
Dans RouterOS, FastTrack traite les paquets avec la table main. Une connexion qui doit utiliser via-isp ne doit donc pas entrer dans la règle FastTrack générale. Ajoutez une acceptation ciblée des connexions marquées et placez-la immédiatement avant la première règle fasttrack-connection.
/ip firewall filter
add chain=forward action=accept connection-mark=from-isp \
connection-state=established,related \
comment="Symetrie: exclure ces connexions de FastTrack"
Dans WinBox, déplacez cette règle au-dessus de FastTrack. En ligne de commande, affichez d’abord les numéros, puis utilisez move avec les numéros visibles plutôt que de supposer un emplacement.
/ip firewall filter print where action=fasttrack-connection
/ip firewall filter print where comment~"Symetrie"
WAN avec passerelle attribuée par DHCP
Une route personnalisée ne suit pas toujours automatiquement le changement de passerelle du client DHCP. RouterOS expose toutefois les variables bound et gateway-address au script d’événement du client. Le script suivant crée ou actualise uniquement la route portant le commentaire via-isp-dhcp : il ne touche pas aux autres routes.
Ouvrez IP → DHCP Client, éditez le client de ether1, puis collez ce code dans le champ Script de l’onglet avancé.
:local routeComment "via-isp-dhcp"
:local routeId [/ip route find where comment=$routeComment]
:if ($bound = 1) do={
:local nextHop ($"gateway-address" . "@main")
:if ([:len $routeId] = 0) do={
/ip route add dst-address=0.0.0.0/0 gateway=$nextHop \
routing-table=via-isp distance=1 comment=$routeComment
} else={
/ip route set $routeId gateway=$nextHop disabled=no
}
:log info ("Route via-isp mise a jour: " . $nextHop)
} else={
:if ([:len $routeId] > 0) do={
/ip route disable $routeId
}
:log warning "Route via-isp desactivee: bail DHCP absent"
}
Après l’enregistrement, renouvelez le bail pendant une fenêtre de maintenance ou réexécutez le script depuis l’interface. Vérifiez que la route apparaît active dans la table via-isp. Le script désactive cette route si le bail disparaît, plutôt que de conserver silencieusement une ancienne passerelle.
Cas d’un accès PPPoE
Avec PPPoE, la passerelle de la route peut être l’interface logique elle-même. Aucun script DHCP n’est alors nécessaire.
/ip route
add dst-address=0.0.0.0/0 gateway=pppoe-out1 \
routing-table=via-isp distance=1 \
comment="Symetrie: retour PPPoE par le FAI"
Remplacez pppoe-out1 par le nom réel de l’interface. Si le VPN utilise lui aussi PPPoE ou une interface dynamique, identifiez chaque entrée avec un commentaire unique.
Vérifier le résultat
Testez depuis un réseau réellement externe : connexion mobile, site distant ou sonde de supervision. Une requête lancée depuis le même LAN peut utiliser le hairpin NAT et ne valide pas le chemin Internet complet.
/routing table print
/ip route print detail where routing-table=via-isp
/ip firewall mangle print stats
/ip firewall filter print stats
/ip firewall connection print detail where connection-mark=from-isp
/log print where message~"via-isp"
Pour une connexion entrante réussie, les compteurs doivent raconter une histoire cohérente :
- la règle
mark-connectionaugmente lors de l’ouverture externe ; - la connexion apparaît avec
connection-mark=from-isp; - la règle
mark-routingdu LAN augmente quand le serveur répond ; - la route par défaut de
via-ispest active ; - la connexion établie n’est pas capturée par FastTrack.
Une capture limitée sur l’interface du FAI et celle du VPN permet de confirmer le résultat sans ambiguïté. Le paquet de réponse du serveur doit sortir par le FAI, pas par le tunnel.
/tool sniffer quick interface=ether1 ip-protocol=tcp
/tool torch interface=ether1
Filtrez si possible sur l’adresse ou le port du service testé afin d’éviter une capture trop volumineuse. Ne laissez pas un sniffer permanent sur un routeur en production.
Dépannage : les causes les plus fréquentes
| Symptôme | Cause probable | Contrôle |
|---|---|---|
| Aucune connexion n’est marquée | Mauvaise interface WAN ou règle placée après une règle qui arrête le traitement | Comparer in-interface et les compteurs mangle |
| La marque existe, mais la réponse passe dans le VPN | Règle VPN prioritaire ou interfaces LAN absentes de la liste | Contrôler l’ordre et /interface list member print |
La table via-isp est inactive | Passerelle erronée ou non résolue | Vérifier le suffixe @main et le bail DHCP |
| Le premier paquet fonctionne puis le flux casse | FastTrack reprend la connexion | Placer l’acceptation marquée avant FastTrack |
| Le routeur répond mal, mais le serveur fonctionne | Règle output absente | Ajouter la marque de routage pour les réponses locales |
| IPv4 fonctionne, IPv6 non | La configuration ne couvre que le pare-feu IPv4 | Construire une politique IPv6 séparée avec ses propres routes et règles |
Évitez aussi un réglage rp-filter=strict dans une architecture volontairement multichemin. Un filtrage de chemin inverse strict peut rejeter des paquets valides lorsque plusieurs tables et plusieurs sorties coexistent. Évaluez ce paramètre dans le contexte complet du pare-feu avant de le modifier.
Retirer proprement la configuration
Si le résultat n’est pas conforme, le Safe Mode peut annuler les changements de la session. Pour un retrait manuel, utilisez les commentaires et les noms uniques plutôt que des numéros de règles susceptibles d’avoir changé.
/ip firewall filter remove [find where comment="Symetrie: exclure ces connexions de FastTrack"]
/ip firewall mangle remove [find where comment~"Symetrie:"]
/ip route remove [find where comment="Symetrie: retour par le FAI"]
/ip route remove [find where comment="Symetrie: retour PPPoE par le FAI"]
/ip route remove [find where comment="via-isp-dhcp"]
/routing table remove [find where name=via-isp]
Si vous aviez ajouté le script au client DHCP, videz également son champ Script. N’effacez pas la table tant qu’une règle ou une route la référence encore.
Conclusion
La coexistence d’un FAI et d’un VPN ne pose pas de problème tant que chaque connexion conserve un chemin de retour prévisible. Dans RouterOS, la combinaison correcte est simple : une marque de connexion mémorise le WAN d’entrée, une marque de routage traite les réponses, et une table dédiée contient le chemin de sortie.
La fiabilité dépend surtout des détails : créer la table avant de l’utiliser, résoudre la passerelle dynamique, placer l’exception avant le policy routing VPN, écarter ces flux de FastTrack et vérifier les compteurs depuis un réseau extérieur. Une fois ces points contrôlés, les services publiés répondent par le FAI sans priver le reste du réseau de son tunnel VPN.
Discussion
Commentaires
Aucun commentaire pour le moment. Vous pouvez ouvrir la discussion avec une question ou un retour d’expérience.