Pas à pas complet pour configurer un switch Mikrotik comme routeur avec une connexion Internet à Orange/Sosh.
À l’origine, j’avais un switch Mikrotik CRS309-1G-8+S+, et un router Edgerouter ER-4 qui, s’il a ce qu’il faut sous le capot, n’est plus maintenu par Ubiquiti. Et j’en avais franchement marre de me taper la WebUI pourrie ou le shell Vyatta. En regardant les spécifications techniques du Mikrotik, je me suis dit qu’il pourrait endosser le rôle de routeur aussi. Et c’est le cas :), du moins jusqu’à un certain point.

Capture de l’authentification Livebox

Pour reproduire le comportement de la Livebox, le plus simple est de capturer ce qu’elle fait. Pour cela, nous aurons besoin d’une machine Linux et un switch avec des ports Ethernet et SFP capable de faire du port mirroring. Pour avoir testé, je déconseille fortement de faire la capture sous Windows, en effet certain dongles Ethernet font tout simplement disparaître l’en-tête VLAN (802.1Q). Lorsqu’on débug du L4 ou L7, c’est pas grave, mais Orange utilise cet en-tête pour prioriser le traffic d’initialisation entre la box et le BNG (Broadband Network Gateway, le premier routeur auquel est connecté la box).

architecture-beta
    service fiber_wall_socket(material-symbols-light:cable)[Fibre prise murale]
    service linux_capture(devicon:kalilinux)[Linux box]
    service livebox(material-symbols-light:router-outline)[Livebox]
    service switch(tabler:switch-2)[Switch]

    fiber_wall_socket:L --> R:switch
    linux_capture:B --> T:switch
    livebox:R --> L:switch

Branchez le port WAN Ethernet de la Livebox au switch sur un port “A”.
Branchez le cable fibre SC/APC avec son module SFP sur le switch sur un port “B”.
Branchez la linux box sur un port “C”.
Configurez les ports A et B en taggé pour le VLAN 832.
Configurez le port mirroring avec :

  • le port C en destination
  • le port B en source tx/rx

Sur mon switch, j’ai configuré les ports 23 à 26 pour accepter des paquets taggés avec le vlan id 832, et refuser tout le reste (en utilisant un vlan inutilisé en access) Configuration des ports du switch sur le vlan 832

La Linux box est branchée sur le port 13, et l’ONT sur le port 25. Configuration du port mirroring

Il n’y aura plus qu’à (dans l’ordre) :

  • allumer la Livebox
  • lancer la capture sur la Linux box avec tcpdump
  • brancher la fibre (ou si vous êtes flemmard, vous pouvez tout brancher et shut/no shut le port via l’interface du switch)

Laissez tourner 5 minutes, le temps que la Livebox se connecte au réseau, fasse ses petites affaires et vous êtes bon pour arrêter la capture et sauvegarder le fichier de capture précieusement. Il contient tout le nécessaire pour reproduire la configuration sur le Mikrotik.

tcpdump -i interface -Us0 -w - udp port 67 or arp or icmpv6 or ip6 and udp port 547 | tee /tmp/orange.pcap | tcpdump -evr -

Le setup

Le routeur Mikrotik est un switch CRS309-1G-8S+ équipé d’un CPU Marvell 98DX8208, un ARM 32-bits bi-coeurs cadencé à 800MHz et disposant d’accélération pour le forwarding L2 mais aussi L3. Si pour router du 1G, le switch risque fortement de tirer la tronche, il pourra supporter du 300Mbps à l’aise.
Quant au switching, qui est ce pourquoi j’ai pris ce modèle à la base, il n’y a rien à dire, l’engin supportera de saturer ses ports 10G.

Je ne conseille pas d’utiliser un switch comme switch/routeur, à moins de se satisfaire de ces performances d’une part, et de savoir faire la distinction entre la configuration qui relève d’un switch, celle qui relève d’un routeur, et surtout quel va en être l’impact en terme de performance, c’est à dire si le paramètre est compatible avec une accélérération matérielle, ou bien si les paquets impactés vont devoir être traités par le CPU.

Nous aurons :

  • un bridge br-lan avec tous les ports physiques dedans
  • l’ONT au format SFP, où arrive la fibre, sera branché sur le port 8 (note : ça marche aussi avec un media-transceiver comme un TP-Link MC220L si vous ne pouvez brancher que du RJ)
  • le vlan 10 nommé home, pour toute la partie réseau local et dont le réseau est en 192.168.45.0/24
  • le vlan 832 nommé orange, pour la partie Internet
  • l’IPv6 sera configuré mais l’adresse réseau dépendra de ce que nous fourni Orange

Configuration du Mikrotik - Layer 2

On démarre sur une configuration complètement vierge, sans même charger la configuration par défaut. Les premières étapes se feront donc soit avec winbox en ciblant le Mikrotik par son adresse mac (c’est de l’UDP broadcast) soit en sérial. Dès que le Mikrotik a une IP, vous pourrez basculer sur la GUI ou SSH.

/interface bridge
add admin-mac=A4:3E:51:xx:xx:xx auto-mac=no name=br-lan pvid=2 vlan-filtering=yes
/interface vlan
add interface=sfp-sfpplus8 loop-protect=off name=orange vlan-id=832
/interface bridge port
add bridge=br-lan edge=yes interface=sfp-sfpplus1 pvid=10 restricted-role=yes
add bridge=br-lan interface=sfp-sfpplus2
add bridge=br-lan edge=yes interface=sfp-sfpplus3 pvid=10 restricted-role=yes
add bridge=br-lan interface=sfp-sfpplus4
add bridge=br-lan edge=yes interface=sfp-sfpplus5 pvid=10 restricted-role=yes
add bridge=br-lan interface=sfp-sfpplus6
add bridge=br-lan interface=sfp-sfpplus7
add bridge=br-lan interface=ether1 pvid=10
add bridge=br-lan interface=orange pvid=2
/interface bridge vlan
add bridge=br-lan tagged=br-lan,sfp-sfpplus2 untagged=sfp-sfpplus1,sfp-sfpplus3,sfp-sfpplus5,ether1 vlan-ids=10
add bridge=br-lan tagged=sfp-sfpplus2,br-lan vlan-ids=832
add bridge=br-lan untagged=sfp-sfpplus2 vlan-ids=1

Parce qu’on aura besoin de traffiquer des packets plus tard pour monter la connexion avec Orange, l’interface (au sens L3) qui portera la connexion Internet ne sera pas orange mais le bridge directement. L’interface Orange sera slave du bridge, comme sous Linux avec ip link set orange master br0.
De manière optionnelle, vous pouvez recopier l’adresse mac de la livebox côté WAN avec le paramètre admin-mac= du bridge, reférrez-vous à la capture réseau faire précédemment pour la récupérer.
Pour isoler le réseau local du reste du monde, on va dédier un VLAN, ici 2 et y mettre le bridge et l’interface orange avec pvid=2. Pas d’inquiétude, le traffic sera bien taggé en sortie en 832 comme indiqué dans la section /interface/bridge/vlan

Configuration du Mikrotik - Layer 3

La partie switch est configurée, on peut définir nos interfaces réseaux.

/interface vlan
add interface=br-lan name=home vlan-id=10
/interface list
add name=wan
add name=lan
add name=lab
/interface list member
add interface=home list=lan
add interface=br-lan list=wan

Puis faire un proto réseau local en assignant une IP fixe au boitier et activer le serveur DHCP sur ce segment :

/ip address
add address=192.168.45.251/24 interface=home network=192.168.45.0
/ip pool
add name=home ranges=192.168.45.100-192.168.45.191
/ip dhcp-server
add address-pool=home client-mac-limit=1 interface=home lease-time=23h30m name=home
/ip dhcp-server network
add address=192.168.45.0/24 dns-server=192.168.45.251,9.9.9.9 domain=home.kveer.fr gateway=192.168.45.251 ntp-server=192.168.45.251
/ip dns
set allow-remote-requests=yes servers=9.9.9.9,149.112.112.112

On définit des interfaces list, wan et lan, plus pour généraliser la configuration au niveau du pare-feu.

Orange en IPv4

Le trafficotage intervient ici. Comme on peut le voir dans la capture réseau, les trames entre la Livebox et le BNG (le “routeur” de la Livebox) sont taggés avec une priorité de 6 (802.1p). Orange a mis une QoS pour ces paquets afin de s’assurer de pouvoir les recevoir et donc les traiter, y compris en cas de saturation du lien.

Piority 6 sur le paquet DHCP

Étant donnée que cette marque se trouve en dehors du payload IP, on ne peut pas utiliser /ip/firewall/mangle (équivalent iptables -t mangle).
L’interface Mikrotik propose des switch rules, malheureusement sur les switches CRS3xx au moins, les règles ne s’appliquent qu’aux paquets ingress.
La seule solution restante et fonctionnelle est une règle sur le bridge pour tagger ce traffic, à savoir :

  • l’échange DHCP
  • le traffic ARP

Les paquets IP sont taggés avec le champ DSCP=6«3 (48 ou CS6) pour la même raison. Ce tag n’est pas obligatoire mais dans un soucis de reproduire la Livebox le plus fidèlement possible, nous allons le poser. Comme c’est de l’IP, ce traitement se fera par une règle mangle. Cependant la règle ne s’appliquera que lors d’un renouvellement de baud DHCP car lors de la première requête DHCP, le boitier n’a pas encore d’IP et dialogue en broadcast. Le client DHCP (ISC DHCP) utilise une socket RAW, qui bypass le pare-feu.

/interface bridge filter
add action=set-priority chain=output comment="CoS for DHCP orange" dst-port=67 ip-protocol=udp log=yes log-prefix="orange: " mac-protocol=ip new-priority=6 out-interface=orange passthrough=yes
add action=set-priority chain=output comment="CoS for ARP orange" log=yes log-prefix="orange: " mac-protocol=arp new-priority=6 out-interface=orange passthrough=yes
/ip firewall mangle
add action=change-dscp chain=postrouting comment="DSCP for DHCP orange" dst-port=67 new-dscp=48 out-interface=br-lan passthrough=yes protocol=udp

On va pouvoir configurer le DHCP, en s’aidant de la capture réseau pour reproduire la requête DHCP le plus fidèlement possible :

/ip dhcp-client option
add code=60 name=60_vendor-class-identifier value="'sagem'"
add code=77 name=77_orange_user-class value="'+FSVDSL_livebox.Internet.softathome.Livebox4'"
add code=61 comment="0x01 + MAC address" name=61_clientid value=0x01a43e51cXXYYZZ
add code=90 name=90_rfc3118-auth value="0x00000000000000000000001a0900000558010341010d'fti/UUUUUUU'0x3c12SALTSALTSALTSALTSALTSALTSALTSALT0313ZZHASHHASHHASHHASHHASHHASHHASHHASH"
/ip dhcp-client
add comment=orange default-route-distance=10 dhcp-options=60_vendor-class-identifier,61_clientid,77_orange_user-class,90_rfc3118-auth interface=br-lan use-peer-dns=no

L’option 90 est l’option la plus importante, c’est votre login auprès de Orange. Elle peut être générée à partir de vos identifiants fti/**** et mot de passe, ou bien vous faire un copier-coller depuis la capture. Une dernière option est également d’extraire la configuration de la Livebox.
L’option 61 est l’adresse MAC de la Livebox, préfixée par 0x01.

Et voilà, normalement une IP devrait remonter et visible dans /ip/address :

[admin@MikroTik] /ip/address> /ip/address/print where interface=br-lan
Flags: D - DYNAMIC
Columns: ADDRESS, NETWORK, INTERFACE
#   ADDRESS           NETWORK      INTERFACE
1 D AA.BBB.CC.DDD/22  AA.BBB.CC.0  br-lan

On finalise avec un pare-feu minimal et le MASQUERADE pour aller sur Internet :

/ip firewall address-list
add address=10.0.0.0/8 list=NON_ROUTABLE
add address=172.16.0.0/12 list=NON_ROUTABLE
add address=192.168.0.0/16 list=NON_ROUTABLE
add address=100.64.0.0/10 comment="carrier-grade nat" list=NON_ROUTABLE
add address=169.254.0.0/16 comment=apipa list=NON_ROUTABLE
add address=127.0.0.0/8 comment=loopback list=NON_ROUTABLE
add address=AA.BBB.CC.DDD list=home_publicip
add address=192.168.45.0/24 list=home
/ip firewall filter
add action=accept chain=input comment="ctstate=established,related" connection-state=established,related
add action=drop chain=input comment="ctstate=invalid" connection-state=invalid
add action=accept chain=input comment="udp services for lan" dst-port=67 in-interface-list=lan protocol=udp
add action=accept chain=input comment="udp services for lan" dst-port=53,67,123,8291 in-interface-list=lan protocol=udp
add action=accept chain=input comment="tcp services for lan" dst-port=22,53,80,443 in-interface-list=lan protocol=tcp
add action=accept chain=input dst-address-type=unicast in-interface-list=lan
add action=drop chain=input
add action=drop chain=input disabled=yes in-interface=br-wan
add action=fasttrack-connection chain=forward hw-offload=yes
add action=accept chain=forward comment="ctstate=established,related" connection-state=established,related
add action=drop chain=forward comment="ctstate=invalid" connection-state=invalid
add action=drop chain=forward comment="non-routable to wan" disabled=yes ipsec-policy=out,none out-interface-list=wan src-address-list=NON_ROUTABLE
add action=accept chain=forward comment="lan > wan" in-interface-list=lan out-interface-list=wan
add action=drop chain=forward
/ip firewall nat
add action=masquerade chain=srcnat comment="lan > wan" out-interface-list=wan src-address=192.168.45.0/24

Orange en IPv6

On applique la même logique qu’en IPv4, à savoir configurer le client DHCPv6, un pare-feu minimal, et tagger ce qu’il faut :

On tag le traffic ICMPv6 et DHCPv6 entre la Livebox et le BNG dans avec la priorité 802.1p à 6 et le code DSCP à CS6 :

/interface bridge filter
add action=set-priority chain=output comment="CoS for DHCPv6 orange" dst-mac-address=33:33:00:01:00:02/FF:FF:00:00:00:00 mac-protocol=ipv6 new-priority=6 out-interface=orange passthrough=yes
add action=set-priority chain=output comment="CoS for ICMPv6 orange" mac-protocol=ipv6 new-priority=6 out-interface=orange packet-type=multicast passthrough=yes
add action=set-priority chain=output comment="CoS for ICMPv6 orange" dst-address6=fe80::/10 mac-protocol=ipv6 new-priority=6 out-interface=orange passthrough=yes
/ipv6 firewall mangle
add action=change-dscp chain=postrouting comment="DSCP=6 for ICMPv6 orange" dst-address=fe80::/10 new-dscp=48 out-interface-list=wan passthrough=yes protocol=icmpv6
add action=change-dscp chain=postrouting comment="DSCP=6 for ICMPv6 orange" dst-address=ff00::/8 new-dscp=48 out-interface-list=wan passthrough=yes protocol=icmpv6
add action=change-dscp chain=postrouting comment="DSCP for DHCPv6 orange" dst-address=ff00::/8 dst-port=547 new-dscp=48 out-interface-list=wan passthrough=yes protocol=udp src-port=546

Configuration du client DHCPv6 pour obtenir un préfixe IPv6 /56 :

/ipv6 dhcp-client option
add code=11 name=11_authentication value="0x00000000000000000000001a0900000558010341010d'fti/UUUUUUU'0x3c12SALTSALTSALTSALTSALTSALTSALTSALT0313ZZHASHHASHHASHHASHHASHHASHHASHHASH"
add code=15 name=15_user-class value="0x00'+FSVDSL_livebox.Internet.softathome.Livebox4'"
add code=16 name=16_vendor-class value="0x0000040e0005'sagem'"
add code=17 name=17_vendor-specific-information-orange value=0x000005580002000a280000ffffffffffffff
/ipv6 dhcp-client
add add-default-route=yes default-route-distance=10 dhcp-options=11_authentication,15_user-class,16_vendor-class,17_vendor-specific-information-orange dhcp-options=11_authentication,15_user-class,16_vendor-class,17_vendor-specific-information-orange disabled=yes \
    interface=br-lan pool-name=orange pool-prefix-length=56 rapid-commit=no request=prefix use-interface-duid=yes use-peer-dns=no
/ipv6 dhcp-client
add add-default-route=yes default-route-distance=10 dhcp-options=11_authentication,15_user-class,16_vendor-class,17_vendor-specific-information-orange dhcp-options=11_authentication,15_user-class,16_vendor-class,17_vendor-specific-information-orange disabled=yes \
    interface=br-lan pool-name=orange pool-prefix-length=56 rapid-commit=no request=prefix use-interface-duid=yes use-peer-dns=no

On attend que le lien monte. Étonamment ce n’est pas immédiat comme en IPv4 et peu prendre plusieurs dizaines de secondes (ou alors c’est parce que j’ai énervé le routeur Orange avec mes tests). Une fois que c’est fait, on va pouvoir récupérer notre prefixe dans /ipv6/pool et à l’aide de ça, configurer notre réseau local :

[admin@MikroTik] /ipv6/address> /ipv6/pool/print where [/ipv6/pool/find name=orange]
Flags: D - DYNAMIC
Columns: NAME, PREFIX, PREFIX-LENGTH, EXPIRES-AFTER
#   NAME    PREFIX                    PREFIX-LENGTH  EXPIRES-AFTER
0 D orange  2a01:c000:1234:5600::/56             56  2d23h59m22s

Ici j’ai obtenu le préfixe 2a01:c000:1234:5600::/56. Converti en range, ça donne : 2a01:c000:1234:5600::-2a01:c000:1234:56ff::, ou 255 réseaux en ::/64. En IPv6, on ne va pas trop utiliser le DHCP pour distribuer des IP individuelles, mais plutôt le ND (Neighbor Discovery). Dans ce mode, le client va broadcaster régulièrement un “y-a-t-il un routeur” en ICMPv6, et le routeur va répondre “c’est moi, voici le réseau”, pour faire simple. Et le client va se prendre une ou plusieurs IPv6 dans ce réseau. Le ND ne fonctionne qu’avec des réseaux en ::/64. On va arbitrairement décider que notre réseau local sera en 2a01:c000:1234:5610::/64.

/ipv6 nd prefix
add interface=home preferred-lifetime=1d prefix=2a01:c000:1234:5610::/64 valid-lifetime=3d
/ipv6 route
add disabled=no distance=1 dst-address=2a01:c000:1234:5610::/64 gateway=home routing-table=main scope=30 suppress-hw-offload=no target-scope=10

Et un pare-feu minmal :

/ipv6 firewall filter
add action=accept chain=input comment="ctstate=established,related" connection-state=established,related
add action=drop chain=input comment="ctstate=invalid" connection-state=invalid
add action=accept chain=input comment=icmpv6 protocol=icmpv6
add action=accept chain=input comment="udp services for lan" dst-port=53,123,8291 in-interface-list=lan protocol=udp
add action=accept chain=input comment="tcp services for lan" dst-port=22 in-interface-list=lan protocol=tcp
add action=accept chain=input comment="ret DHCPv6 orange" dst-port=546 in-interface-list=wan protocol=udp src-address=fe80::ba0:bab/128 src-port=547
add action=drop chain=input
add action=accept chain=forward comment="ctstate=established,related" connection-state=established,related
add action=drop chain=forward comment="ctstate=invalid" connection-state=invalid
add action=accept chain=forward comment="lan > wan" in-interface-list=lan out-interface-list=wan
add action=drop chain=forward

Exposer un service sur Internet, avec Hairpin NAT

Si on veut exposer un service sur Internet, ça sera exactement comme sous Linux :

  • une règle filter pour autoriser le flux
  • une règle NAT

Dans l’exemple qui suit, je souhaite exposer sur Internet les services HTTP et HTTPS de la machine bes :

/ip firewall address-list
add address=192.168.45.60 list=bes
/ip firewall filter
add action=accept chain=forward comment="internet > bes" dst-address-list=bes dst-port=80,443 in-interface-list=wan \
    out-interface-list=lan protocol=tcp
add action=accept chain=forward comment="internet > bes" dst-address-list=bes dst-port=443 in-interface-list=wan \
    out-interface-list=lan protocol=udp
/ip firewall nat
add action=dst-nat chain=dstnat comment="internet > bes" dst-address-list=home_publicip dst-port=80,443 \
    in-interface-list=wan protocol=tcp to-addresses=192.168.45.60
add action=dst-nat chain=dstnat comment="internet > bes" dst-address-list=home_publicip dst-port=443 \

Note : déplacez la règle filter au-dessus du drop final.

La natte de cheveux accrochée (ou Hairpin NAT)

Et si vous souhaitez accédez à votre propres services depuis le LAN ?

Avec un double NAT, on y arrive. Lorsqu’un paquet depuis le LAN à destination de l’IP publique arrive, le routeur va changer l’IP de destination (dst-nat). Puis pour s’assurer que les paquets de retour repassent par le routeur, on va changer l’IP source avec un masquerade. Si on ne change pas l’IP source, bes verra un paquet de son réseau locale, et répondra donc en direct, avec son IP interne et non son IP “internet”, or c’est ce à quoi s’attend le demandeur, qui va alors drop le paquet. À noter que, vu que l’interface Orange est monté sur le bridge, il va falloir activer le pare-feu dans le bridge, sinon les règles ci-dessous n’auront absolument aucun effet.

/interface bridge settings
set use-ip-firewall=yes
/ip firewall filter
add action=accept chain=forward comment="lan > wan" in-interface-list=lan out-interface-list=wan
/ip firewall nat
add action=dst-nat chain=dstnat comment="hairpin nat" dst-address-list=home_publicip dst-address-type=unicast \
    dst-port=80,443 in-interface-list=lan protocol=tcp src-address-list=home to-addresses=192.168.45.60
add action=masquerade chain=srcnat comment="hairpin nat" disabled=yes dst-address=91.222.185.218 log=yes log-prefix=\
    "gog: " out-interface-list=wan protocol=udp src-address=192.168.45.0/24
add action=masquerade chain=srcnat comment="hairpin nat" dst-address-list=bes dst-address-type=unicast out-interface=\
    home src-address-list=home

Une autre alternative consiste à modifier la résolution DNS. Si l’IP est portée par maison.kveer.fr, et que le services est accessible via services.kveer.fr, qui est un CNAME vers maison.kveer.fr, alors il n’y a juste qu’à changer le résultat de maison.kveer.fr pour une résolution locale :

/ip dns static
add address=192.168.45.60 name=maison.kveer.fr type=A

Finalisation

Une fois que la partie L3 est terminée et qu’on n’y touche plus (pas avant), on peut activer l’accélération matérielle :

/interface ethernet switch
set 0 l3-hw-offloading=yes

Et deux trois paramètres qui ne mangent pas de pain :

# Discovery limited to LLDP, and prevent discovery on wan interfaces
/ip neighbor discovery-settings
set discover-interface-list=!wan lldp-mac-phy-config=yes protocol=lldp
# disable unused services
/ip service
set telnet disabled=yes
set ftp disabled=yes
# configure NTP client, and allow NTP on home network
/system clock
set time-zone-name=Europe/Paris
/system note
set show-at-login=no
/system ntp client
set enabled=yes
/system ntp server
set enabled=yes
/system ntp client servers
add address=0.fr.pool.ntp.org
add address=1.fr.pool.ntp.org
add address=2.fr.pool.ntp.org
add address=3.fr.pool.ntp.org

Bonus : extraire la configuration de la Livebox

Si la capture réseau n’est pas possible ou que vous ne parveniez pas à calculer le bon hash pour l’option 90 dans le DHCP, le plus simple reste sans doute à extraire la conf de la Livebox. On va supposer que son IP est 192.168.1.1. On effectue un premier call pour s’authentifier auprès de la Livebox et récupérer un token en faisant un POST à http://192.168.1.1/ws avec deux en-têtes :

  • Content-Type: application/x-sah-ws-4-call+json
  • Authorization: X-Sah-Login

Et ce corps de message :

{
    "service": "sah.Device.Information",
    "method": "createContext",
    "parameters": {
        "applicationName": "webui",
        "username": "admin",
        "password": "le_password"
    }
}

Vous aurez en retour un cookie (pas sur que ça serve, je ne m’en souviens plus) et le token dans .data.contextID pour la requête suivante.

Puis on effectue une requête POST à http://192.168.1.1/ws avec deux en-têtes :

  • Content-Type: application/x-sah-ws-4-call+json
  • X-Context: le_token

Et ce corps de message :

{
    "service": "NeMo.Intf.data",
    "method": "getMIBs",
    "parameters": {}
}

Vous aurez en réponse un fichier JSON avec :

  • la configuration DHCP à .status.dhcp.dhcp_data.SentOption
  • la configuration DHCPv6 à .status.dhcpv6.dhcpv6_data.SentOption
  • l’adresse MAC de la Livebox à .status.netdev.eth0.LLAddress

Sources