[Dnsmasq-discuss] Captive Portals check
Petr Menšík
pemensik at redhat.com
Mon Nov 13 13:09:25 UTC 2023
Hi,
--strict-order might be what you are looking for. More comments below.
On 13. 11. 23 6:34, Evgeny Shatokhin wrote:
>
> Hi,
>
>
> 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.
>
> There is a problem I can’t solve, and I was wondering if you may point
> me in the right direction.
>
>
> 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.
>
>
> 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”
>
>
> 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?
>
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.
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.
Is the solution you are working on with an open source license?
>
> 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 http://connectivitycheck.gstatic.com/generate_204
> <http://connectivitycheck.gstatic.com/generate_204>.) The problem is
> that this method works only if the network-provided DNS server is used
> for resolving connectivitycheck.gstatic.com
> <http://connectivitycheck.gstatic.com>. Unfortunately, with the config
> described in (1), dnsmasq will send the DNS query for
> connectivitycheck.gstatic.com <http://connectivitycheck.gstatic.com>
> to our proxy rather than the network-provided DNS server, and the
> detection method does not work in this case.
>
>
> I’ve been looking at potential solutions, and I could see a few options.
>
>
> 2.a) Find another way to detect captive portals. Some way that does
> not attempt to reach any URLs.
>
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).
>
> 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
> connectivitycheck.gstatic.com <http://connectivitycheck.gstatic.com>.
>
> 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.
>
Yes, you can do --server=/connectivitycheck.gstatic.com
<http://connectivitycheck.gstatic.com>/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.
>
> 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
> http://connectivitycheck.gstatic.com/generate_204
> <http://connectivitycheck.gstatic.com/generate_204>
>
> 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”.
>
>
> Is getting the network-provided DNS server (or, alternatively, the
> full list of DNS servers) something that is or could be supported by
> dnsmasq?
>
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.
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.
>
> Thanks,
>
> Evgeny
>
>
Cheers,
Petr
1. https://github.com/InfrastructureServices/dnsconfd
--
Petr Menšík
Software Engineer, RHEL
Red Hat,http://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20231113/952f82a9/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x4931CA5B6C9FC5CB.asc
Type: application/pgp-keys
Size: 9098 bytes
Desc: OpenPGP public key
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20231113/952f82a9/attachment-0001.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20231113/952f82a9/attachment-0001.sig>
More information about the Dnsmasq-discuss
mailing list