You have a Mikrotik router and some server at home. Your family expects 100% high availability for the internet access, but you want to go extra step and install Pi-Hole or alike (I prefer Blocky) on home server. However, that home server crashed and DNS is no longer working for everyone at home! Or you wanted to reboot it, or upgrade something and Pi-Hole is no longer accessible.
While having 2nd server for Pi-Hole is an idea - it's actually an overkill...
Naturally you pick one out of 2 options:
- Configure DHCP server to issue DHCP lease with DNS value pointing directly to Pi-Hole.
- Configure Mikrotik's DNS server to Pi-Hole, and configure DHCP server to issue DHCP lease with DNS value pointing to Mikrotik router.
Solution
Thanks to Mikrotik's scripting functionality and freedom of configuration, we can achieve an automatic failover, while still using Pi-Hole directly. Here is the idea:
- Mikrotik "port-forwards" DNS query traffic to Pi-Hole if Pi-Hole is working.
- Mikrotik serves DNS queries by itself (e.g. from 1.1.1.2,1.0.0.2) if Pi-Hole is not working.
Instructions
FYI for below steps, I am using "Blocky", therefore in comments I have this keyword
1. Configure router
First, point each of your network device to use router as DNS server.
Then disable the Mikrotik's DNS server:
Code: Select all
/ip/dns/set allow-remote-requests=no
Code: Select all
/ip firewall nat add action=dst-nat chain=dstnat comment=Blocky dst-port=53 protocol=tcp src-address-list=LANs dst-address-list=LANs to-addresses=192.168.72.10
/ip firewall nat add action=dst-nat chain=dstnat comment=Blocky dst-port=53 protocol=udp src-address-list=LANs dst-address-list=LANs to-addresses=192.168.72.10
Code: Select all
$ nslookup mikrotik.com 192.168.72.1
Server: 192.168.72.1
Address: 192.168.72.1#53
Non-authoritative answer:
...
Code: Select all
/ip firewall mangle add action=mark-connection chain=prerouting comment="Mark connections for hairpin NAT - LAN IP" dst-address-list=LANs new-connection-
mark="Hairpin NAT" passthrough=yes src-address-list=LANs
/ip firewall nat add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark="Hairpin NAT"
If it's working, enable router's DNS server back:
Code: Select all
/ip/dns/set allow-remote-requests=yes
2. Add scheduled script
Add this script to /system/scheduler (by using GUI). Modify it accordingly:
Code: Select all
# Specify search filters for NAT rules
:local tcpRuleId [/ip firewall nat find comment="Blocky" protocol="tcp"]
:local udpRuleId [/ip firewall nat find comment="Blocky" protocol="udp"]
# Find Blocky IP from NAT rule
:local toAddresses [/ip firewall nat get $tcpRuleId to-addresses]
# Specify query domain
:local queryDomain "www.google.com"
:if ([/ip firewall nat get $tcpRuleId disabled] = false) do={
:do {
:resolve $queryDomain server=$toAddresses
} on-error={
/ip firewall nat set $tcpRuleId disabled=yes
/ip firewall nat set $udpRuleId disabled=yes
}
} else={
:do {
:resolve $queryDomain server=$toAddresses
/ip firewall nat set $tcpRuleId disabled=no
/ip firewall nat set $udpRuleId disabled=no
} on-error={}
}
Schedule this script to run every 10-30 seconds and forget about complains when Pi-Hole is temporarily not working.