Community discussions

MikroTik App
 
jovaf32128
just joined
Topic Author
Posts: 24
Joined: Sun Apr 26, 2020 9:22 pm

How to optimize DNS (and DoH) checker script?

Fri Jan 13, 2023 8:55 pm

I used DoH, but due to local restrictions, the DoH servers became unavailable from time to time. Therefore, I wrote a simple script: is the current DoH server alive, if not, check the next one, the next one, and if there is none, disable DoH. I run it every minute. But if the main DoH is not available and the second one is alive, I get a lot of warnings from the log.
How to optimize this script? I dream of using an array of DoH servers and a loop that will check one by one and select the available DoHs, but not with my scripting kiddie skills.
:local result yes
:do {tool fetch url="https://cloudflare-dns.com/dns-query\?name=mikrotik.ca%26type=A" output=none dst-path=result http-header-field=accept:application/dns-json} on-error={:set result no}
:if $result do={
 :local testdns [/ip dns get use-doh-server];
 :if ($testdns != "https://cloudflare-dns.com/dns-query")  do={
  /ip dns set servers="" use-doh-server="https://cloudflare-dns.com/dns-query" verify-doh-cert=yes;:log warning "DNS over HTTPS returned to cloudflare-dns.com"
 }
} else={
  :set result yes;
  :do {tool fetch url="https://1.0.0.1/dns-query\?name=mikrotik.ca%26type=A" output=none dst-path=result http-header-field=accept:application/dns-json} on-error={:set result no}
  :if $result do={
   /ip dns set servers="" use-doh-server="https://1.0.0.1/dns-query" verify-doh-cert=yes;:log warning "DNS over HTTPS changed to 1.0.0.1"
  } else={
    :set result yes
    :do {tool fetch url="https://dns.google.com/resolve\?name=mikrotik.ca%26type=A" output=none dst-path=result http-header-field=accept:application/dns-json} on-error={:set result no}
    :if $result do={
     /ip dns set servers="" use-doh-server="https://dns.google/dns-query" verify-doh-cert=yes;:log warning "DNS over HTTPS changed to dns.google"
    } else={
     /ip dns set servers="1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4" use-doh-server="";:log warning "DNS over HTTPS switched off!"
    }
  }
}
 
tomislav91
Member
Member
Posts: 303
Joined: Fri May 26, 2017 12:47 pm

Re: How to optimize DNS (and DoH) checker script?

Sat Jan 14, 2023 12:31 am

To optimize this script, you can use an array of DoH servers and a loop to check them one by one. Instead of hardcoding the URLs, you can store them in an array and then use a loop to iterate through the array, checking each one until you find an available server. This will make the script more modular and easier to update if you need to add or remove DoH servers. Additionally, you can add a timeout for the fetch command, so that it doesn't spend too much time trying to reach an unavailable server.

Here is an example of how you could structure your script using an array and a loop:
# Define an array of DoH servers
:local dohServers {"https://cloudflare-dns.com/dns-query", "https://1.0.0.1/dns-query", "https://dns.google.com/resolve"}
:local currentDohServer ""

# Use a loop to iterate through the array and check each server
:foreach dohServer in=$dohServers do={
    # Use the built-in :resolve command to check if the server is available
    :if ([/tool dns-client resolve $dohServer] = "resolved") do={
        :set currentDohServer $dohServer
        break
    }
}

# If a server is available, set it as the DoH server
:if ($currentDohServer != "") do={
  /ip dns set use-doh-server=$currentDohServer verify-doh-cert=yes;
  :log warning "DNS over HTTPS changed to $currentDohServer"
} else={
  # If no servers are available, disable DoH and use regular DNS servers
  /ip dns set use-doh-server=no;
  :log warning "DNS over HTTPS switched off!"
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to optimize DNS (and DoH) checker script?

Sat Jan 14, 2023 1:22 am

/tool dns-client resolve ?
break ?
and try to "resolve" the url like a dns name???

Is like the script generated by iMStupidIA™ than invent unexistant commands...



Is better provide for start something that works, not finished, but work:
:global dohquery do={
    ([/tool fetch http-header-field="accept:application/dns-json" url="$1\3Fname=$2&type=$3" as-value output=user]->"data")
}

:put [$dohquery "https://cloudflare-dns.com/dns-query" "mikrotik.com" "A"]
:put [$dohquery "https://dns.google.com/resolve" "mikrotik.com" "A"]
 
jovaf32128
just joined
Topic Author
Posts: 24
Joined: Sun Apr 26, 2020 9:22 pm

Re: How to optimize DNS (and DoH) checker script?

Sat Jan 14, 2023 7:47 pm

/tool dns-client resolve ?
break ?
and try to "resolve" the url like a dns name???
Hello ChatGPT

Now my actual problem that Google DoH URL is "https://dns.google/dns-query", but correct URL to check is Google alive - "https://dns.google.com/resolve" and I can not use array of DoHs, because:
tool fetch url="https://dns.google.com/dns-query\?name=mikrotik.ca%26type=A" output=none dst-path=result http-header-field=accept:application/dns-json
  status: failed

failure: closing connection: <301 Moved Permanently location="https://dns.google/dns-query?name=mikrotik.ca%26type=A">
 8.8.8.8:443 (5)
How to pass that?

Anyway I used a part of that script for beginning:
:local dohServers {"https://cloudflare-dns.com/dns-query"; "https://1.0.0.1/dns-query"; "https://dns.google/dns-query"}
:local dohServerAvailable false
:local result yes
:foreach dohServer in=$dohServers do={
 :do {tool fetch url="$dohServer\?name=mikrotik.ca%26type=A" output=none dst-path=result http-header-field=accept:application/dns-json} on-error={:set result no}
  :if $result do={
	/ip dns set servers="" use-doh-server="$dohServer" verify-doh-cert=yes;
	:log warning "DNS over HTTPS setted to $dohServer"
    :set dohServerAvailable true
  }
}

:if ( $dohServerAvailable = false) do={
  /ip dns set servers="1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4" use-doh-server="";
  :log warning "DNS over HTTPS switched off!"
}
It works, but set avary good server from the array. But I need only one server change. How to stop it after first successed server?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to optimize DNS (and DoH) checker script?

Sat Jan 14, 2023 8:50 pm

Now my actual problem that Google DoH URL is "https://dns.google/dns-query", but correct URL to check is Google alive - "https://dns.google.com/resolve" and I can not use array of DoHs,
and what's the problem???
you don't have to put the single domain names in the array, but the whole string (before the ? as I suggested) for each domain
 
jovaf32128
just joined
Topic Author
Posts: 24
Joined: Sun Apr 26, 2020 9:22 pm

Re: How to optimize DNS (and DoH) checker script?

Sun Jan 15, 2023 8:08 pm

Now my actual problem that Google DoH URL is "https://dns.google/dns-query", but correct URL to check is Google alive - "https://dns.google.com/resolve" and I can not use array of DoHs,
and what's the problem???
Problem in two different URLs, one for the check
dns.google.com/resolve (and it not works for DoH)
and one for the DoH
dns.google/dns-query (and it now works for the check)
ANd I can use just one of them in my array, right?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to optimize DNS (and DoH) checker script?

Sun Jan 15, 2023 9:17 pm

Ok, this check directly with RFC 8484, you can use only unique array.
dns.google.com no longer exist, permaredirect to dns.google
:global dohquery do={
    ([/tool fetch http-header-field="accept:application/dns-message" url="$1\3Fdns=$2" as-value output=user]->"data")
}

:global q1 [$dohquery "https://dns.google/dns-query"         "AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"]
:global q2 [$dohquery "https://cloudflare-dns.com/dns-query" "AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"]
/sys script environment print

results code

q1 ;\00\00\81\80\00\01\00\01\00\00\00\00\03www\07example\03com\00\00\01\00\01\C0\0C\00\01\00\01\00\00Q\85\00\04]\B8\D8"
q2 ;\00\00\81\80\00\01\00\01\00\00\00\00\03www\07example\03com\00\00\01\00\01\C0\0C\00\01\00\01\00\0154\00\04]\B8\D8"
the ; and " are part of the reply, not a delimiters (; = 0x3B, " = 0x22).
the Q on q1reply is 0x51, and the \0154 are 0x01 and 0x35 0x34
and on both ] = \93
are really this (without translate www, example and com):

decoded code

q1=\3B\00\00\81\80\00\01\00\01\00\00\00\00\03www\07example\03com\00\00\01\00\01\C0\0C\00\01\00\01\00\00\51\85\00\04\5D\B8\D8\22                                                                                                                 
q2=\3B\00\00\81\80\00\01\00\01\00\00\00\00\03www\07example\03com\00\00\01\00\01\C0\0C\00\01\00\01\00\01\35\34\00\04\5D\B8\D8\22
You can read the IP of 93.184.216.34 for the queried A of www.example.com on the last 4 bytes:

IP code

0x5D = 93
0xB8 = 184
0xD8 = 216
0x22 = 34
The AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB is base64 encoded DNS query for A record of www.example.com
\00\00\01\00\00\01\00\00\00\00\00\00\03www\07example\03com\00\00\01\00\01
 
jovaf32128
just joined
Topic Author
Posts: 24
Joined: Sun Apr 26, 2020 9:22 pm

Re: How to optimize DNS (and DoH) checker script?

Mon Jan 16, 2023 2:35 pm

Well, I got final DoH checking script:
:local dohServers {"https://cloudflare-dns.com/dns-query";"https://1.0.0.1/dns-query";"https://dns.google/dns-query";"https://doh.opendns.com/dns-query";"https://dns.quad9.net/dns-query"}
:local dohServerAvailable false
:foreach dohServer in=$dohServers do={
 :if ($dohServerAvailable=false) do={
  :local result yes
  :do {tool fetch url="$dohServer\?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB" output=none dst-path=result http-header-field=accept:application/dns-message} on-error={:set result no}
  :if $result do={
   :if ([/ip dns get use-doh-server] != $dohServer) do={
    /ip dns set servers="" use-doh-server="$dohServer" verify-doh-cert=yes;
    :log warning "DNS over HTTPS => $dohServer"
   }
   :set dohServerAvailable true
  }
 }
}

:if ( $dohServerAvailable = false) do={
  /ip dns set servers="1.1.1.1,8.8.8.8,1.0.0.1,8.8.4.4" use-doh-server="";
  :log warning "DNS over HTTPS switched off!"
}
Main problem with dns.google and 400 Bad Request error was about two different google services for RFC 8484 and JSON requests.
 
BrunoLeao
just joined
Posts: 3
Joined: Thu Jun 11, 2020 3:49 pm
Location: Sao Paulo / Brazil
Contact:

Re: How to optimize DNS (and DoH) checker script?

Mon Oct 23, 2023 11:19 pm

RoS 7.11.2

I see that the main problem is the 1.1.1.2 and 1.0.0.2 goes offline, I just created a netwatch host and switch to put it on/off on verify DoH certs options..
/ip firewall address-list
add address=security.cloudflare-dns.com list=https://security.cloudflare-dns.com/dns-query

/ip dns
set allow-remote-requests=yes cache-size=4096KiB doh-max-concurrent-queries=100 doh-max-server-connections=10 doh-timeout=10s servers=8.8.8.8,8.8.4.4 \
    use-doh-server=https://security.cloudflare-dns.com/dns-query verify-doh-cert=yes

/ip dns static
add address=1.1.1.2 name=security.cloudflare-dns.com
add address=1.0.0.2 name=security.cloudflare-dns.com

/tool netwatch
add disabled=no down-script="ip/dns/set verify-doh-cert=no" host=1.1.1.2 http-codes="" test-script="" type=icmp up-script=\
    "ip/dns/set verify-doh-cert=yes" 
   

Who is online

Users browsing this forum: No registered users and 27 guests