Community discussions

MikroTik App
 
erkexzcx
Member Candidate
Member Candidate
Topic Author
Posts: 175
Joined: Mon Oct 07, 2019 11:42 pm

[Script] Automatically change DNS if Pi-hole is no longer working

Sun May 31, 2020 2:44 pm

I've wrote a script that detects when Pi-Hole is no longer working, and automatically switches to public DNS 1.1.1.2,1.0.0.2.

Disclaimer: I am aware of possibility to set multiple DNS servers, but for Pi-Hole to work you need to set only Pi-Hole IP address.

Use case: Set-up Mikrotik and RPI with Pi-Hole. When RPI goes down, internet will "stop" working for everyone on the LAN, and you don't want it to happen. Add script to Mikrotik that detects when Pi-Hole is no longer resolving queries and switch all DNS settings on Mikrotik to public DNS servers, such as 1.1.1.2,1.0.0.2. Also notify yourself that RPI is down. Second RPI costs money, and brings no benefits rather than high-availability, so this is not an option in this case.

Variant 1 - changes only DNS server for router. Assumes that all devices use router as the only DNS server:
:local currentDNS [/ip dns get server]
:local piholeDNS "192.168.0.50"
:local backupDNS "1.1.1.2,1.0.0.2"
:local testDomain "www.google.com"

:if ($currentDNS = $piholeDNS) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
        /ip dns set servers=$backupDNS
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
        /ip dns set servers=$piholeDNS
    } on-error={}
}
Variant 2 - changes only DNS server for router + notify yourself when Pi-Hole goes down via Telegram Bot. Assumes that all devices use router as the only DNS server:
:local telegramBotKey "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
:local chatID "XXXXXXXXX"

:local currentDNS [/ip dns get server]
:local piholeDNS "192.168.0.50"
:local backupDNS "1.1.1.2,1.0.0.2"
:local testDomain "www.google.com"

:if ($currentDNS = $piholeDNS) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
        /ip dns set servers=$backupDNS
        /tool fetch "https://api.telegram.org/bot$telegramBotKey/sendmessage?chat_id=$chatID&text=Pi-Hole not working! Changed DNS from $currentDNS to $backupDNS." keep-result=no
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
        /ip dns set servers=$piholeDNS
        /tool fetch "https://api.telegram.org/bot$telegramBotKey/sendmessage?chat_id=$chatID&text=Pi-Hole is working again. Changed DNS from $currentDNS to $piholeDNS." keep-result=no
    } on-error={}
}
Variant 3 - changes DNS server for router and for all the networks (IP --> DHCP Server --> Networks). Depending on lease time, DNS will not update instantly for all clients, but allows Pi-Hole to show what uses it:
:local currentDNS [/ip dns get server]
:local piholeDNS "192.168.0.50"
:local backupDNS "1.1.1.2,1.0.0.2"
:local testDomain "www.google.com"

:if ($currentDNS = $piholeDNS) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
        /ip dns set servers=$backupDNS
        /ip dhcp-server network set [find] dns-server=$backupDNS;
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
        /ip dns set servers=$piholeDNS
        /ip dhcp-server network set [find] dns-server=$piholeDNS;
    } on-error={}
}
Variant 4 - changes DNS server for router and for all the networks (IP --> DHCP Server --> Networks) + notify yourself when Pi-Hole goes down via Telegram Bot. Depending on lease time, DNS will not update instantly for all clients, but allows Pi-Hole to show what uses it:
:local telegramBotKey "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
:local chatID "XXXXXXXXX"

:local currentDNS [/ip dns get server]
:local piholeDNS "192.168.0.50"
:local backupDNS "1.1.1.2,1.0.0.2"
:local testDomain "www.google.com"

:if ($currentDNS = $piholeDNS) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
        /ip dns set servers=$backupDNS
        /ip dhcp-server network set [find] dns-server=$backupDNS;
        /tool fetch "https://api.telegram.org/bot$telegramBotKey/sendmessage?chat_id=$chatID&text=Pi-Hole not working! Changed DNS from $currentDNS to $backupDNS." keep-result=no
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
        /ip dns set servers=$piholeDNS
        /ip dhcp-server network set [find] dns-server=$piholeDNS;
        /tool fetch "https://api.telegram.org/bot$telegramBotKey/sendmessage?chat_id=$chatID&text=Pi-Hole is working again. Changed DNS from $currentDNS to $piholeDNS." keep-result=no
    } on-error={}
}
Usage: Use system --> scheduler --> add. Set interval to 00:00:30, any name and paste script into "On Event:" field. Do not forget to change variable values to match your Pi-Hole IP address.

EDIT: Updated scripts according to suggestions in comments & offered more variants.
Last edited by erkexzcx on Sun May 31, 2020 7:43 pm, edited 1 time in total.
 
User avatar
jvanhambelgium
Member
Member
Posts: 393
Joined: Thu Jul 14, 2016 9:29 pm
Location: Belgium

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun May 31, 2020 3:13 pm

This will not work for all clients that have received their DHCP-lease.
I don't know how many hours of lease-time you provide so these clients don't really benefit from the switchover you make on RouterOS. If their (only) DNS-server fails it is over & out.

Multiple DNS would be a / the only true "redundant solution" for your clients.

EDIT : Ah ok, so your Mikrotik IS already the DNS for your client and you are only forwarding to either Pi-hole (if operational) or some public upstream DNS in case of failure ? Or not ?
Because if your Mikrotik is in the DNS-chain, do you see in the Pi-hole stats the individual clients ? Aren't they all appearing come from 1 client "mikrotik" ?
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 1920
Joined: Sat Dec 24, 2016 11:17 am
Location: jo.overland at gmail.com

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun May 31, 2020 6:43 pm

Thanks for the script.

I do see a use for it in my case. I have a DoH server running separately on an MT running 6.47 beta. On my main MT Router i have one DNS point to that DoH MT router. If add a second DNS on main router, that will be used without going trough the DoH server. So I can use the script to test the if the DNS on the DoH router works, if not replace DNS with a working one.


Some tips.

If you do suggest to use local variable. I do not see in your script any reason to use global variable. It will just fill up the variable space.

Noe need for semicolon at the end of the line. Only needed when multiple commands are on the same line.

So:
:local currentDNS [/ip dns get server]
:local piholeDNS "192.168.0.50"
:local backupDNS "1.1.1.2,1.0.0.2"
:local testDomain "www.google.com"

:if ($currentDNS = $piholeDNS) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
        /ip dns set servers=$backupDNS
        /ip dhcp-server network set [find] dns-server=$backupDNS
    }
} else={
    :do {
        :resolve $testDomain server $piholeDNS
        /ip dns set servers=$piholeDNS
        /ip dhcp-server network set [find] dns-server=$piholeDNS
    } on-error={}
}
 
Why do not use Splunk to monitor your MikroTik Router(s)? Look at this page in how to set it up.

MikroTik->Splunk
 
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 1920
Joined: Sat Dec 24, 2016 11:17 am
Location: jo.overland at gmail.com

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun May 31, 2020 7:15 pm

Here is my version of DoH server not working any more. Thanks again for the idea.
Added logging when things change. I love to log everything (see my signature)
:local currentDNS [/ip dns get server]
:local DoHDNS "192.168.20.10"
:local backupDNS "8.8.8.8,1.1.1.1"
:local testDomain "www.google.com"

:if ($currentDNS = $DoHDNS) do={
    :do {
        :resolve $testDomain server $DoHDNS
    } on-error={
        /ip dns set servers=$backupDNS
		:log info message="DNS_server=$backupDNS"
    }
} else={
    :do {
        :resolve $testDomain server $DoHDNS
        /ip dns set servers=$DoHDNS
		:log info message="DNS_server=$DoHDNS"
    } on-error={}
}
I do run this with an one minute schedule. 00:01:00
Last edited by Jotne on Wed Jul 29, 2020 11:01 am, edited 1 time in total.
 
Why do not use Splunk to monitor your MikroTik Router(s)? Look at this page in how to set it up.

MikroTik->Splunk
 
 
erkexzcx
Member Candidate
Member Candidate
Topic Author
Posts: 175
Joined: Mon Oct 07, 2019 11:42 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun May 31, 2020 7:44 pm

Thank you. I updated my initial comment with your suggestions. :)
 
ladegro
just joined
Posts: 8
Joined: Tue Apr 03, 2018 11:05 am

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Wed Jul 29, 2020 10:25 am

Thanks a lot for this, exactly what I was looking for and very useful. Even if there is some downtime because of not yet expired lease time, this guarantees it will eventually come back up. So if I'm away from home, the misses doesn't have to worry. Great!

(using it with adGuard by the way but that of course doesn't matter)
 
TDJ211
just joined
Posts: 7
Joined: Mon Jul 01, 2019 2:30 am

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Tue Aug 11, 2020 1:05 pm

Oh wow, this is perfect for me!

Im using a local Unbound DNS server for perfomance and like you Ive found the only way to get the Mikrotik to reliably use the local DNS is to set only the one DNS server.

Ive been bitten once before by forgetting to change my DNS when doing server maintenance. Nice to know ill have a backup just in case the server goes down for real.
 
Dennypr
just joined
Posts: 2
Joined: Tue Aug 11, 2020 7:30 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Tue Aug 11, 2020 8:04 pm

Please help,

Can i change mac address automatically by script on every day?..
Btw thx can any one to help me
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 1920
Joined: Sat Dec 24, 2016 11:17 am
Location: jo.overland at gmail.com

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Tue Aug 18, 2020 11:00 pm

Can i change mac address automatically by script on every day?..
Yes it can be do.
Post it as a new question.
 
Why do not use Splunk to monitor your MikroTik Router(s)? Look at this page in how to set it up.

MikroTik->Splunk
 
 
hollerauer
just joined
Posts: 3
Joined: Wed Jan 06, 2021 12:55 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Wed Jan 06, 2021 1:52 pm

!! Due to sporadic failures (in my installation) affecting DNS-queries it is NOT advised to use the proposed configuration in PRODUCTIVE environment. This post will be updated after problem is fixed!!
I've wrote a script that detects when Pi-Hole is no longer working, and automatically switches to public DNS 1.1.1.2,1.0.0.2.Disclaimer: I am aware of possibility to set multiple DNS servers, but for Pi-Hole to work you need to set only Pi-Hole IP address.

Use case: Set-up Mikrotik and RPI with Pi-Hole. When RPI goes down, internet will "stop" working for everyone on the LAN, and you don't want it to happen. Add script to Mikrotik that detects when Pi-Hole is no longer resolving queries and switch all DNS settings on Mikrotik to public DNS servers, such as 1.1.1.2,1.0.0.2. Also notify yourself that RPI is down. Second RPI costs money, and brings no benefits rather than high-availability, so this is not an option in this case.
This script is exactly what I was looking for. I want to share an even more elegant way how to integrate a Pi-Hole in your LAN.
Use case:
  1. Set mikrotik as DNS server for your LAN(-segments)
    /ip dns set allow-remote-requests=yes servers=$YourPrefferedPublicDNSServers$; \
    /ip dhcp-server network set dns-server=$YourMikrotikLANAddress$
  2. Add a NAT rule for each LAN(-segment) to redirect any traffic from LAN(-segment) associated with udp port 53 to Pi-Hole. Comment the rule with "pihole".
    /ip firewall nat add chain=dstnat action=dst-nat to-addresses=$YourPiHoleAddress$ protocol=udp src-address=$YourLANSegment$ dst-address=!$YourPiHoleAddress$ dst-port=53 comment="pihole"
  3. Add script to switch (enable|disable) NAT rule
    :local piholeDNS "$YourPiHoleAddress$"
    :local testDomain "www.example.com"
    :local piholeRulesEnabled [/ip firewall nat print count-only where comment~"pihole" && !disabled]
    
    if ($piholeRulesEnabled > 0)
    do={ \
    	:do {:resolve $testDomain server=$piholeDNS} \
    	on-error={/ip firewall nat disable [find comment~"pihole"]} \
    	}
    else={ \
    	:do { \
    		:resolve $testDomain server=$piholeDNS; \
    		/ip firewall nat enable [find comment~"pihole"] \
    		} \
    	on-error={} \
    	}
    
  4. Add scheduler to execute script time based
Benefits:
  • All DNS queries (even the ones from clients where you can not change DNS server) are redirected to Pi-Hole
  • Pi-Hole can "see" all LAN clients
  • Fallback if Pi-Hole is down
!! Due to sporadic failures (in my installation) affecting DNS-queries it is NOT advised to use the proposed configuration in PRODUCTIVE environment. This post will be updated after problem is fixed!!
Last edited by hollerauer on Fri Jan 22, 2021 8:25 am, edited 1 time in total.
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Thu Jan 14, 2021 5:50 pm

This script is exactly what I was looking for. I want to share an even more elegant way how to integrate a Pi-Hole in your LAN.
Use case:
  1. Set mikrotik as DNS server for your LAN(-segments)
    /ip dns set allow-remote-requests=yes servers=$YourPrefferedPublicDNSServers$; \
    /ip dhcp-server network set dns-server=$YourMikrotikLANAddress$
  2. Add a NAT rule for each LAN(-segment) to redirect any traffic from LAN(-segment) associated with udp port 53 to Pi-Hole. Comment the rule with "pihole".
    /ip firewall nat add chain=dstnat action=dst-nat to-addresses=$YourPiHoleAddress$ protocol=udp src-address=$YourLANSegment$ dst-address=!$YourPiHoleAddress$ dst-port=53 comment="pihole"
    Benefits:
    • All DNS queries (even the ones from clients where you can not change DNS server) are redirected to Pi-Hole
    • Pi-Hole can "see" all LAN clients
    • Fallback if Pi-Hole is down

Without using the fallback script yet: the NAT rule does not work as expected.

Scenario 1, my working situation without fallback:
Router IP: 192.168.88.1 with IP > DHCP Server > DNS set to 192.168.88.1
IP > DNS is set to 192.168.88.2
My (Ubuntu) Server running PiHole has IP 192.168.88.2. This way, internet works.

Scenario 1-modified to support a fallback (without the actual script yet):
I change IP > DNS to 1.1.1.1 (necessary for the fallback scenario).
I add the NAT rule:
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.88.2 protocol=udp src-address=192.168.88.0/24 dst-address=!192.168.88.2 dst-port=53 comment="pihole"
Issue 1:
After I add the NAT rule, my clients cannot resolve DNS anymore. Not even when I disconnect/reconnect them.
Issue 2:
Your rule includes dst-address=!$YourPiHoleAddress$ not sure what it means, but doesn't that exclude the server? I still need my server for other things that requires resolving of domains.

I would love for your NAT rule to work though..

EDIT: to get it to work at all, you also need a masquerade rule like this:
[/code]add action=masquerade chain=srcnat src-address=192.168.88.0/24 dst-address-list=192.168.88.2 dst-port=53 protocol=udp[/code]

But still, the server that runs Pi-Hole is now unable to resolve domains. Also, it seems none of my devices work.
As soon as I disable your NAT rule and my masquarade rule, everything works again.
 
hollerauer
just joined
Posts: 3
Joined: Wed Jan 06, 2021 12:55 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Thu Jan 14, 2021 9:14 pm

Without using the fallback script yet: the NAT rule does not work as expected.
You are correct. That's what I meant with $YourFavoritePublicDNSServers$ = e.g. 1.1.1.1, 1.0.0.1, etc.
Scenario 1-modified to support a fallback (without the actual script yet):
I change IP > DNS to 1.1.1.1 (necessary for the fallback scenario).
I add the NAT rule:
/ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.88.2 protocol=udp src-address=192.168.88.0/24 dst-address=!192.168.88.2 dst-port=53 comment="pihole"
Issue 1:
After I add the NAT rule, my clients cannot resolve DNS anymore. Not even when I disconnect/reconnect them.
The parameters are set correct. But your use-case is different then mine. In my case the pihole is in another IP-Segment (10.0.0.0/8). If your mikrotik device is your Internet-gateway than it will loop DNS-traffic (udp p53) back to pihole.
You will need a second rule which is placed above your pihole-rule (processed first):
ip firewall nat add chain=dstnat src-address=192.168.88.2 protocol=udp dst-port=53 comment="traffic pihole to www"
Issue 2:
Your rule includes dst-address=!$YourPiHoleAddress$ not sure what it means, but doesn't that exclude the server? I still need my server for other things that requires resolving of domains.
Means if there is DNS traffic directly to your server it is excluded from this rule. You should configure your server to use 127.0.0.1 for DNS.
EDIT: to get it to work at all, you also need a masquerade rule like this:
[/code]add action=masquerade chain=srcnat src-address=192.168.88.0/24 dst-address-list=192.168.88.2 dst-port=53 protocol=udp[/code]
Not true. there is no need to masquerade or srcnat or redirect. Masquerade is a special version of srcnat designed for traffic from LAN -> www with changing public ip address.
The dstnat rule will take care of redirecting DNS traffic back to device.

It works like this:
  1. device A asks mikrotik (= per DHCP defined DNS server) for Domain "example.com"
  2. mikrotik recieves the request and checks if there is a firewall (nat) rule for it
  3. as there is a rule (pihole), mikrotik asks pihole for Domain "example.com" in the name of device A
  4. pihole answers to mikrotik and asks mikrotik to forward the answer to device A
  5. mikrotik receives the answer and checks if there is a firewall (nat) ruie for it
  6. mikrotik forwards answer of pihole to device A
Please test the additional NAT rule in your setup. If it works for you I'll edit my original post.
 
LordTMortis
just joined
Posts: 1
Joined: Fri Jan 15, 2021 5:39 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Jan 15, 2021 5:59 pm

Hey,

I've sucessfully used PiHole to improve my ad-situation and have been trying to use some sort of script to have working failsafe in place in case my Pi is not running.
I am not seeing Mikrotik for the first time, but I am quite new to scripting.

However, I am a bit stuck at the moment, as I do not want to change DNS systemwide, I only want to change DNS for clients that use DHCP.

I used following code to have working switch from piholeDNS to backupDNS:
:local piholeDNS "192.168.88.6"
:local backupDNS "8.8.8.8,8.8.4.4"
:local currentDHCPDNS []

:if ([/ping $piholeDNS count=20] =0) do={
        :log info "PiHole server nedostupny, pro DHCP klienty měním DNS server na zalozni." 
	/ip dhcp-server network set [find] dns-server=$backupDNS;
    } else={
	     
	    :log info "PiHole server dostupny, netreba nic menit." 
		 }
 
This code allows my MK to change DNS for my DHCP clients. It's not ideal, as when my Pi comes back online, there is no automatic change from backupDNS to piholeDNS.
What I did at the moment was adding following line into my else statement:
/ip dhcp-server network set [find] dns-server=$piholeDNS;
Which works... but the problem is, it works everytime and in my Log i can see that DNS has been changed everytime. This behaviour is not optimal and I would like to make it work only, if the DNS for my DHCP clients is not piholeDNS. This is the place that made me stuck as I found no way to get information about DHCP DNS only.

I tried to make local variable in which I store the value of currentDHCPDNS:
:local currentDHCPDNS [/ip dhcp-server network get [find dns-server]]
That does not work, so I tried:
:local currentDHCPDNS [/ip dhcp-server network get dns-server]
It seems I cannot figure out how to get desired info.

Could you please give me some hint how to extract current value of DHCP DNS?

Thank you very much.
Last edited by LordTMortis on Fri Jan 15, 2021 6:02 pm, edited 1 time in total.
 
hollerauer
just joined
Posts: 3
Joined: Wed Jan 06, 2021 12:55 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Jan 22, 2021 9:23 am

I've sucessfully used PiHole to improve my ad-situation and have been trying to use some sort of script to have working failsafe in place in case my Pi is not running.
I am not seeing Mikrotik for the first time, but I am quite new to scripting.
You can get the number of DHCP server which use pihole as DNS server:
:local currentDHCPDNS [/ip dhcp-server network print count-only where dns-server=$piholeDNS] 
and decide based on that:
:if ($currentDHCPDNS = 0) ...


Another solution might be, instead of using a script you could use the netwatch tool.
/tool netwatch add host=$piholeDNS up-script=[/ip dhcp-server network set dns-server=$piholeDNS] down-script=[/ip dhcp-server network set dns-server=$backupDNS]
A major drawback of both methods is, that clients will notice the change first after dhcp lease renew. Depending on lease-time this can be quite a while (default 10m).
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Jan 29, 2021 1:16 pm

It works like this:
  1. device A asks mikrotik (= per DHCP defined DNS server) for Domain "example.com"
  2. mikrotik recieves the request and checks if there is a firewall (nat) rule for it
  3. as there is a rule (pihole), mikrotik asks pihole for Domain "example.com" in the name of device A
  4. pihole answers to mikrotik and asks mikrotik to forward the answer to device A
  5. mikrotik receives the answer and checks if there is a firewall (nat) ruie for it
  6. mikrotik forwards answer of pihole to device A
Please test the additional NAT rule in your setup. If it works for you I'll edit my original post.

Sorry it really doesn't work:
  • Router on 192.168.88.1
  • I have a server/nas/workstation on 192.168.88.2.
  • No VLANs or other networks configured besides 192.168.88.0/24.
  • IP > DNS: a public DNS server (9.9.9.9) and Allow Remote Requests enabled.
  • IP > DHCP Server > Networks > 192.168.88.0/24 > 192.168.88.1 (the router itself).
  • chain=dstnat protocol=udp src-address=192.168.88.2 dst-port=53
  • dstnat action=dst-nat to-addresses=192.168.88.2 protocol=udp src-address=192.168.88.0/24 dst-address=!192.168.88.2 dst-port=53
The short rule is placed above the long rule. They are at the top of my NAT list, below those two rules I only have a few port forwarding rules (to my server at 192.168.88.2). My Firewall rules are just the default rules. I am on RouterOS 6.48 stable.
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Jan 29, 2021 6:06 pm

EDIT: to get it to work at all, you also need a masquerade rule like this:
[/code]add action=masquerade chain=srcnat src-address=192.168.88.0/24 dst-address=192.168.88.2 dst-port=53 protocol=udp[/code]
Not true. there is no need to masquerade or srcnat or redirect. Masquerade is a special version of srcnat designed for traffic from LAN -> www with changing public ip address.
The dstnat rule will take care of redirecting DNS traffic back to device.
Ok so just as a test I added the masquerade rule, below the 2 rules you gave me:
add action=masquerade chain=srcnat src-address=192.168.88.0/24 dst-address-list=192.168.88.2 dst-port=53 protocol=udp
Now it works BUT Pihole sees all requests coming from my router. No statistics per client unfortunately.
Without this masquerade rule, no client can resolve domains unfortunately.

As soon as I disable the masquerade rule, it does not work anymore :(
 
Ddram
just joined
Posts: 5
Joined: Mon Feb 08, 2021 7:56 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Tue Feb 09, 2021 5:38 pm

Hi,

I also had some problems here. My Pi-Hole is configured with unbound on Port 5335 to resolve from DNS-Rootservers.

The solution that works for me comes from another thread here: viewtopic.php?f=9&t=170487 and i changed some things according to my setup and some overthinking i've done.

Mysetup is:
RB2011iL: 192.168.0.1 configured with two external DNS Servers (1.1.1.1, 1.0.0.1)
Pi-Hole: 192.168.0.250
DHCP-Range: 192.168.0.0/24 and Pi-Hole as DNS

I added two NAT-Rules to grab every dns request and force it to use my configured server.
6 X  ;;; Mikrotik forced
      chain=dstnat action=dst-nat to-addresses=192.168.0.1 
      protocol=udp src-address=!192.168.0.1 
      dst-address=!192.168.0.1 in-interface=bridge dst-port=53 
      log=no log-prefix="" 

 7    ;;; pihole forced
      chain=dstnat action=dst-nat to-addresses=192.168.0.250 
      protocol=udp src-address=!192.168.0.250 
      dst-address=!192.168.0.250 in-interface=bridge 
      dst-port=53 log=no log-prefix="" 
To check pi-hole running state i have configured a scheduler task that resolves google.com every 5 minutes via pihole. If there's an error the pihole NAT-Rule would be disabled and the mikrotik would be enabled.
:local piholedown [/ip firewall nat get value-name=disabled [find comment="pihole forced"]]
:local piholeDNS "192.168.0.250"
:local testDomain "www.google.com"


:if ($piholedown = false) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat;
			disable [find comment="pihole forced"];
			enable [find comment="Mikrotik forced"];
    		}
} else={
    :do {
        :resolve $testDomain server $piholeDNS;
		/ip firewall nat;
			enable [find comment="pihole forced"];
			disable [find comment="Mikrotik forced"];
    } on-error={}
}
In short the pi is my standard and only in case of error there is a forced dns redirection to the router with the external dns servers.

Maybe you could give it a try. (hopefully a successfull one)

As mentioned before, the initial idea came from this thread viewtopic.php?f=9&t=170487

Have a nice day!

PS: English is not my native language, so be careful while reading, it could be nonsense :)
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Feb 12, 2021 11:13 am

Mysetup is:
RB2011iL: 192.168.0.1 configured with two external DNS Servers (1.1.1.1, 1.0.0.1)
Pi-Hole: 192.168.0.250
DHCP-Range: 192.168.0.0/24 and Pi-Hole as DNS

I added two NAT-Rules to grab every dns request and force it to use my configured server.
6 X  ;;; Mikrotik forced
      chain=dstnat action=dst-nat to-addresses=192.168.0.1 
      protocol=udp src-address=!192.168.0.1 
      dst-address=!192.168.0.1 in-interface=bridge dst-port=53 
      log=no log-prefix="" 

 7    ;;; pihole forced
      chain=dstnat action=dst-nat to-addresses=192.168.0.250 
      protocol=udp src-address=!192.168.0.250 
      dst-address=!192.168.0.250 in-interface=bridge 
      dst-port=53 log=no log-prefix="" 
To check pi-hole running state i have configured a scheduler task that resolves google.com every 5 minutes via pihole. If there's an error the pihole NAT-Rule would be disabled and the mikrotik would be enabled.
:local piholedown [/ip firewall nat get value-name=disabled [find comment="pihole forced"]]
:local piholeDNS "192.168.0.250"
:local testDomain "www.google.com"


:if ($piholedown = false) do={
    :do {
        :resolve $testDomain server $piholeDNS
    } on-error={
		/ip firewall nat;
			disable [find comment="pihole forced"];
			enable [find comment="Mikrotik forced"];
    		}
} else={
    :do {
        :resolve $testDomain server $piholeDNS;
		/ip firewall nat;
			enable [find comment="pihole forced"];
			disable [find comment="Mikrotik forced"];
    } on-error={}
}
In short the pi is my standard and only in case of error there is a forced dns redirection to the router with the external dns servers.

Maybe you could give it a try. (hopefully a successfull one)

As mentioned before, the initial idea came from this thread viewtopic.php?f=9&t=170487

Have a nice day!

PS: English is not my native language, so be careful while reading, it could be nonsense :)
@Ddram thank you for posting this. Could you please confirm a few things?
1. the RouterOS version you are using
2. you only have 1 subnet/dhcp range right? So your pihole and your LAN clients are all in the same IP range.
3. In PiHole, do you see DNS requests and nice stats per client? Or does this solution mean PiHole will "see" all DNS requests coming from your router? Because I really want to be able to have per-client stats and I believe your solution works, but in PiHole it will look like you only have 1 client because all requests come from the router?
 
Ddram
just joined
Posts: 5
Joined: Mon Feb 08, 2021 7:56 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Fri Feb 12, 2021 7:44 pm

Hi zilexa,

1. I'm on Version 6.48
2. Yes that's my small home setup only one subnet with everything in it.
3. Yes, i've read your previous postings and that's exactly what i want and have! ;) Every client calls the Pi with it's own fqdn. As an example, i can see my Mobilephone querying as "OnePlus7T.home.arpa" in pihole querys.

I think the Problem is the srcnat masquerading rule (someone mentioned this before).

With masquerading, every request seems top be sent from your Router. That's the opposit from what you want.

Greetings
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun Feb 14, 2021 1:31 am

Hi zilexa,

1. I'm on Version 6.48
2. Yes that's my small home setup only one subnet with everything in it.
3. Yes, i've read your previous postings and that's exactly what i want and have! ;) Every client calls the Pi with it's own fqdn. As an example, i can see my Mobilephone querying as "OnePlus7T.home.arpa" in pihole querys.

I think the Problem is the srcnat masquerading rule (someone mentioned this before).

With masquerading, every request seems top be sent from your Router. That's the opposit from what you want.

Greetings
My point is, it should be impossible without the masquerade rule.
None of my clients are able to access any domains, with only the single rule you mention to force DNS to your pihole.
Are you using the default Firewall rules from 6.48? Do you have other NAT rules set up?
I asked this in a Dutch forum and they confirm it cannot work without the masquerade rule.
 
Ddram
just joined
Posts: 5
Joined: Mon Feb 08, 2021 7:56 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Sun Feb 14, 2021 2:58 pm

Hi,

well I see it working every day since exactly one week ago.

Yes I have other nat rules active but none of them handles DNS traffic.

I split my rule with some explanation, maybe someone can correct me, where I'm wrong (or right).
Do
chain=dstnat (declare outgoing nat)
action=dst-nat (redirect for outgoing NAT)
to-addresses=192.168.0.250 (redirect to my pi)
to-ports=53 (to DNS port)

But only if:
protocol=udp (maybe TCP but mostly DNS is a udp thing)
And 
src-address=!192.168.0.250 (not from pi, so requests from pi could passthrough)
And
dst-address=!192.168.0.250 (no requests already sent to my pi)
And
in-interface=bridge (request is from local network)
And
dst-port=53 (if DNS port is used)

So every matching request is redirected to the pi. I can use 'ping' and 'dig' commands from my pi (via SSH) as much as I want, everything works as expected.

Maybe I'm wrong, but it's working.

Have a nice Sunday
 
zilexa
just joined
Posts: 13
Joined: Tue Apr 10, 2018 6:05 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Mon Feb 15, 2021 12:23 pm

So every matching request is redirected to the pi. I can use 'ping' and 'dig' commands from my pi (via SSH) as much as I want, everything works as expected.

Maybe I'm wrong, but it's working.

Have a nice Sunday
Would you mind posting the output of:
/ip firewall export
You can ofcourse remove all port forwarding rules of NAT.

In my case, I only use the default Mikrotik/RouterOS firewall rules:
/ip firewall filter
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new in-interface-list=WAN
/ip firewall nat
add action=dst-nat chain=dstnat comment=DNS-to-server-rule1 dst-address=!192.168.88.2 dst-port=53 in-interface=bridge protocol=udp src-address=!192.168.88.2 to-addresses=192.168.88.2 to-ports=53
add action=masquerade chain=srcnat comment=DNS-to-server-rule2 dst-address=192.168.88.2 dst-port=53 protocol=udp src-address=192.168.88.0/24
add action=masquerade chain=srcnat out-interface=pppoe-client
NAT only contains the 2 rules to force DNS to pihole. The very last rule is required for internet access as my proivider uses PPOE.
 
Ddram
just joined
Posts: 5
Joined: Mon Feb 08, 2021 7:56 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Mon Feb 15, 2021 1:00 pm

Hi,

Here is my Firewall export, without lists and mangle rules.
/ip firewall filter
add action=drop chain=input comment="Winbox on WAN" dst-port=\
    8291 in-interface=pppoe-out1 log-prefix="winbox on wan " \
    protocol=tcp
add action=drop chain=forward comment=\
    "Drop incoming packets that are not NATted" \
    connection-nat-state=!dstnat connection-state=new \
    in-interface=pppoe-out1 log=yes log-prefix=!NAT
add action=drop chain=forward comment=" Drop  Invalid" \
    connection-state=invalid log-prefix=invalid
add action=drop chain=forward comment=\
    "Drop incoming from internet which is not public IP" \
    in-interface=pppoe-out1 log=yes log-prefix=!public \
    src-address-list=not_in_internet
add action=drop chain=input comment="Drop Wan2Lan DNS (TCP)" \
    dst-port=53 in-interface=pppoe-out1 protocol=tcp
add action=drop chain=input comment="Drop Wan2Lan DNS (UDP)" \
    dst-port=53 in-interface=pppoe-out1 protocol=udp
add action=drop chain=forward comment=\
    "Drop packets from LAN that do not have LAN IP" \
    in-interface=bridge log=yes log-prefix=LAN_!LAN \
    src-address=!192.168.0.0/24
add action=drop chain=forward comment="Firehol list" \
    connection-state=new disabled=yes dst-address-list=firehol
add action=accept chain=input comment=\
    "Allow established, related" \
    connection-state=established,related
add action=accept chain=input comment="Allow internal" \
    src-address-list=allowed_to_router
add action=fasttrack-connection chain=forward comment=\
    "FastTrack" connection-state=\
    established,related
add action=accept chain=forward comment="Established,  Related" \
    connection-state=established,related
add action=accept chain=forward comment=\
    "Forward Portmapping (Plex)" connection-nat-state=dstnat \
    dst-port=32400 in-interface=pppoe-out1 log=yes log-prefix=\
    "Forward Plex" protocol=tcp
add action=accept chain=forward comment="SIP forward" \
    connection-nat-state=dstnat log=yes log-prefix=SIP \
    src-address-list=SIP
add action=accept chain=forward comment="Zyxel Forward Rule" \
    dst-address=192.168.1.1 in-interface=bridge log=yes \
    log-prefix="Forward to Zyxel" out-interface=ether1 \
    src-address-list=allowed_to_router
add action=drop chain=forward comment=\
    " Drop  tries  to  reach  not public  addresses  from  LAN" \
    dst-address-list=not_in_internet in-interface=bridge \
    log-prefix=!publich_from_LAN out-interface=!bridge
add action=drop chain=input comment="Drop everything" \
    in-interface=pppoe-out1 log-prefix=dropped
and the NAT part:
/ip firewall nat
add action=dst-nat chain=dstnat comment=\
    "SIP Connection forward 3478 to FB7590 (UDP)" \
    connection-type=sip dst-port=3478 in-interface=pppoe-out1 \
    log=yes log-prefix="UDP(5060)" protocol=udp \
    src-address-list=SIP to-addresses=192.168.0.254 to-ports=\
    3478
add action=dst-nat chain=dstnat comment=\
    "SIP Connection forward 5060 to FB7590 (UDP)" \
    connection-type=sip dst-port=5060 in-interface=pppoe-out1 \
    log=yes log-prefix="UDP(5060)" protocol=udp \
    src-address-list=SIP to-addresses=192.168.0.254 to-ports=\
    5060
add action=dst-nat chain=dstnat comment=\
    "SIP Connection forward 5060 to FB7590 (TCP)" dst-port=5060 \
    in-interface=pppoe-out1 log=yes log-prefix="TCP(5060)" \
    protocol=tcp src-address-list=SIP to-addresses=\
    192.168.0.254 to-ports=5060
add action=dst-nat chain=dstnat comment=\
    "SIP forward to FB7590 only 1and1-IPs" in-interface=\
    pppoe-out1 log=yes log-prefix="UDP(CALL)" protocol=udp \
    src-address-list=SIP to-addresses=192.168.0.254 to-ports=\
    7077-7110
add action=dst-nat chain=dstnat comment="Plex forward to 32400" \
    dst-port=24179 in-interface=pppoe-out1 log=yes log-prefix=\
    Plex protocol=tcp to-addresses=192.168.0.31 to-ports=32400
add action=dst-nat chain=dstnat comment="PS4 Forward" disabled=\
    yes dst-port=3074 in-interface=pppoe-out1 protocol=udp \
    to-addresses=192.168.0.18 to-ports=3074
add action=dst-nat chain=dstnat comment="Mikrotik forced" \
    disabled=yes dst-address=!192.168.0.1 dst-port=53 \
    in-interface=bridge protocol=udp src-address=!192.168.0.1 \
    to-addresses=192.168.0.1
add action=dst-nat chain=dstnat comment="pihole forced" \
    dst-address=!192.168.0.250 dst-port=53 in-interface=bridge \
    protocol=udp src-address=!192.168.0.250 to-addresses=\
    192.168.0.250 to-ports=53
add action=masquerade chain=srcnat comment=\
    "Outbound to Zyxel for Configuration" dst-address=\
    192.168.1.1 out-interface=ether1
add action=masquerade chain=srcnat comment=\
    "Outgoing NAT for WAN" dst-address-list=!not_in_internet \
    out-interface=pppoe-out1
I hope there's something that could help, but i don't see anything related. Maybe there's some difference in your other dns related configuration (pihole or router)?

Here is mine from the router :
/ip dns
set allow-remote-requests=yes cache-max-ttl=12h servers=1.1.1.1,1.0.0.1
How is your pihole configuration?

Greetings
 
Ddram
just joined
Posts: 5
Joined: Mon Feb 08, 2021 7:56 pm

Re: [Script] Automatically change DNS if Pi-hole is no longer working

Mon Feb 15, 2021 8:48 pm

Hello again,

I did some testing and reconfiguration on my setup, because I was interested, what's wrong on your site.

Guess what happened? Well it doesn't work anymore...

Never touch a running system, I guess....

So I think I was wrong all the time. Maybe someone with more networking experience finds a way.

Until then I will use the solution from the thread I've posted, because it's not DHCP TTL dependent.

Have a nice evening.

Who is online

Users browsing this forum: No registered users and 25 guests