Skip to content

Instantly share code, notes, and snippets.

@marfillaster
Last active May 2, 2024 20:08
Show Gist options
  • Save marfillaster/7a136ea826815ac22f2849e099a1c6a1 to your computer and use it in GitHub Desktop.
Save marfillaster/7a136ea826815ac22f2849e099a1c6a1 to your computer and use it in GitHub Desktop.
MikroTik RouterOS v7 dual DHCP WAN recursive failover w/ PCC load-balancing; and recursive ECMP
# feb/11/2022 11:00:55 by RouterOS 7.2rc3
# software id = 9QK9-C798
#
# model = RB5009UG+S+
# serial number = XXXXXXXXXX
/ip settings set allow-fast-path=no
/interface bridge add admin-mac=FF:FF:FF:FF:FF:FF auto-mac=no name=bridge
/interface bridge port add bridge=bridge ingress-filtering=no interface=ether3
/interface bridge port add bridge=bridge ingress-filtering=no interface=ether4
/interface bridge port add bridge=bridge ingress-filtering=no interface=ether5
/interface list add name=WAN
/interface list add name=LAN
/interface list member add interface=bridge list=LAN
/interface list member add interface=ether1 list=WAN
/interface list member add interface=ether2 list=WAN
#/interface bridge port add bridge=bridge ingress-filtering=no interface=ether6
#/interface bridge port add bridge=bridge ingress-filtering=no interface=ether7
#/interface bridge port add bridge=bridge ingress-filtering=no interface=ether8
#/interface bridge port add bridge=bridge ingress-filtering=no interface=sfp-sfpplus1
/ip address add address=192.168.88.1/24 interface=bridge network=192.168.88.0
/ip dns static add address=192.168.88.1 name=router.lan
/ip pool add name=pool1 ranges=192.168.88.10-192.168.88.254
/ip dhcp-server add address-pool=pool1 interface=bridge name=dhcp1
/ip dhcp-server network add address=192.168.88.0/24 dns-server=192.168.88.1 gateway=192.168.88.1
/ip dhcp-client add interface=ether1 add-default-route=no script=":if (\$bound=1) do={\r\
\n /ip/route/set [find where comment=\"ISP1\"] gateway=\$\"gateway-address\"\r\
\n}\r\
\n\r\
\n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
\n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\
\n" use-peer-dns=no use-peer-ntp=no
/ip dhcp-client add interface=ether2 add-default-route=no script=":if (\$bound=1) do={\r\
\n /ip/route/set [find where comment=\"ISP2\"] gateway=\$\"gateway-address\"\r\
\n}\r\
\n\r\
\n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
\n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]" use-peer-dns=no use-peer-ntp=no
/routing table add fib name=to_ISP1
/routing table add fib name=to_ISP2
/ip route
# recursive routes for ECMP default gateways, dst-address are public DNS servers
add distance=1 dst-address=9.9.9.9/32 gateway=ether1 scope=10 target-scope=10 comment=ISP1
add distance=1 dst-address=8.26.56.26/32 gateway=ether2 scope=10 target-scope=10 comment=ISP2
# ECMP default gateways
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=9.9.9.9 scope=10 target-scope=11
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=8.26.56.26 scope=10 target-scope=11
# recursive routes for default gateways, dst-address are public DNS servers
add dst-address=64.6.64.6/32 gateway=ether1 scope=10 comment="ISP1"
add dst-address=208.67.220.220/32 gateway=ether1 scope=10 comment="ISP1"
add dst-address=208.67.222.222/32 gateway=ether2 scope=10 comment="ISP2"
add dst-address=64.6.65.6/32 gateway=ether2 scope=10 comment="ISP2"
# load-balanced w/ auto failover default gateways
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=64.6.64.6 routing-table=to_ISP1 scope=10 target-scope=11
add check-gateway=ping distance=2 dst-address=0.0.0.0/0 gateway=64.6.65.6 routing-table=to_ISP1 scope=10 target-scope=11
add check-gateway=ping distance=1 dst-address=0.0.0.0/0 gateway=208.67.222.222 routing-table=to_ISP2 scope=10 target-scope=11
add check-gateway=ping distance=2 dst-address=0.0.0.0/0 gateway=208.67.220.220 routing-table=to_ISP2 scope=10 target-scope=11
/ip firewall address-list add address=192.168.88.0/24 list=local
/ip firewall mangle
add action=accept chain=prerouting comment="bridge access" dst-address-list=local in-interface-list=LAN
# WAN to LAN
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=established,related in-interface=ether1 new-connection-mark=ISP1_conn \
passthrough=yes
add action=mark-connection chain=prerouting connection-mark=no-mark connection-state=established,related in-interface=ether2 new-connection-mark=ISP2_conn \
passthrough=yes
# PCC mangles
add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=!local dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP1_conn passthrough=yes per-connection-classifier=both-addresses-and-ports:2/0
add action=mark-connection chain=prerouting connection-mark=no-mark dst-address-list=!local dst-address-type=!local in-interface-list=LAN new-connection-mark=ISP2_conn passthrough=yes per-connection-classifier=both-addresses-and-ports:2/1
add action=mark-routing chain=prerouting connection-mark=ISP1_conn in-interface-list=LAN new-routing-mark=to_ISP1 passthrough=yes
add action=mark-routing chain=prerouting connection-mark=ISP2_conn in-interface-list=LAN new-routing-mark=to_ISP2 passthrough=yes
add action=mark-routing chain=output connection-mark=ISP1_conn dst-address-list=!local new-routing-mark=to_ISP1 passthrough=yes
add action=mark-routing chain=output connection-mark=ISP2_conn dst-address-list=!local new-routing-mark=to_ISP2 passthrough=yes
# masquerade
/ip firewall nat add action=masquerade chain=srcnat ipsec-policy=out,none out-interface-list=WAN
@oakwhiz
Copy link

oakwhiz commented Jul 28, 2022

I have posted a partial configuration which might help someone: https://gist.github.com/oakwhiz/55b4043e99320129323496ffd5087f05
I should mention though, there are some minor errors in there and various things set up for debugging/testing purposes, I wouldn't recommend copying it.

@dipan29
Copy link

dipan29 commented Nov 30, 2022

Can anyone please explain what this area is doing?

/ip dhcp-client add interface=ether1 add-default-route=no script=":if (\$bound=1) do={\r\
    \n    /ip/route/set [find where comment=\"ISP1\"] gateway=\$\"gateway-address\"\r\
    \n}\r\
    \n\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP1_conn\"]\r\
    \n/ip/firewall/connection/remove [find connection-mark=\"ISP2_conn\"]\r\
    \n" use-peer-dns=no use-peer-ntp=no

I have one Static WAN where I need to setup but how do I add the script?

@marfillaster
Copy link
Author

@dipan29 That is for resetting all connections whenever the DHCP client changes its IP. If your other uplink is a static IP, you only need one DHCP client.

@dipan29
Copy link

dipan29 commented Dec 1, 2022

@marfillaster thanks for the response,

Also, I tried doing the same and gracefully it works for the local network right out of the box. As in for all interface lists LAN. However, My requirement was a little different and could not manage to get it working post Router OS 7.

I would require something similar but for the following scenario

  • Having one DHCP Client and one with Static IP or PPPoE Client (here the gateway caused an issue when I tried to replicate cause for ether1 when its PPPoE the gateway IP isn't defined)
  • Ensuring that both the WAN IPs can be used for DST-NAT - for any local subnet
  • I would be having generally two subnets - one for home lab and one for normal home users. For the home lab I won't really want to do load balancing but just ensure that the DST-NAT for that network works from both the WANs.
  • For normal home users, I would be okay if it goes out through ether1 (PPPoE/Static) most of the times but have an address-list called DUAL say that can only get Load Balancing when tagged to it. In other words, only the addresses tagged as DUAL can have the load balancing.

I tried finding a lot of guides on the internet but could not have something from reddit or mikrotik forum that serves my purpose (some claim to, but they just don't get connected).
Also, I am new to this mikrotik, would be glad if you can guide me with some exact details or something from the internet that works.

@rexsllemel
Copy link

rexsllemel commented Feb 27, 2023

I'm using this config but, when the ISP 1 has no internet, it uses the ISP 2, however, when the ISP 1's internet get's back, the recursive will still mark ISP 1 as no internet. It only uses ISP 2's internet the whole time, unless I'll restart the mikrotik.

@nhan6310
Copy link

@marfillaster thanks for the response,

Also, I tried doing the same and gracefully it works for the local network right out of the box. As in for all interface lists LAN. However, My requirement was a little different and could not manage to get it working post Router OS 7.

I would require something similar but for the following scenario

  • Having one DHCP Client and one with Static IP or PPPoE Client (here the gateway caused an issue when I tried to replicate cause for ether1 when its PPPoE the gateway IP isn't defined)
  • Ensuring that both the WAN IPs can be used for DST-NAT - for any local subnet
  • I would be having generally two subnets - one for home lab and one for normal home users. For the home lab I won't really want to do load balancing but just ensure that the DST-NAT for that network works from both the WANs.
  • For normal home users, I would be okay if it goes out through ether1 (PPPoE/Static) most of the times but have an address-list called DUAL say that can only get Load Balancing when tagged to it. In other words, only the addresses tagged as DUAL can have the load balancing.

I tried finding a lot of guides on the internet but could not have something from reddit or mikrotik forum that serves my purpose (some claim to, but they just don't get connected). Also, I am new to this mikrotik, would be glad if you can guide me with some exact details or something from the internet that works.

I can help you with all your requests

@aaronbolton
Copy link

Has the variable $leaseBound change to $bound now?

@dipan29
Copy link

dipan29 commented Aug 12, 2023

Hi @nhan6310 how can we connect to get this configuration set?

@quinont
Copy link

quinont commented Aug 12, 2023

I tested this on a MikroTik RB4011, and it worked perfectly. However, I'm encountering an issue that perhaps you could assist with: the load balancing is happening constantly (meaning a PC is continuously switching between the two WANs). Is there a way to configure WAN balancing based on the client's IP?

@aaronbolton
Copy link

aaronbolton commented Aug 12, 2023

@quinont the easiest way to to change this is to change the pre routing mangle rule to included a src address list and then you can specify which IP get load balanced or not

Below is how mines looks

add action=mark-connection chain=prerouting
connection-mark=no-mark dst-address-type=
!local in-interface-list=LAN
new-connection-mark=ISP1_conn passthrough=yes
per-connection-classifier=
both-addresses-and-ports:2/0 src-address-list=
MultiWAN-Clients
add action=mark-connection chain=prerouting
connection-mark=no-mark dst-address-type=
!local in-interface-list=LAN
new-connection-mark=ISP2_conn passthrough=yes
per-connection-classifier=
both-addresses-and-ports:2/1 src-address-list=
MultiWAN-Clients

@yosijoe
Copy link

yosijoe commented Dec 21, 2023

any one can give me recursive fail over gate way
im using NTH
my ip : gateway
my dns :8.8.8.8,8.8.4.4,1.1.1.1
wan1 192.168.1.1
wan2 192.168.254.254
wan3 192.168.0.1

@adrianolima83
Copy link

Jovem, que configuração excelente. Testamos em laboratório de bancada, fizemos testes de estresse, usamos conexões diferentes (pppoe, client, etc), e tudo funcionou perfeitamente. Meus parabéns e muito obrigado pelo compartilhamento.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment