Initializing DNS in dnsmasq before leases assigned

0

I am in the process of transferring DHCP/DNS services for my LAN from a system running wheezy to a system running stretch. Both DHCP and DNS are provided by dnsmasq.

What I'm seeing, at least with the way that I've configured dnsmasq on the new machine, is that the DNS service it provides only knows about devices that have gotten DHCP leases from it. I had assumed it would be able to resolve devices which I had assigned a fixed IP address to in dnsmasq.conf even before they requested a new DHCP lease. But apparently that's not the case...or I've misconfigured something.

For example, despite this entry in dnsmasq.conf:

dhcp-host=1C:6F:65:39:09:8D,colossus,10.0.0.8

doing an nslookup on colossus, or colossus.localnet (that being the name I've assigned for my LAN), fails.

Is there a way to configure dnsmasq so it resolves devices with fixed IP addresses before leases are assigned?

Alternatively, since stretch uses resolvconf and dhcpcd and overwrites both /etc/resolv.conf and /run/dnsmasq/resolv.conf, where should I put the fixed IP addresses so they'll be resolved even before leases are assigned? I thought about putting them in resolv.conf.tail, but that seems kludgy.

Mark Olbert

Posted 2018-11-15T23:36:51.363

Reputation: 245

Answers

1

I tested this on debian wheezy and jessie and the OP confirmed it working on stretch as well. Stretch and jessie do use resolvconf, wheezy does not.

Just put all your fixed IP-addresses into the /etc/hosts file local to the host running dnsmasq. You here add hosts with fixed addresses on your local network (domain local.net, IP 192.168.0.xxx in this example) or hosts you want to override locally for some reason or another:

# /etc/hosts
# the local host
127.0.0.1       localhost

# provide fixed addresses used by dnsmasq for the local network
192.168.0.100   host0.local.net             host0
192.168.0.101   host1.local.net             host1
192.168.0.102   host2.local.net             host2

# map a fancy service to the same address as above (e.g. on host2)
192.168.0.102   imap.local.net              imap
192.168.0.102   mediaserver.local.net       mediaserver

# overwrite an external host with address 1.2.3.4
1.2.3.4    some.external-host.com
# map unwanted external hosts to localhost
127.0.0.1  some.malicious-advertising-server.com

Dnsmasq reads the hosts file preferably to calling external resolvers. So all IPs in that file should be available before any of those hosts ask for a lease (or even runs). Make sure that the following is outcommented in your /etc/dnsmasq.conf:

# /etc/dnsmasq.conf
...
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
#no-hosts
...

If your domain local.net is not a publically available domain, put it into the following clause to prevent dnsmaq from querying upstream resolvers on non-existant domains:

# /etc/dnsmasq.conf
...
# Add local-only domains here, queries in these domains are answered
# from /etc/hosts or DHCP only.
local=/local.net/
...

You might want to check out some more options regarding the /etc/hosts file in the /etc/dnsmasq.conf. The surrounding comments are quite informative.

Now you want to map your physical hosts to those IP-addresses. If not present, create the file /etc/ethers. In this file you put the MAC-adresses of all hosts that should get a fixed IP-Address, followed by their appropriate dns-name:

# /etc/ethers
1C:6F:65:39:09:8D host0.local.net
1C:6F:65:39:19:8D host1.local.net
1C:6F:65:39:29:8D host2.local.net

You only need your physical hosts, not the additional service names you defined in the /etc/hosts file above. Go back to your /etc/dnsmasq.conf and check that reading of /etc/ethers is enabled:

# /etc/dnsmasq.conf
...
# If this line is uncommented, dnsmasq will read /etc/ethers and act
# on the ethernet-address/IP pairs found there just as if they had
# been given as --dhcp-host options. Useful if you keep
# MAC-address/host mappings there for other purposes.
read-ethers

Again there are more options regarding /etc/ethers. You might want to skim through them, if you look for additional features.

As a third step, you must convince resolveconf to use the local dnsmasq as the first resolver. Otherwise the resolving won't work correctly for dynamic leases (not the fixed ones configured above) on the very host running dnsmasq. This is how my /etc/resolvconf.conf looks like:

# /etc/resolvconf.conf
# Configuration for resolvconf(8)
# See resolvconf.conf(5) for details

resolv_conf=/etc/resolv.conf
# If you run a local name server, you should uncomment the below line and
# configure your subscribers configuration files below.
name_servers=127.0.0.1

# Mirror the Debian package defaults for the below resolvers
# so that resolvconf integrates seemlessly.
dnsmasq_resolv=/var/run/dnsmasq/resolv.conf
pdnsd_conf=/etc/pdnsd.conf
unbound_conf=/var/cache/unbound/resolvconf_resolvers.conf

The key line here is:

# /etc/resolvconf.conf
...
name_servers=127.0.0.1
...

It tells the resolver to use the local host as a first resolver. The problem here is that dnsmasq uses resolvconf as well, to resolve unknown addresses. But don't worry, dnsmasq is smart enough to avoid calling itself in recursive loops.

One last (probably obvious) thing: If you define a dynamic IP range as well, e.g. for guests, mobile devices etc., make sure that it does not collide with the addresses given in /etc/hosts:

# /etc/dnsmasq.conf
...
# Uncomment this to enable the integrated DHCP server, you need
# to supply the range of addresses available for lease and optionally
# a lease time. If you have more than one network, you will need to
# repeat this for each network on which you want to supply DHCP
# service.
dhcp-range=192.168.0.50,192.168.0.99,12h
# this range must not include above addresses given in /etc/hosts
...

Now dnsmaq get's the IP-addresses from the /etc/hosts file, regardless of an existing lease. DHCP requests resolve the MAC-adress using /etc/ethers to a domain-name which again is resolved to an IP using /etc/hosts.

So you can configure hosts and ethers neatly in separate files and don't need to put every host into your /etc/dnsmaq.conf with the dhcp-host...` option.

Holger Böhnke

Posted 2018-11-15T23:36:51.363

Reputation: 126

Thank you, @Holger! For both the answer and the thorough explanation of why it's a good way to configure the server. I now have a much clearer idea of how dnsmasq, debian, dhcp and dns fit together. Plus, I like the fact that the various configuration details aren't duplicated in various places (e.g., dnsmasq.conf and hosts). – Mark Olbert – 2018-11-18T01:30:49.767

@MarkOlbert You're welcome. So I recon you got it working on stretch? If so, I'll adjust the disclaimer paragraph at the beginning. I currently haven't got the time to try it out on stretch myself. But I will so soon. – Holger Böhnke – 2018-11-18T15:20:08.987

Yep, it's working fine! BTW, here's a post I wrote about my experience, and your critical help in helping me get things working: https://jumpforjoysoftware.com/2018/11/dnsmasq-and-etc-ethers/.

– Mark Olbert – 2018-11-18T18:23:59.883

Thanks @MarkOlbert for confirming that it works on stretch. I changed the disclaimer to include that. Nice blogpost, thanks for the credits. – Holger Böhnke – 2018-11-20T16:26:31.160