blueman
blueman copied to clipboard
Blueman does not provide DNS information when using Network Access Point (NAP)
blueman:2.1.2-1ubuntu0.2
My phone failed to load any web page when I connected it to my computer. I noticed Blueman created a dnsmasq process:
/usr/sbin/dnsmasq --port=0 --pid-file=/var/run/dnsmasq.pan1.pid --except-interface=lo --interface=pan1 --bind-interfaces --dhcp-range=10.42.1.2,10.42.1.254,60m --dhcp-option=option:router,10.42.1.1
The only thing missing in the argument is DNS information. Perhaps blueman don't want to setup dnsmasq as a DNS server (since port=0 is in the argument, meaning DNS server is explicitly disabled), but it should still provide DNS information to tell the device how to do name resolving.
So I killed the dnsmasq process created by blueman, and ran this command:
/usr/sbin/dnsmasq --port=0 --pid-file=/var/run/dnsmasq.pan1.pid --except-interface=lo --interface=pan1 --bind-interfaces --dhcp-range=10.42.1.2,10.42.1.254,60m --dhcp-option=option:router,10.42.1.1 --dhcp-option=option:dns-server,1.1.1.1
I just added --dhcp-option=option:dns-server,1.1.1.1, then everything works fine.
I think perhaps blueman should:
- Enable DNS service in
dnsmasq(thendnsmasqwill automatically provide DNS information to its DHCP clients, you don't need--dhcp-option=option:dns-server)
or
- Provide DNS information to DHCP clients using
--dhcp-option=option:dns-server. You may want to let the user specify which DNS server they want to use in the GUI.
We actually disabled the DNS service as it causes things to fail if the host already has another DNS service running, see #943.
I guess it's a valid request, though, yes. We're setting a default route, so cannot argue that we wouldn't do any extra configuration at all. :sweat_smile:
For dnsmasq we could add a checkbox to enable the service. Alternatively or additionally we could let the user specify DNS servers for any handler (besides dnsmasq we also support dhcpd and udhcpd).
@cschramm Thanks for the comment. And it seems not very hard to implement (though I've no idea how to support other handlers like the ones you mentioned)
Damned if you do and damned if you don't :sob: :smile:. I think the quick fix is to have a checkbox, disable dnsmasq dns, enabled by default. Then you can untick it if you want it to deal with dns.
I found the place where dnsmasq cmdline is defined ... we can just add --dhcp-option=option:dns-server here
https://github.com/blueman-project/blueman/blob/08bbd44a9fe63464946b372bc1eaa07898dcb583/blueman/main/NetConf.py#L94-L97
Anyone want to support dhcpd and udhcpd? I don't know much about them.
I checked dncpd and udhcpd handlers, and found out they both get dns information from this get_dns_servers() function:
https://github.com/blueman-project/blueman/blob/08bbd44a9fe63464946b372bc1eaa07898dcb583/blueman/main/NetConf.py#L60-L70
I have to say this is a very very bad idea. Since the DNS servers defined for the host may not be available for the guest.
For example, systems using "systemd-resolved" usually use 127.0.0.53 as dns server. (if your /etc/resolv.conf is a symlink, then you are likely using "systemd-resolved")
On my system, I use 127.0.0.1 because it runs pihole, and all the dns queries should go through pihole.
We're fiddling with systemd-resolved in #1544 / #1553.
I think the straightforward solution for when a local DNS service (other than systemd-resolved) is used is to use dnsmasq's DNS service as a proxy to it. We can achieve that by not setting --port=0. That should work fine if the local DNS service e.g. binds to 127.0.0.1.
However, dnsmasq will fail if a local DNS service binds to the wildcard address. In case of https://github.com/blueman-project/blueman/issues/943#issue-384699056 I suppose that the unrelated already running instance of dnsmasq did not use --bind-interfaces so that it bound to the wildcard instance. In that case we cannot use dnsmasq's DNS service at all.
I guess the full-blown solution would be to add a check if a DNS service is bound to the wildcard address and disable dnsmasq's DNS service only if there is one, providing its server address as a DNS server to the clients. We then expect the existing service to just work for them.
Good to know you are already trying to fix "systemd-resolved". Your solution sounds good. The steps can be:
- Create a socket and bind port 53 in python
- If 1 failed, catch the exception and start dnsmasq with
--port=0and--dhcp-option=option:dns-server - If 1 succeeded, close the socket and start dnsmasq without
--port=0
I believe your solution works for dnsmasq. But how about dhcpd and udhcpd? I don't know much about them so I don't know if they provide the same functionality. If they both can run as DNS servers then your solution is perfect.
Yes, and in step 2 I'd set dns-server to the same address as router. As something is listening on the wildcard address, I'd just expect it to work (otherwise there's not much we can do for dynamic configuration).
I'm actually wondering if and how the current implementation provides a working setup to the clients as I think it does not set a DNS server at all, does it? :thinking:
dhcpd and udhcpd do not have DNS services. We could substitue local addresses found in /etc/resolv.conf with the router address to make it work in case of a wildcard-bound service. In case of a local-only service I'd advise to use dnsmasq for forwarding or set up another DNS service that binds to the wildcard address. I don't see much more we could do for a dynamic configuration if none of the known name servers is reachable to the client.
I drafted #1565 for this, based on the refactorings in #1564.