Community discussions

MikroTik App
 
mk13139
just joined
Topic Author
Posts: 11
Joined: Mon Dec 30, 2013 3:32 am

Pi-hole forced DNS redirection with failover script

Tue Dec 08, 2020 1:50 pm

I'm trying to create a Pi-hole DNS failover script, without luck so far.

Currently I have a Pi-hole in my network with IP address 192.168.18.2. The router has an outgoing public DNS of 1.1.1.1 and 1.0.0.1. The DHCP server has DNS 192.168.18.1 (router gateway) for the clients.
I've added the following NAT rules to force all DNS through the Pi-hole:
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
What I would like to do in case of failure of the Pi-hole is disabling these NAT rules. When these NAT rules are disabled, the clients DNS will go through the router gateway and public DNS 1.1.1.1/1.0.0.1 like normal until the Pi-hole is up again (NAT rules get enabled again and DNS redirect to Pi-hole).
I've created the following script, scheduled at an interval of 30 seconds:
:local piholeDNS "192.168.18.2"
:local testDomain "www.google.com"


:if ([/ip firewall nat [find comment="piholeNAT1"] enabled]) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat disable [find comment="piholeNAT1"]
		/ip firewall nat disable [find comment="piholeNAT2"]
		/ip firewall nat disable [find comment="piholeNAT3"]
		/ip firewall nat disable [find comment="piholeNAT4"]
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
		/ip firewall nat enable [find comment="piholeNAT1"]
		/ip firewall nat enable [find comment="piholeNAT2"]
		/ip firewall nat enable [find comment="piholeNAT3"]
		/ip firewall nat enable [find comment="piholeNAT4"]
    } on-error={}
}
When I disconnect the Pi-hole as a failure test, the NAT rules don't get disabled. So something is obviously wrong in the script. Can somebody help me out?
Last edited by mk13139 on Wed Dec 09, 2020 12:05 pm, edited 1 time in total.
 
mk13139
just joined
Topic Author
Posts: 11
Joined: Mon Dec 30, 2013 3:32 am

Re: Pi-hole DNS failover script  [SOLVED]

Tue Dec 08, 2020 4:39 pm

Nevermind! I looked again carefully and figured that the fault was in getting the state value of the nat rule.
The working code for forced redirection through Pi-hole with DNS failover is as follows:
:local piholedown [/ip firewall nat get value-name=disabled [find comment="piholeNAT1"]]
:local piholeDNS "192.168.18.2"
:local testDomain "www.google.com"


:if ($piholedown = false) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat;
			disable [find comment="piholeNAT1"];
			disable [find comment="piholeNAT2"];
			disable [find comment="piholeNAT3"];
			disable [find comment="piholeNAT4"];
    		}
} else={
    :do {
        :resolve $testDomain server $piholeDNS;
		/ip firewall nat;
			enable [find comment="piholeNAT1"];
			enable [find comment="piholeNAT2"];
			enable [find comment="piholeNAT3"];
			enable [find comment="piholeNAT4"];
    } on-error={}
}
With the following NAT rules (*edit: added in-interface LAN bridge to dst-nat rules to prevent exposure of port 53 to outside world):
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
 
zilexa
just joined
Posts: 16
Joined: Tue Apr 10, 2018 6:05 pm

Re: Pi-hole DNS failover script

Fri Feb 12, 2021 11:20 am

With the following NAT rules (*edit: added in-interface LAN bridge to dst-nat rules to prevent exposure of port 53 to outside world):
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
With these rules, is the device running pihole (192.168.18.2) able to use the internet, resolve domains?
In my case pihole runs on my homeserver which does need the ability to have normal internet access/resolve domains. It seems, to prevent a loop, you actually exclude the pihole, but then how can that device resolve domains?
 
mk13139
just joined
Topic Author
Posts: 11
Joined: Mon Dec 30, 2013 3:32 am

Re: Pi-hole DNS failover script

Fri Feb 12, 2021 12:03 pm

With the following NAT rules (*edit: added in-interface LAN bridge to dst-nat rules to prevent exposure of port 53 to outside world):
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 in-interface=bridge protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
With these rules, is the device running pihole (192.168.18.2) able to use the internet, resolve domains?
In my case pihole runs on my homeserver which does need the ability to have normal internet access/resolve domains. It seems, to prevent a loop, you actually exclude the pihole, but then how can that device resolve domains?
Hi Zilexa,

Yes, with these rules the PiHole is the only device in the network which is able to resolve domains using an external DNS server (the PiHole is explicitly excluded in above rules).
These rules force a redirect for all DNS queries from all other devices in the network to the PiHole.
 
zilexa
just joined
Posts: 16
Joined: Tue Apr 10, 2018 6:05 pm

Re: Pi-hole DNS failover script

Fri Feb 12, 2021 12:27 pm

Hi Zilexa,

Yes, with these rules the PiHole is the only device in the network which is able to resolve domains using an external DNS server (the PiHole is explicitly excluded in above rules).
These rules force a redirect for all DNS queries from all other devices in the network to the PiHole.
Thanks, I tried and luckily I am still able to resolve dns queries coming from my server itself :)

The biggest downside though: You no longer have per-client stats in PiHole. PiHole will see only 1 client: your router.
But I guess that is acceptable for now.
 
User avatar
kaherdin
newbie
Posts: 32
Joined: Sat Nov 20, 2021 7:47 am

Re: Pi-hole DNS failover script

Wed Dec 01, 2021 1:51 pm



With these rules, is the device running pihole (192.168.18.2) able to use the internet, resolve domains?
In my case pihole runs on my homeserver which does need the ability to have normal internet access/resolve domains. It seems, to prevent a loop, you actually exclude the pihole, but then how can that device resolve domains?
Hi Zilexa,

Yes, with these rules the PiHole is the only device in the network which is able to resolve domains using an external DNS server (the PiHole is explicitly excluded in above rules).
These rules force a redirect for all DNS queries from all other devices in the network to the PiHole.
Hi!
Would you mind creating screenshots of this in webfig/winbox?
I'm new at this, and I want to start using the gui...
or if you could explain how to input this in to RouterOS terminal in a correct way.

My pihole is at 10.0.0.31
My DHCP is 10.0.0.100-10.0.0.200 and static leases are at 10.0.0.3-10.0.0.99

Best of regards
 
User avatar
kaherdin
newbie
Posts: 32
Joined: Sat Nov 20, 2021 7:47 am

Re: Pi-hole forced DNS redirection with failover script

Wed Dec 01, 2021 10:51 pm

Hi
Where do you specify the "outgoing public DNS"?
I'm trying to create a Pi-hole DNS failover script, without luck so far.

Currently I have a Pi-hole in my network with IP address 192.168.18.2. The router has an outgoing public DNS of 1.1.1.1 and 1.0.0.1. The DHCP server has DNS 192.168.18.1 (router gateway) for the clients.
I've added the following NAT rules to force all DNS through the Pi-hole:
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
What I would like to do in case of failure of the Pi-hole is disabling these NAT rules. When these NAT rules are disabled, the clients DNS will go through the router gateway and public DNS 1.1.1.1/1.0.0.1 like normal until the Pi-hole is up again (NAT rules get enabled again and DNS redirect to Pi-hole).
I've created the following script, scheduled at an interval of 30 seconds:
:local piholeDNS "192.168.18.2"
:local testDomain "www.google.com"


:if ([/ip firewall nat [find comment="piholeNAT1"] enabled]) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat disable [find comment="piholeNAT1"]
		/ip firewall nat disable [find comment="piholeNAT2"]
		/ip firewall nat disable [find comment="piholeNAT3"]
		/ip firewall nat disable [find comment="piholeNAT4"]
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
		/ip firewall nat enable [find comment="piholeNAT1"]
		/ip firewall nat enable [find comment="piholeNAT2"]
		/ip firewall nat enable [find comment="piholeNAT3"]
		/ip firewall nat enable [find comment="piholeNAT4"]
    } on-error={}
}
When I disconnect the Pi-hole as a failure test, the NAT rules don't get disabled. So something is obviously wrong in the script. Can somebody help me out?
 
zilexa
just joined
Posts: 16
Joined: Tue Apr 10, 2018 6:05 pm

Re: Pi-hole forced DNS redirection with failover script

Tue Apr 18, 2023 3:56 pm

Hi
Where do you specify the "outgoing public DNS"?
I'm trying to create a Pi-hole DNS failover script, without luck so far.

Currently I have a Pi-hole in my network with IP address 192.168.18.2. The router has an outgoing public DNS of 1.1.1.1 and 1.0.0.1. The DHCP server has DNS 192.168.18.1 (router gateway) for the clients.
I've added the following NAT rules to force all DNS through the Pi-hole:
/ip firewall nat

add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=udp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT1"
add chain=dstnat action=dst-nat to-addresses=192.168.18.2 protocol=tcp src-address=!192.168.18.2 dst-address=!192.168.18.2 dst-port=53 comment="piholeNAT2"

add chain=srcnat action=masquerade protocol=udp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT3"
add chain=srcnat action=masquerade protocol=tcp src-address=192.168.18.0/24 dst-address=192.168.18.2 dst-port=53 comment="piholeNAT4"
What I would like to do in case of failure of the Pi-hole is disabling these NAT rules. When these NAT rules are disabled, the clients DNS will go through the router gateway and public DNS 1.1.1.1/1.0.0.1 like normal until the Pi-hole is up again (NAT rules get enabled again and DNS redirect to Pi-hole).
I've created the following script, scheduled at an interval of 30 seconds:
:local piholeDNS "192.168.18.2"
:local testDomain "www.google.com"


:if ([/ip firewall nat [find comment="piholeNAT1"] enabled]) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat disable [find comment="piholeNAT1"]
		/ip firewall nat disable [find comment="piholeNAT2"]
		/ip firewall nat disable [find comment="piholeNAT3"]
		/ip firewall nat disable [find comment="piholeNAT4"]
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
		/ip firewall nat enable [find comment="piholeNAT1"]
		/ip firewall nat enable [find comment="piholeNAT2"]
		/ip firewall nat enable [find comment="piholeNAT3"]
		/ip firewall nat enable [find comment="piholeNAT4"]
    } on-error={}
}
When I disconnect the Pi-hole as a failure test, the NAT rules don't get disabled. So something is obviously wrong in the script. Can somebody help me out?

I have this running for 2 years without ever having to look back. Works nicely. Instructions should be more clear for you.
If you have multiple DNS servers (multiple AdGuard Home or PiHole, see this solution: viewtopic.php?f=2&t=174873&p=858336#p858336

Who is online

Users browsing this forum: marcelofares, rextended and 27 guests