<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi,</p>
    <p>--strict-order might be what you are looking for. More comments
      below.<br>
    </p>
    <div class="moz-cite-prefix">On 13. 11. 23 6:34, Evgeny Shatokhin
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAN_soBYXz6A=5oZN6cX8NYnJWnOHwXFVMmrRxP_q-r8SFZiazA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr"><span
          id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402">
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">Hi,</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">We
              have our own DNS proxy implemented, and we are trying to
              integrate it into our existing network stack that
              currently contains NetworkManager + dnsmasq. The plan is
              for our network stack to contain NetworkManager + dnsmasq
              + our DNS proxy.</span></p>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">There
              is a problem I can’t solve, and I was wondering if you may
              point me in the right direction.</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">Our
              DNS proxy runs locally, listens on a local address (e.g.
              127.8.8.8), and proxies all incoming DNS queries to a DNS
              server via DNS-over-HTTPS. It has to do some other things
              too, that’s the reason we had to implement our own DNS
              proxy in the first place.</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">1)
              We would like dnsmasq to send DNS queries to our proxy
              first; and if the proxy misbehaves and does not respond to
              a DNS query within a period of time, we would like dnsmasq
              to send the same query to the network-provided DNS server.
              To implement this behavior, we are dropping a config file
              into /etc/NetworkManager/dnsmasq.d, and the config has a
              line like “server=127.8.8.8”</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">If
              I read the dnsmasq source code correctly, in the presence
              of this config file dnsmasq will always keep 127.8.8.8 as
              the primary resolver, and the network-provided DNS server
              will be used as the secondary resolver. The information
              about the network-provided DNS server is provided by
              NetworkManager via dbus; after the machine gets connected
              to a new network, NetworkManager will send an update to
              dnsmasq (using SetServers/SetServersEx or a similar
              message), and dnsmasq will only update the secondary
              resolver, but it will keep 127.8.8.8 as the primary one.
              Is my understanding correct?</span></p>
        </span></div>
    </blockquote>
    <p>No, unfortunately it won't work as you wish. dnsmasq has
      relatively simple failover algorithm and tries to choose fastest
      responding server, every couple of seconds or every 20 queries or
      so. It does not store any priorities to servers, unless you
      specify --strict-order. Then it tries always in the given order.
      It may work as you want with that added to additional dnsmasq.d
      conf too. I expect file-specified local resolver would be first
      then, because dbus configuration is done asynchronously after the
      start. But I haven't seen any obvious priorities in the code.<br>
    </p>
    <p>But be warned, dnsmasq has somehow poor TCP queries algorithm
      failover. It may have issues on its own. If you have local proxy,
      ensure in problems SERVFAIL status is returned and it does not
      drop queries after timeout. That way dnsmasq should react a good
      way. I were thinking about using dnsdist for similar purpose, as a
      way to have DNS over TLS uplink with dnsmasq. Or stubby as a
      similar replacement. But I have not done serious testing.</p>
    <p>Is the solution you are working on with an open source license?<br>
    </p>
    <blockquote type="cite"
cite="mid:CAN_soBYXz6A=5oZN6cX8NYnJWnOHwXFVMmrRxP_q-r8SFZiazA@mail.gmail.com">
      <div dir="ltr"><span
          id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402"><br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">2)
              Now we get to the problem I am trying to solve. Our proxy
              needs to detect whether we are behind a captive portal. A
              common way to detect captive portals is to open a specific
              URL and check the result. (Our proxy is using </span><a
              href="http://connectivitycheck.gstatic.com/generate_204"
              style="text-decoration-line:none" moz-do-not-send="true"><span
style="font-size:11pt;font-family:Arial,sans-serif;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;text-decoration-line:underline;vertical-align:baseline">http://connectivitycheck.gstatic.com/generate_204</span></a><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">.)
              The problem is that this method works only if the
              network-provided DNS server is used for resolving <a
                href="http://connectivitycheck.gstatic.com"
                moz-do-not-send="true">connectivitycheck.gstatic.com</a>.
              Unfortunately, with the config described in (1), dnsmasq
              will send the DNS query for <a
                href="http://connectivitycheck.gstatic.com"
                moz-do-not-send="true">connectivitycheck.gstatic.com</a>
              to our proxy rather than the network-provided DNS server,
              and the detection method does not work in this case.</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">I’ve
              been looking at potential solutions, and I could see a few
              options.</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">2.a)
              Find another way to detect captive portals. Some way that
              does not attempt to reach any URLs.</span></p>
        </span></div>
    </blockquote>
    There is DHCP option for captive portal detection (RFC 8910). It
    would not work always, but Android is using it already, I think
    Windows and Apple systems too. Unfortunately Network Manager does
    not support it yet. Network Manager already does captive portal
    detection. If possible, watch status of NetworkManager via nmcli
    general. Better over dbus api. It should tell you a hint, that some
    action might be needed. With strict-order and always sending
    SERVFAIL from your proxy, it might be sufficient to have short
    timeout before first query after connecting to current network is
    completed (nm connectivity full).<br>
    <blockquote type="cite"
cite="mid:CAN_soBYXz6A=5oZN6cX8NYnJWnOHwXFVMmrRxP_q-r8SFZiazA@mail.gmail.com">
      <div dir="ltr"><span
          id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402"><br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">2.b)
              Could dnsmasq be configured to send DNS queries for a
              specific domain name straight to the secondary resolver?
              Then we would configure dnsmasq to ignore the primary
              resolver 127.8.8.8 and use the network-provided DNS server
              when resolving </span><span
style="font-size:11pt;font-family:Arial,sans-serif;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;text-decoration-line:underline;vertical-align:baseline"><a
                href="http://connectivitycheck.gstatic.com"
                moz-do-not-send="true">connectivitycheck.gstatic.com</a></span><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">.</span></p>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">I
              have found options in the configs that allow sending a
              specific domain to a specific DNS server address, but that
              is not exactly what we need as we do not know the address
              of the network-provided DNS server in advance.</span></p>
        </span></div>
    </blockquote>
    Yes, you can do --server=/<a
      href="http://connectivitycheck.gstatic.com">connectivitycheck.gstatic.com</a>/8.8.8.8,
    but you would have to know what special domains to send to local
    resolvers provided by network. Unfortunately such list is usually
    not provided. Often ipv4.dns-search list is misused for that purpose
    and NM will configure that for you. Check journalctl -xeu
    NetworkManager with dns=dnsmasq configured in NM. Provisioning
    Domains should help, but NM does not support RFC 7556 also.<span
      id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402"><span
style="font-size:11pt;font-family:Arial,sans-serif;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;text-decoration-line:underline;vertical-align:baseline"><br>
      </span></span>
    <blockquote type="cite"
cite="mid:CAN_soBYXz6A=5oZN6cX8NYnJWnOHwXFVMmrRxP_q-r8SFZiazA@mail.gmail.com">
      <div dir="ltr"><span
          id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402"><br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">2.c)
              If our proxy could know the address of the
              network-provided DNS server, it could use that specific
              DNS address when reaching to </span><a
              href="http://connectivitycheck.gstatic.com/generate_204"
              style="text-decoration-line:none" moz-do-not-send="true"><span
style="font-size:11pt;font-family:Arial,sans-serif;background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;text-decoration-line:underline;vertical-align:baseline">http://connectivitycheck.gstatic.com/generate_204</span></a></p>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">The
              problem is that only dnsmasq holds the information about
              the current network-provided DNS server. And I could not
              find any way to get this information from dnsmasq via
              dbus. dnsmasq supports messages like “SetServers” but
              nothing like “GetServers”.</span></p>
          <br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">Is
              getting the network-provided DNS server (or,
              alternatively, the full list of DNS servers) something
              that is or could be supported by dnsmasq?</span></p>
        </span></div>
    </blockquote>
    <p>There is NM plugin to push network servers to dnsmasq via dbus. I
      suggest you use DBus to get servers from NM. That knows dns
      servers too, but I think does not offer simple way as well.
      Unfortunately memory structures used in dnsmasq does not offer
      simple way to do GetServers implementation. Even printing used
      servers into the log is somehow incomplete. I think it would
      require refactoring to implement GetServers properly. With current
      structures it would be inefficient, but still possible.<br>
    </p>
    <p>We are working on dnsconfd [1] prototype, which sometime in the
      future might be able to handle similar situations, but we are not
      there yet. Captive portal processing is one of reasons for its
      existence, especially if they should be followed by encrypted DNS
      channel. But current code won't help you, it barely does basic
      configuration now. We want unbound to be primary handling software
      now, but our idea is every capable DNS cache/proxy should work
      with it too, with just thin specialized module. Including dnsmasq
      in the future. But we are still far from that.<br>
    </p>
    <blockquote type="cite"
cite="mid:CAN_soBYXz6A=5oZN6cX8NYnJWnOHwXFVMmrRxP_q-r8SFZiazA@mail.gmail.com">
      <div dir="ltr"><span
          id="gmail-docs-internal-guid-dbe70189-7fff-45cb-3bf6-e9c8f8104402"><br>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">Thanks,</span></p>
          <p dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span
style="font-size:11pt;font-family:Arial,sans-serif;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;font-variant-alternates:normal;vertical-align:baseline">Evgeny</span></p>
        </span><br class="gmail-Apple-interchange-newline">
      </div>
    </blockquote>
    Cheers,<br>
    Petr
    <p>1. <a class="moz-txt-link-freetext" href="https://github.com/InfrastructureServices/dnsconfd">https://github.com/InfrastructureServices/dnsconfd</a></p>
    <p><br>
    </p>
    <p></p>
    <pre class="moz-signature" cols="72">-- 
Petr Menšík
Software Engineer, RHEL
Red Hat, <a class="moz-txt-link-freetext" href="http://www.redhat.com/">http://www.redhat.com/</a>
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB</pre>
  </body>
</html>