Dnsmasq: can't access server from other devices on LAN

,

Apologies if this turns out to be trivial, but getting dnsmasq to work has completely frustrated and defeated me, after days of faffing around.

I have a bunch of vhosts on a server, and need to access them from other devices. To date, I’ve done this via /etc/hosts on each device. However, an iPad, iPhone and Samsung tablet now also need access, hence looking at dnsmasq.

Fedora 35, installed Nov.2021
Linux 5.15.5-200.fc35.x86_64
dnsmasq v 2.86

/etc/hosts:
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain
192.168.178.9 server.lan
192.168.178.10 laptop.lan
127.0.0.1 vhost1.lan
127.0.0.1 vhost2.lan
… … …

Router: Fritzbox 7490
Local DNS Server: 192.168.178.9 (server)

/etc/NetworkManager/NetworkManager.conf
[main]
dns=none

NM config for wlp5s0 (wifi conn on server)
Method: Manual
Address: 192.168.178.9/24
Gateway: 192.168.178.1 (router)
DNS Servers: 127.0.0.1 (server)
Search domains: localhost

/etc/dnsmasq.conf:
domain-needed
bogus-priv
no-resolv
no-poll
local=/lan/
interface=wlp5s0 (wifi)
listen-address=127.0.0.1 (server)
no-dhcp-interface=wlp5s0
bind-interfaces
address=/lan/127.0.0.1
address=/lan/192.168.178.9

Most of the help on the web uses dnsmasq as both a DNS server and DHCP lessor. I /only/ want to run the DNS server, leaving the router to assign leases as it sees fit.

I couldn’t figure out how to stop NM from running the dnsmasq plugin which was blocking port 53, and ended up killing the process. In case the plugin starts up on next reboot, it would be good to know if there is a better way.

/etc/resolv.conf:
resolv.conf -> /run/systemd/resolve/stub-resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search localhost

$ netstat -tulpn | grep ":53 "

tcp/udp   0   0   192.168.178.9:53   0.0.0.0:*   LISTEN 2250435/dnsmasq
tcp/udp   0   0   127.0.0.1:53       0.0.0.0:*   LISTEN 2250435/dnsmasq     
tcp/udp   0   0   127.0.0.53:53      0.0.0.0:*   LISTEN 2213842/systemd-resolve

/run/systemd/resolve/resolv.conf
nameserver 192.168.178.1
nameserver 127.0.0.1
search localhost

Output from dig on the server:
; <<>> DiG 9.16.28-RH <<>> vhost1.lan
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57328
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;vhost1.lan. IN A
;; ANSWER SECTION:
vhost1.lan. 0 IN A 127.0.0.1
;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun May 22 07:10:27 CEST 2022
;; MSG SIZE rcvd: 55

This is a complex setup, so not easy to pin-point the problem.

dnsmasq started by NetworkManager: is an interface “shared”? In that case NetworkManager controls dhcp, dns, masquerading and routing, and in fact you’re finished then. If you do not want this, you’ve to configure it manually and use dnsmasq for DHCP and/or DNS.

Also systemd-resolved looks involved: may be the parameter “DNSStubListenerExtra” can be used to simply replace dnsmasq’s DNS functionality.

What in any case is wrong: the vhosts should not have 127.0.0.1, but the server.lan address. 127.0.0.1 is only local host, so the iPhone, ipad access there own localhost instead of the server…

Good luck!

Thanks for replying, much appreciated.

NetworkManager is no longer using the dnsmasq plugin. I figured out how to stop it, and start dnsmasq standalone.

I did some searching wrt “DNSStubListenerExtra”, and fell over this post, which told me exactly what to do to cut systemd-resolve out of the picture. That also meant the resolv.conf problem just “went away”, and now contains the nameservers it should. So indirectly, thank you.
https://www.mail-archive.com/dnsmasq-discuss@lists.thekelleys.org.uk/msg13069.html

vhosts: I did what you suggested, which got rid of yet another problem.

Now, I think dnsmasq is running very well on the server. That just leaves the “minor” problem of not being able to access any of the vhosts from devices on the LAN. Onward…

Great that you found solutions. But in dnsmasq.conf you tell dnsmasq to listen on the wifi, but not on the LAN. Probably you have to add an “interface” option.

I specifically restricted dnsmasq to listen only on the wifi while I tried to figure out what was going on. Time enough to add ethernet in when I’ve sussed that.

Am now trying to figure out why mDNS doesn’t seem to be broadcasting its presence. I don’t quite understand how this works.

I’m starting to suspect the villain of the piece may be the Fritzbox itself. Irritatingly, it slaps “.fritz.box” onto the end of some - not all - devices. So “server.mydomain.lan” becomes "server.fritz.box. Example run on on the laptop:

laptop$ dig server.mydomain.lan
; <<>> DiG 9.16.24-RH <<>> server.mydomain.lan
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9628
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;server.mydomain.lan. IN A
;; AUTHORITY SECTION:
. 1894 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2022052201 1800 900 604800 86400
;; SERVER: 127.0.0.53#53(127.0.0.53)

But:
laptop$ dig server.fritz.box
; <<>> DiG 9.16.24-RH <<>> server.fritz.box
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46068
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;server.fritz.box. IN A
;; ANSWER SECTION:
server.fritz.box. 9 IN A 192.168.178.9
;; AUTHORITY SECTION:
server.fritz.box. 9 IN NS fritz.box.
;; ADDITIONAL SECTION:
fritz.box. 9 IN A 192.168.178.1
;; SERVER: 127.0.0.53#53(127.0.0.53)

The fritzbox might get a DHCP request with the single word hostname included, and apparently it adds fritz.box as domainname. On my providers’s router, “.home” is appended and I cannot change it. Either you should be able to control Fritz’ DNS server and change domain, or you should change the DNS server the Fritz announces in DHCP answers to your own dnsmasq server, if possible.

mDNS is another story, I do not understand it too yet. But as far I know, the domain should be “.local”, and it does not broadcast. It is multicast: a request is sent out to a special multicast address, 224.0.0.251 port 5353, and every host on the same LAN segment can respond to it. You can ask for services, e.g. _ipp._tcp is a printer, _smb._tcp is a file server.
As far I know, you need to have the avahi-daemon running on each host, programs can register to it and announce their services. systemd-resolved also implements it. But this has nothing to do with DNSMasq.

This is a problem of systemd-resolved, which is enabled by default. Your client uses resolved, which in turn sends all queries to 192.168.178.1. Check current server in resolvectl command output.

Fix this by:

  • systemctl disable --now systemd-resolved
  • dnf remove systemd-resolved
  • rm /etc/resolv.conf
  • create a new resolv.conf pointing to localhost
cat << EOF
nameserver 127.0.0.1
nameserver 192.168.178.1
search lan
EOF
  • systemctl enable --now dnsmasq
  • dig @localhost server.lan - check localhost responds with local name
  • dig server.lan - check it is used by default

By the way, official reserved name instead lan is home.arpa (RFC 8375).