Securing DNSMasq

Author: R Zach Feeser

DNSMasq insists on listening on all addresses, port 53. Even when dnsmasq is set to listen to internal interfaces only, it appears to be servicing all interfaces. I’m not the only one that’s living with this. Consider these write-ups:

There will be a happy ending to this story. I’ll show you that dnsmasq does NOT listen on all interfaces if you tell it not to, but let’s test that theory first.

Here is a test configuration that restricts dnsmasq to one ip address only.

dnsmasq.conf
listen-address=10.10.0.1 <---- JUST LISTEN ON THIS INTERNAL ADDRESS
domain-needed
bogus-priv
server=8.8.8.8
expand-hosts
domain=localdomain
strict-order
dhcp-range=10.10.252.2,10.10.255.255,255.255.0.0,2m
dhcp-fqdn
dhcp-option=3,10.10.0.1
dhcp-option=119,localdomain
dhcp-option=15,localdomain
dhcp-hostsfile=/etc/dnsmasq/hosts.static
dhcp-optsfile=/etc/dnsmasq.d/options

Oh no! The socket statistics (ss) command says “port 53 is WIDE OPEN. "

ubuntu@router-10-32:~$ sudo ss -antp
State        Recv-Q       Send-Q             Local Address:Port               Peer Address:Port        Process
LISTEN       0            32                       0.0.0.0:53                      0.0.0.0:*            users:(("dnsmasq",pid=1379,fd=7))

So let’s dig the outside interface of the dnsmaq server

$ dig @a.b.c.d example.com (a.b.c.d is my public ip address)

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @a.b.c.d example.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

GOOD! dnsmasq is not actually listening on all interfaces as we specified.

So if I comment out the listen-address line then it should work on all interfaces.

#listen-address=10.10.0.1 <--- commnet out this line!
domain-needed
bogus-priv
server=8.8.8.8
expand-hosts
domain=localdomain
strict-order
dhcp-range=10.10.252.2,10.10.255.255,255.255.0.0,2m
dhcp-fqdn
dhcp-option=3,10.10.0.1
dhcp-option=119,localdomain
dhcp-option=15,localdomain
dhcp-hostsfile=/etc/dnsmasq/hosts.static
dhcp-optsfile=/etc/dnsmasq.d/options

Restart dnsmasq

sudo systemctl restart dnsmasq

Well now, look at that! It works as expected…

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @a.b.c.d example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32709
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.                       IN      A

;; Query time: 0 msec
;; SERVER: a.b.c.d#53
;; WHEN: Tue Aug 25 01:22:07 UTC 2020
;; MSG SIZE  rcvd: 36

But I don’t want this to work on the internet side, so raise the shields!

listen-address=10.10.0.1 <--- now I know that this actually works!
domain-needed
bogus-priv
server=8.8.8.8
expand-hosts
domain=localdomain
strict-order
dhcp-range=10.10.252.2,10.10.254.255,255.255.0.0,2m
dhcp-fqdn
dhcp-option=3,10.10.0.1
dhcp-option=119,localdomain
dhcp-option=15,localdomain
dhcp-hostsfile=/etc/dnsmasq/hosts.static
dhcp-optsfile=/etc/dnsmasq.d/options

Restart dnsmasq

sudo systemctl restart dnsmasq

OK, dnsmasq is secure again and in spite of what ss -antp tells me

stu@tower2:update-motd.d$ dig @71.251.147.236 sumi-01

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @71.251.147.236 sumi-01
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
stu@tower2:update-motd.d$

Conclusion

If only I had read the man page I would have seen this, which confirms my observations:

-z, --bind-interfaces

dnsmasq binds the wildcard address, even when it’s only listening on some interfaces.

  • It then discards requests that it shouldn’t reply to.
  • This has the advantage of working even when interfaces come and go and change address.
  • This option forces dnsmasq to only bind the interfaces it’s listening on.
  • This option is useful when running another nameserver (or another instance of dnsmasq) on the same machine.
  • This is useful for multiple instances of dnsmasq which provide DHCP service to run in the same machine.