Réseaux et cybersécurité 16 min de lecture

Router certains domaines dans un VPN avec MikroTik

Transformer les réponses DNS en liste d’adresses dynamique, marquer les connexions correspondantes et les envoyer dans une table VPN sans détourner tout le réseau.

Router un domaine dans un VPN paraît simple : il suffirait d’écrire son nom dans une règle. Mais un routeur ne transmet pas des noms, il transmet des paquets vers des adresses IP. Un même service peut changer d’adresse, utiliser plusieurs sous-domaines ou s’appuyer sur un CDN partagé avec d’autres sites. La configuration doit donc relier proprement la résolution DNS au policy routing.

RouterOS sait réaliser cette chaîne sans script externe. Une entrée DNS statique de type FWD peut reconnaître un domaine et ses sous-domaines, transmettre la requête à un résolveur, puis ajouter les adresses obtenues à une address-list dynamique. Le pare-feu marque ensuite les nouvelles connexions vers cette liste et une table dédiée les envoie dans le tunnel VPN.

Le principe en cinq étapes

  1. les clients du LAN utilisent le MikroTik comme serveur DNS ;
  2. une règle DNS FWD reconnaît le domaine demandé et, si nécessaire, ses sous-domaines ;
  3. les adresses IPv4 retournées alimentent la liste vpn-domains ;
  4. les nouvelles connexions vers cette liste reçoivent la marque domain-vpn ;
  5. la marque de routage via-vpn-domain sélectionne une table dont la route par défaut traverse le tunnel.
Schéma de la chaîne DNS, address-list, connection-mark et table VPN dans RouterOS
Le domaine n’est pas routé directement : sa résolution alimente une liste d’adresses, puis les connexions correspondantes sont dirigées vers la table du VPN.

Prérequis et noms utilisés

L’exemple suppose que le tunnel WireGuard wg-vpn est déjà établi et que son pair accepte les destinations nécessaires. Pour un tunnel utilisé comme sortie Internet, ses allowed-address incluent généralement 0.0.0.0/0. Le serveur distant doit aussi assurer le transfert et le NAT de sortie, ou connaître une route de retour vers le LAN.

NomRôleÀ adapter
wg-vpnInterface du tunnel déjà fonctionnelNom réel de l’interface VPN
LANListe des interfaces clientesBridge ou liste d’interfaces interne
vpn-domainsAdresses apprises par DNSNom libre et unique
domain-vpnMarque des connexions sélectionnéesNom libre et unique
via-vpn-domainTable de routage du tunnelNom libre et unique
service.exampleDomaine de documentationVotre domaine réel

La configuration présentée est volontairement limitée à IPv4. Si les clients obtiennent aussi une adresse IPv6 et résolvent des enregistrements AAAA, ils peuvent joindre le service hors de cette politique IPv4. Il faut alors concevoir une politique IPv6 équivalente ou empêcher ce chemin de contournement de façon explicite.

Avant de modifier le routage

Travaillez depuis le LAN, activez le Safe Mode avec Ctrl+X et exportez la configuration. Vérifiez également que le tunnel fonctionne déjà vers une adresse de test avant d’ajouter le routage par domaine.

/export file=avant-domaines-vpn
/system backup save name=avant-domaines-vpn
/interface wireguard print detail
/interface wireguard peers print detail
/ip route print detail
/ip firewall mangle print detail

N’utilisez pas la nouvelle règle pour diagnostiquer un tunnel encore inactif. Le DNS, la table de routage et le pare-feu ajoutent plusieurs couches ; le transport VPN doit être validé séparément.

1. Créer la table de routage du VPN

Dans RouterOS 7, la table doit exister avant d’être utilisée dans une action mark-routing. Le drapeau fib autorise son emploi pour le transfert des paquets.

/routing table
add fib name=via-vpn-domain

Ajoutez ensuite une route par défaut dans cette table. Avec une interface WireGuard point à point, l’interface peut servir de passerelle.

/ip route
add dst-address=0.0.0.0/0 gateway=wg-vpn \
    routing-table=via-vpn-domain distance=1 \
    comment="Domaines: sortie par le VPN"

Pour un autre type de tunnel, utilisez la passerelle adaptée à sa documentation. Contrôlez que la route porte le drapeau actif avant de poursuivre.

/routing table print
/ip route print detail where routing-table=via-vpn-domain

2. Faire utiliser le DNS du MikroTik aux clients

La liste dynamique ne se remplit que si le MikroTik voit la requête DNS. Activez les requêtes distantes, puis annoncez l’adresse LAN du routeur comme serveur DNS dans le réseau DHCP.

/ip dns
set allow-remote-requests=yes cache-size=8192KiB \
    address-list-extra-time=1h

/ip dhcp-server network
set [find where address="192.168.88.0/24"] dns-server=192.168.88.1

Remplacez le réseau et l’adresse du routeur. Une heure supplémentaire après le TTL réduit le risque qu’un client conserve encore une adresse alors que la liste du routeur vient de l’oublier. Évitez toutefois une valeur arbitrairement longue : sur un CDN qui change rapidement, une ancienne adresse pourrait rester routée inutilement dans le VPN.

Lorsque allow-remote-requests=yes est actif, le pare-feu input doit autoriser TCP et UDP 53 depuis le LAN et les refuser depuis le WAN. Le profil par défaut de RouterOS applique normalement cette séparation, mais vérifiez-la.

/ip firewall filter
add chain=input action=accept in-interface-list=LAN \
    protocol=udp dst-port=53 comment="DNS: clients LAN"
add chain=input action=accept in-interface-list=LAN \
    protocol=tcp dst-port=53 comment="DNS: clients LAN TCP"

Placez ces règles avant le rejet final de la chaîne input. N’ajoutez jamais une autorisation DNS sans limiter l’interface ou les adresses sources : un résolveur ouvert sur Internet peut être détourné pour des attaques par amplification.

3. Alimenter l’address-list avec DNS Static

Depuis RouterOS 7.16, une entrée statique de type FWD peut être utilisée avec un transfert DNS moderne et une liste d’adresses. Dans l’exemple, les requêtes pour service.example et ses sous-domaines sont transmises au résolveur 9.9.9.9. Les réponses alimentent automatiquement vpn-domains.

/ip dns static
add name=service.example type=FWD forward-to=9.9.9.9 \
    match-subdomain=yes address-list=vpn-domains \
    disabled=no \
    comment="Domaines: resolution et liste VPN"

Remplacez le domaine de documentation. Une entrée exacte avec match-subdomain=yes est préférable à une expression régulière très large : elle est plus lisible, plus rapide et limite les correspondances accidentelles.

Si le contenu est distribué par un CDN, le résolveur peut renvoyer une adresse différente selon le lieu d’où part la requête DNS. Pour obtenir une réponse cohérente avec la sortie du VPN, vous pouvez faire passer le résolveur choisi dans le tunnel, à condition que le VPN soit déjà établi et que cela ne crée pas de dépendance circulaire.

/ip route
add dst-address=9.9.9.9/32 gateway=wg-vpn routing-table=main \
    comment="DNS des domaines via le VPN"

Variante simple pour un seul nom

Pour un hôte unique sans sous-domaines, RouterOS accepte aussi un nom DNS directement dans une address-list. Le routeur crée les entrées dynamiques correspondantes.

/ip firewall address-list
add list=vpn-domains address=service.example \
    comment="Domaine unique vers le VPN"

Cette variante est pratique pour un petit nombre de noms connus. Elle devient moins claire dès qu’un service utilise plusieurs sous-domaines, des alias ou une chaîne de CDN. La méthode FWD avec match-subdomain=yes est alors plus souple, car elle apprend les adresses réellement demandées par les clients.

4. Marquer la connexion puis le routage

Marquer directement chaque paquet par sa destination fonctionne, mais une marque de connexion rend la logique plus robuste et facilite l’exclusion de FastTrack. La première règle mémorise les nouvelles connexions dont la destination appartient à vpn-domains. La seconde applique la table VPN à tous leurs paquets provenant du LAN.

/ip firewall mangle
add chain=prerouting action=mark-connection \
    in-interface-list=LAN dst-address-list=vpn-domains \
    dst-address-type=!local connection-state=new \
    connection-mark=no-mark new-connection-mark=domain-vpn \
    passthrough=yes comment="Domaines: marquer la connexion"

add chain=prerouting action=mark-routing \
    in-interface-list=LAN connection-mark=domain-vpn \
    dst-address-type=!local new-routing-mark=via-vpn-domain \
    passthrough=no comment="Domaines: router dans le VPN"

Placez ces règles avant les règles générales de policy routing. La condition in-interface-list=LAN évite de marquer le trafic qui arrive d’un autre WAN, et dst-address-type=!local protège l’accès aux adresses du routeur.

5. Exclure ces connexions de FastTrack

FastTrack ne traite correctement que la table main. Ajoutez une règle d’acceptation pour les connexions marquées et placez-la immédiatement avant la règle fasttrack-connection. Les autres connexions peuvent continuer à bénéficier de FastTrack.

/ip firewall filter
add chain=forward action=accept connection-mark=domain-vpn \
    connection-state=established,related \
    comment="Domaines: exclure du FastTrack"

Affichez les numéros de règles et déplacez l’acceptation au-dessus de FastTrack dans WinBox ou avec move. Il n’est pas nécessaire de désactiver FastTrack pour tout le réseau.

/ip firewall filter print where action=fasttrack-connection
/ip firewall filter print where comment~"Domaines"

6. Vérifier le NAT de sortie

Dans un VPN site à site correctement routé, le réseau distant peut posséder une route de retour vers le LAN et aucun NAT supplémentaire n’est nécessaire. Pour un tunnel utilisé comme sortie Internet, le pair distant attend souvent une adresse source du tunnel. Ajoutez alors un masquerade ciblé, et seulement si l’architecture l’exige.

/ip firewall nat
add chain=srcnat action=masquerade out-interface=wg-vpn \
    comment="Domaines: NAT vers la sortie VPN"

Le NAT local ne suffit pas à transformer un pair WireGuard en passerelle Internet : le système distant doit aussi autoriser le forwarding et assurer sa propre sortie. Vérifiez les deux extrémités.

Tester la chaîne complète

Videz le cache DNS du poste client, puis résolvez le domaine en interrogeant explicitement le MikroTik. La liste doit se remplir avant que les compteurs mangle puissent augmenter.

/ip dns cache flush
/ip dns cache all print where name~"service.example"
/ip firewall address-list print where list=vpn-domains
/ip firewall mangle print stats where comment~"Domaines"
/ip firewall connection print detail where connection-mark=domain-vpn
/ip route print detail where routing-table=via-vpn-domain

Depuis un client, ouvrez ensuite le service et observez le tunnel.

/interface monitor-traffic wg-vpn
/tool torch interface=wg-vpn

Vérifiez aussi une destination non sélectionnée : elle doit continuer à utiliser l’accès Internet normal. Le test est incomplet si tout le trafic passe accidentellement dans le VPN.

Pourquoi certains domaines restent difficiles

SituationConséquenceRéponse possible
Le client utilise DoH ou DoT externeLe MikroTik ne voit pas la résolution et la liste reste videGérer le DNS des appareils par politique, MDM ou pare-feu
Un CDN partage la même IP entre plusieurs sitesD’autres services peuvent suivre le VPNEmployer un proxy applicatif si une précision par nom est indispensable
Le service appelle des domaines annexesLa page s’ouvre partiellementIdentifier les noms requis dans les outils développeur et les journaux DNS
Le cache du client vit plus longtemps que la listeLe client conserve une IP que le routeur ne classe plusAjuster prudemment address-list-extra-time
IPv6 reste disponibleLe trafic AAAA peut éviter la politique IPv4Créer une politique IPv6 cohérente ou désactiver ce chemin de façon assumée
QUIC utilise UDP 443Un filtrage limité à TCP serait contournéMarquer toutes les connexions IP de la liste, comme dans ce guide

Une adresse apprise par DNS ne prouve pas qu’elle appartient exclusivement au domaine. À l’inverse, si une application contacte directement une adresse IP sans requête DNS visible, elle ne sera jamais ajoutée à la liste. Le routage par domaine est donc une association dynamique utile, pas une inspection du contenu TLS.

Retirer la configuration

Les commentaires et noms uniques permettent un retrait sans dépendre des numéros de règles.

/ip firewall filter remove [find where comment="Domaines: exclure du FastTrack"]
/ip firewall mangle remove [find where comment~"Domaines:"]
/ip firewall nat remove [find where comment="Domaines: NAT vers la sortie VPN"]
/ip dns static remove [find where comment="Domaines: resolution et liste VPN"]
/ip firewall address-list remove [find where comment="Domaine unique vers le VPN"]
/ip route remove [find where comment="DNS des domaines via le VPN"]
/ip route remove [find where comment="Domaines: sortie par le VPN"]
/routing table remove [find where name=via-vpn-domain]

Rétablissez aussi le serveur DNS annoncé par DHCP et la valeur précédente de address-list-extra-time si elles avaient été modifiées uniquement pour cette fonction.

Conclusion

RouterOS peut envoyer un domaine et ses sous-domaines dans un VPN sans maintenir manuellement une liste d’adresses. Le résolveur transforme les réponses DNS en address-list, la marque de connexion mémorise la décision et la table via-vpn-domain sélectionne le tunnel. Le reste du réseau conserve sa route habituelle.

La réussite dépend de trois contrôles : les clients doivent réellement interroger le MikroTik, les connexions marquées doivent rester hors FastTrack et la sortie VPN doit disposer du routage de retour ou du NAT approprié. Pour les services complexes, partagés ou fortement distribués, un proxy applicatif reste plus précis qu’une décision fondée uniquement sur les adresses IP.

Références techniques

À propos de l’auteur

Jeremy Kraft administre les infrastructures et les services auto-hébergés de l’IBCSC. Ces guides reprennent des configurations réellement déployées, revérifiées avant publication.

Discussion

Commentaires

0

Aucun commentaire pour le moment. Vous pouvez ouvrir la discussion avec une question ou un retour d’expérience.

Vous avez un compte ? Se connecter

Texte simple, 2 000 caractères maximum. Les nouveaux commentaires sont modérés. Votre nom sera affiché avec le commentaire. Aucune adresse e-mail n’est demandée ; seule une empreinte non réversible de votre adresse IP est conservée pour lutter contre le spam.