Asking for scripting assistance - DoH Healthcheck

I want to create a service health check script that monitors my DoHs. I couldn’t get it done with my poor scripting skill.
I surely appreciate any help.
Original script

:log info "DNS HealthCheck Started"
:local currentDNS [/ip dns get use-doh-server]
:local DoHMain "https://record.domain-A.tld/dns-query"
:local DoHSec "https://record.domain-B.tld/dns-query"
:local TDomain "www.domain.tld"

:if ($currentDNS =$DoHMain) do={
    :do {
        :resolve $TDomain
    } on-error={
        /ip dns set use-doh-server=$DoHSec
		:log info message="DOH Server=$DoHSec"
    }
} 
:delay 180s
else={
    :do {
        /ip dns set use-doh-server=$DoHMain
        :resolve $TDomain
            :log info message="DOH Server=$DoHMain""
    } on-error={
	    /ip dns set use-doh-server=$DoHSec
		:log info message="DOH Server=$DoHSec"
    }
}

:log info "DNS HealthCheck Done"

Why you simply do not use the “original script” linked?

Hi, It doesn’t work with DoH. :frowning:

This command doesn’t exist. :unamused:
:put [resolve www.domain.tld use-doh-server=“server” ]
2023-05-29_03-45-13.jpg

Mmm… let me think… (or better, let me search the post I already wrote…)

http://forum.mikrotik.com/t/how-to-optimize-dns-and-doh-checker-script/163565/5

I tried the final script, but it didn’t work even with the default request record of www.example.com.
How should I encode the requested record? I have tried several online Base64url encoders, none of which worked with the error status “400 bad requests”.
2023-05-29_05-02-23.jpg
.

PS C:\Users\user> echo 'www.example.com' | openssl base64
d3d3LmV4YW1wbGUuY29tDQo=
PS C:\Users\user> echo -n 'AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB' | openssl base64 --decode
base64: Unknown cipher: decode
base64: Use -help for summary.
904E0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto\evp\evp_fetch.c:341:Global default library context, Algorithm (decode : 0), Properties (<null>)

.

:local dohServers {"https://record.domain.tld/dns-query";"https://record.domain.tld/dns-query";"https://record.domain.tld/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!"

I can’t test your own DoH server.
If is not configured correctly for support RFC 8484 like google or cloudflare, I can not help you…


About the base64… is not www.example.com converted on base64, but is the query on RFC 8484 format…
Is written clearly, read more carefully
http://forum.mikrotik.com/t/how-to-optimize-dns-and-doh-checker-script/163565/5

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

Use something that works :wink:
http://forum.mikrotik.com/t/base64-and-sha256-function-for-scripting/164889/4
> :global test [$base64dec “AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB”]
> /system script environment
/system script environment> print

NAME VALUE

0 base64dec ;(eval / […]
1 test \00\00\01\00\00\01\00\00\00\00\00\00\03www\07example\03com\00\00\01\00\01
/system script environment>

Okay, I will keep the default one for now. Can you check the functionality of the script? My DOH is an Adguard-home container. It responded to the default record in the terminal.
Well, thank you. I’m reading the http://forum.mikrotik.com/t/how-to-optimize-dns-and-doh-checker-script/163565/5 right now.

What are these in the value?
I can’t understand how to construct my request record. :smiley:
2023-05-29_07-11-27.jpg

(you use parameters from $str2base64 instead of the appropriate for $base64dec, “url” and “nopad” must not be used on DNS query)

the (really are not [ and ] but a special character that represent unprintable characters) are presents
because NULL 0x00, SOH 0x01 and other special characters really are hex values of the DNS query following RFC 8484.

For compose your own string, replace the value in this:
\00\00\01\00\00\01\00\00\00\00\00\00

  • length of the next part on hex \03
  • next part “www”
  • length of the next part on hex \07
  • next part “example”
  • length of the next part on hex \03
  • next part “com”
    \00\00\01\00\01

for example for smtp.mypreferreddonmain.cloud = 4 + 18 (0x12) + 5

\00\00\01\00\00\01\00\00\00\00\00\00\04smtp\12mypreferreddonmain\05cloud\00\00\01\00\01

and for encode it:
http://forum.mikrotik.com/t/base64-and-sha256-function-for-scripting/164889/3] > :put [$str2base64 (“\00\00\01\00\00\01\00\00\00\00\00\00\04smtp\12mypreferreddonmain\05cloud\00\00\01\00\01”)]
AAABAAABAAAAAAAABHNtdHASbXlwcmVmZXJyZWRkb25tYWluBWNsb3VkAAABAAE=

Thank you, Finally.

:put [$str2base64 ("\00\00\01\00\00\01\00\00\00\00\00\00\03wwww\07example\03com\00\00\01\00\01") "nopad"]
AAABAAABAAAAAAAAA3d3d3cHZXhhbXBsZQNjb20AAAEAAQ
:put [$str2base64 ("\00\00\01\00\00\01\00\00\00\00\00\00\03wwww\06google\03com\00\00\01\00\01") "nopad"]
AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE

.

:put [$str2base64 ("\00\00\01\00\00\01\00\00\00\00\00\00\03www\06google\03com\00\00\01\00\01") "nopad"]
AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE
/tool fetch url="https://record.domain.tdl/dns-query\?dns=AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE" output=user dst-pat
h=result http-header-field=accept:application/dns-message
      status: finished
  downloaded: 0KiBC-z pause]
        data: ��wwwgooglecom�
                                    {��i�
                                             {��c�
                                                      {��g�
                                                               {����
                                                                        {��h�
                                                                                 {��j

Again @extended rescued me. <3
2023-05-29_15-21-19.jpg

yes :sunglasses:

Hi @own3r1138 , could you please post your working script? This is exactly what I am trying to set up now as well and am failing at the check if doh works script part.
I am not using the certificate verification in my case
Thanks!

Script

:local dohServers {"https://record-a.domain.tld/dns-query";"https://record-b.domain.tld/dns-query";"https://record-c.domain.tld/dns-query";"https://record-d.domain.tld/dns-query"}
:local dohServerAvailable false
:foreach dohServer in=$dohServers do={
 :if ($dohServerAvailable=false) do={
 :local resultDoH true
 :do {tool fetch url="$dohServer\?dns=AAABAAABAAAAAAAAA3d3dwZnb29nbGUDY29tAAABAAE" output=none dst-path=result http-header-field=accept:application/dns-message} on-error={:set resultDoH false}
  :if $resultDoH do={
  :if ([/ip dns get use-doh-server] != $dohServer) do={
      /ip dns set servers="" use-doh-server="$dohServer" verify-doh-cert=yes;
   :log warning "The DoH server changed to $dohServer."
   }
   :set dohServerAvailable true
  }
 }
}