AdGuard failover to public DNS; is this OK?

I adapted this script from an article I found on the web. I’m OK with not blocking stuff when local AdGuard is down

:delay 2
:local servers [/ip dns get servers];

:do {
    /tool fetch \
        http-header-field="Authorization: Basic <BASE64_USERNAME_COLON_PASSWORD>" \
        url="http://192.168.1.53/control/status" \
        keep-result=no;

    # AdGuard responded -> Healthy state.
    # Only set AdGuard as DNS if we're not already using it.
    :if ($servers != "192.168.1.53") do={
        /ip dns set servers=192.168.1.53;
        /ip dhcp-server network set [find] dns-server=192.168.1.53;
        /ip dns cache flush;
        :log info "AdGuard UP: DHCP/router DNS -> 192.168.1.53";
    }

} on-error={

    # Fetch failed -> AdGuard DOWN.
    # Only set backup DNS if we're not already using it.
    :if ($servers != "1.1.1.1") do={
        /ip dns set servers=1.1.1.1;
        /ip dhcp-server network set [find] dns-server=1.1.1.1;
        /ip dns cache flush;
        :log warning "AdGuard DOWN: DHCP/router DNS -> 1.1.1.1";
    }
}

Useless, if not specified at all, it is inherited from ip/dns (and if not specified neither on ip/dns is taken from dhcp client or pppoe client if are present).

Optionally, dhcp server dynamic leases can be removed so that clients receive new dns when changed, this will result short connection loss for clients; or implement nat hairpin for dns and whatever dns client uses it will always sent requests to dns defined by hairpin rule without connection loss, this is also preferred when having static dhcp leases.

1 Like

I should’ve probably clarified that I’m not exactly fluent in home networking and far from fluent in WinBox/MikroTik and was looking to see if this script works as intended and is not harmful.

Interesting...

Or simply the machines should use RouterOS's DNS, and only RouterOS then uses AdGuard when it works...
Simpler (and more logical) and avoids interruptions...

1 Like

I would have already written it, the script is safe... :upside_down_face:

1 Like

Thanks. So you’re saying skip the 1.1.1.1 and just use whatever RouterOS would like to use? One requirement is I’d like to see the individual client IPs in AdGuard. I don’t know if that matters. Anyway, I wouldn’t know how to write that script :confused:

Yes, it depends if OP wants that clients shuld use ROS DNS or external, by script I assumed one wants external, but as you wrote it is not necessary unless if there is some specific case.

Well, @foobar229 specified that he wants to see the individual IPs... so the DHCP lease should be set to no more than 10 minutes to be safe because the machines won't run for a maximum of 5 minutes before getting a working IP DNS...

For avoid, with advanced scripting, a NAT/U53 can help...

This would make a difference for me. Why would this avoid interruptions? And how can I change 1.1.1.1 to whatever RouterOS wants to use?

Avoid interruptions because the PC use RouterOS for solve the DNS, then RouterOS use AdGuard for solve, but use directly 1.1.1.1 for resolve when AdGuard do not work wihout waiting the DHCP renew...

But you do not see the PC IP on AdGuard, but RouterOS one...

If I understand correctly though, that means AdGuard would see router’s IP only when receiving requests, which is something I don’t want. Because then it’s client → router → AdGuard and not client → AdGuard.

appreciate your patience.

Yes, if you want little downtime, you NOT see PC IP,
if you accept long service interruption (at least long as DHCP lease time), you see PC IP inside AdGuard.

Is your choice: single device IPs on AdGuard, or near-ininterrupted service.

1 Like

So my script is problematic if we have long DHCP leases? That’s a problem. If I understand correctly what you’re writing, clients who got 192.168.1.53 as DNS server will not know about 1.1.1.1 until they renew their DHCP leases? Anyway to avoid that with having the client IPs in AdGuard?

With a very advanced configuration, AdGuard is only reachable via RouterOS.

When the AdGuard test IP doesn't work properly,
RouterOS interrupts the direct connection between devices and AdGuard,
taking over AdGuard's IP address, responding directly instead of AdGuard.
Alternatively, a NAT is configured to divert all DNS calls directly to RouterOS, which always resolves via 1.1.1.1.

I see. So it is achievable to have no interruptions and direct client IPs in AdGuard, but it takes a very advanced configuration. I guess I’m better off just having another instance of AdGuard running on another machine, something I hope to avoid…

If you have two instances, you specify 2 different IPs in the DHCP server, then the devices do it themselves, if one DNS doesn't respond they use the other, making this also seamless and without interruptions.

1 Like

There is no such guarantee at all. Specifying 2 DNS servers in DHCP means the clients will know about 2 DNS servers, but it is not possible to specify an order or a priority. Some clients will use only the first and query the 2nd when it is down, some will only use the 2nd and query the first when it is down, some will round-robin across the two servers.

E.g. a router using RouterOS will do the latter. When you specify two DNS servers in /ip dns, both of them will be used.

When having multiple DNS servers, they should always have equal characteristics. When you want to hide ads, and you have one DNS server that does that and another one that doesn’t, you will still get ads. How many, that will depend on the client behavior. I don’t think what is what @foobar229 would want.

(similarly, some people have put a local DNS which knows about local names as first and then a “fallback” to some public DNS. but that doesn’t work, because local names will still be looked up in the public DNS)

What I suggested was to have 2 AdGuard instances be the two DNS servers, which I hoped to avoid, but will give the same experience when either one is chosen, and doesn’t involve the downtime that was discussed here.

if there was a way to avoid running 2 instances and the downtime, I would prefer that.

If AGH is running on a separate subnet (bridge or VLAN interface) from the client devices, then you can do this:

  • In all the DHCP Server Network configurations, announce the router's IP address as DNS server, same value as the announced gateway address.

  • Add the following two DSTNAT rules, assuming the VLAN interface list contains the interfaces with the clients that need DNS (excluding the interface of the subnet where AGH is running)

    /ip firewall nat
    add action=dst-nat chain=dstnat comment="redirect to AGH" \
        dst-address-type=local dst-port=53 in-interface-list=VLAN protocol=udp \
        to-addresses=192.168.1.53
    add action=dst-nat chain=dstnat comment="redirect to AGH" \
        dst-address-type=local dst-port=53 in-interface-list=VLAN protocol=tcp \
        to-addresses=192.168.1.53
    

This preserves the source addresses of the queries in AGH. And when AGH is down, you only need to disable the two rules with the comment "redirect to AGH", and the router automatically takes over the DNS duty, without the clients having to renew DHCP leases.

Of course, the devices in 192.168.1.0/24 cannot benefit from this. If you let them use 192.168.1.1 (the router) as DNS server and do the DSTNAT for that subnet too, then you'll need a hairpin-NAT rule, and AGH won't see the real source addresses for devices in the 192.168.1.0/24 subnet, only 192.168.1.1.