8

I would like to ask a question about configuring of dnsmasq DNS server. I know about such configuration option as "listen-address". But even if I set this option to "listen-address=127.0.0.1" dnsmasq still open port on both internal 127.0.0.1:53 and external 192.168.x.x:53 sides.

So I would like to ask if it is possible to configure dnsmasq so that it opens port 53 just for localhost (127.0.0.1) like for example it is possible for MySQL database.

# Configuration file for dnsmasq.

port=53
proxy-dnssec
no-resolv
no-poll
server=127.0.0.1#[some port here]
server=127.0.0.1#[some another port here]
listen-address=127.0.0.1
no-hosts
D.K.
  • 91
  • 1
  • 1
  • 3
  • Sure you can. Please post your configuration file and the transcript. Of course, don't forget a sanity check: stop dnsmasq and verify if nothing else listens on 53 on external interface. – techraf Aug 26 '16 at 01:00
  • @techraf # Configuration file for dnsmasq. port=53 proxy-dnssec no-resolv no-poll server=127.0.0.1#[some port here] server=127.0.0.1#[some another port here] listen-address=127.0.0.1 no-hosts Also when I stop dnsmasq service so port 53 is closed on 127.0.0.1 and 192.168.x.x sides. – D.K. Aug 27 '16 at 01:48

3 Answers3

16

I had to add "bind-interfaces" to the config file, so that interface and listen-address had the desired effect. E.g.:

listen-address=127.0.0.1
interface=lo
bind-interfaces

This will have the desired effect of listening only on localhost. I was running into issues, since I was running a public dns (that resolves just my own domains) on the public ip of the server, but I wanted to run dnsmasq on localhost, too. So if I remove "bind-interfaces", I will get "dnsmasq: failed to create listening socket for port 53: Address already in use", as it tries to listen on the public IP.

shapecatcher
  • 161
  • 1
  • 3
4

Yes you can do that

The dnsmasq man page says this about the --interface argument:

 -i, --interface=<interface name>
          Listen only on the specified interface(s). Dnsmasq automatically adds the loopback (local) interface to the list of interfaces  to  use
          when  the  --interface option  is used. If no --interface or --listen-address options are given dnsmasq listens on all available inter‐
          faces except any given in --except-interface options. IP alias interfaces (eg "eth1:0") cannot be used with  --interface  or  --except-
          interface  options,  use  --listen-address  instead.  A  simple  wildcard, consisting of a trailing '*', can be used in --interface and
          --except-interface options.

The interface name for localhost/127.0.0.1 would be lo by default on most systems.

You can put it right in your config file like so

interface=lo

Or specify it on the command line like so

dnsmasq --interface=lo
Ryan Babchishin
  • 6,260
  • 2
  • 17
  • 37
  • 1
    I tried your advice, Ryan, but unfortunatelly such way it still opens port on external side. Also when interface is set like "interface=lo" dnsmasq always response to request like "dig @192.168.x.x" even if "listen-address=127.0.0.1" But when "interface" option is commented out dnsmasq follows "listen-address" option and response just to "dig @127.0.0.1" if "listen-address=127.0.0.1" – D.K. Aug 27 '16 at 01:29
  • @LargoWinch That doesn't make sense. And, in your question you said `listen-address` didn't work, and that was why you were asking for help. What's going on? – Ryan Babchishin Aug 27 '16 at 01:48
  • There are 2 thing here. 1) Dnsmasq **always** opens ports on 127.0.0.1 and 192.168.x.x (I check this with nmap) 2) another thing is dnsmasq respons on just "@127.0.0.1" when "listen-address=127.0.0.1". When I set "interface=lo" dnsmasq starts to ignore "listen-address=127.0.0.1" and answers requests for "@192.168.x.x". But my question was if it is possible to do so that dnsmasq not open port on 192.168.x.x side at all. For now I managed to do just so that dnsmasq opens port on both sides but ignores requests "@192.168.x.x". – D.K. Aug 27 '16 at 01:57
  • @LargoWinch try to pass --interface=lo on the command line to dnsmasq instead. – Ryan Babchishin Aug 27 '16 at 03:12
  • This is how I tried, Ryan: dnsmasq is run as service, so line for starting looks like this one. (ExecStart=/usr/bin/dnsmasq -k --enable-dbus --user=dnsmasq --pid-file --interface=lo). So I tested and results was the same as with changes in configuration. Dnsmasq just ignores "listen-address" in this case and ports being still opened both sides. – D.K. Aug 27 '16 at 10:07
  • @LargoWinch Interesting, it sounds like you might have found a bug. Your only option may be to report it if you don't want to work around it. What is your OS and DNSMasq version? – Ryan Babchishin Aug 27 '16 at 13:23
  • Yes, maybe the fastest way to clarify this case will be just to report this as an issue to developers. I think I will try this. Should I delete this question or mark it in title as [CLOSED] for example. What is the common practice on this? As about my system there is: OS: Arch Linux x86_64 Linux 4.7.2-1-ARCH, and DNSMasq: version 2.76 – D.K. Aug 27 '16 at 16:56
  • Yes and nice to use interface rather than the address since then both ipv4 and ipv6 are added. I needed to specify `bind-interfaces` to get this working on rhel7. Otherwise it was listening on '*:53'. The comments are a little vague in the conf file "On systems which support it..." – JGurtz Jul 31 '20 at 00:43
0

This idiotic programme can NOT be prevented from listening on all ports short of editing the code and recompiling it. The "bind-interfaces" option is useless, it will prevent any access from other machines on the intranet. I want it to be accessible on the intrAnet, but not the internet. But it insists on listening on udp6, which is obviously global. The description babbles something about

It then  discards  requests  that it shouldn't reply to...

The question is just what how it defines "should". What it definitely should NOT do is allow access over ipv6 to every single moron who thinks it funny to connect to my dnsmasq server to use it as his DNS resolver. This programme is a HUGE security hole.

Plus, dnsmasq is listening on tcp + tcp6. What, something has changed in the last 2 minutes? Because DNS was an udp protocol two minutes ago when my browser queried google DNS to access this very site. But hey, maybe they changed that and DNS is tcp now.

So, anyway, first download the source:

https://thekelleys.org.uk/gitweb/?p=dnsmasq.git

Then, in network.c , function "make_sock", right at the beginning:

if (family == AF_INET6 || type == SOCK_STREAM) return 1;

Look, it listens on udp only now, and DNS gets resolved all right! Phew! I was afraid they changed the way DNS was working, lol.

netstat -an | grep :53

udp        0      0 0.0.0.0:53              0.0.0.0:*

lsof -c dnsmasq | grep IPv

dnsmasq 473 root    4u     IPv4              24618      0t0   UDP *:domain
WRFan
  • 19
  • 1
  • DNS `should` always be able to use TCP. See https://datatracker.ietf.org/doc/html/rfc1123#section-6.1.3.2 from 1989 `DNS servers MUST be able to service UDP queries and SHOULD be able to service TCP queries. A name server MAY limit the resources it devotes to TCP queries, but it SHOULD NOT refuse to service a TCP query just because it would have succeeded with UDP.` DNS responses over 4096 bytes will be returned with a `TR` bit set (truncated) and the client should retry over TCP. This is common in regular operation in the last 15 years due to larger record sizes (DNSSEC and IPv6 AAAA). – batfastad Oct 27 '21 at 15:47