[SOLVED - PEBCAK] Why does dnsmasq relink /tmp/resolv.conf when stopping?

Hi all,
I was fighting with my resolv.conf file being changed unexpectedly. Long story short, I sometimes set it to some other variants that I have by relinking /tmp/resolv.conf to specific files. And I don't want my device to revert to the .auto version just because one instance of dnsmasq that used it is stopped (as it would for example leak traffic to my ISP).

The code I'm reffering to is that when dnsmasq stops an instance and that instance has a resolvfile matching "/tmp/resolv.conf.auto", it relinks /tmp/resolv.conf to the .auto file.

See code snippet here (sic)
	#relink /tmp/resolve.conf only for main instance
	[ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
		[ -f /tmp/resolv.conf ] && {
			rm -f /tmp/resolv.conf
			ln -s "$resolvfile" /tmp/resolv.conf
		}
	}

I'm really not sure why this is since I can't find any place where dnsmasq would set that file to some other value that would need to be reverted. And if it's not the owner of that file in the first place, why would it go and change it?

For info, I had a look at unbound, and it does the same unless dnsmasq is also present. (i.e. are all dns/dhcp servers worrying about setting /tmp/resolv.conf back when stopping?)

Anyone has an explanation for this?

Some clues might be found at [Solved] Dnsmasq resolv.conf inconsitent

Thanks for the link @jeff , that's quite clear. I think I understand the flow of routing and the use of each resolv.conf (apart from my question).

Let me give an example.
I use three dnsmasq instances:

  1. uses resolv.conf.auto i.e. my ISP DNS
  2. uses google DNS for some of my devices
  3. uses my VPN provider DNS for traffic that goes through VPN

I then relink /tmp/resolv.conf to a file that contains my VPN DNS servers.

Following this, if I stop the first dnsmasq instance, /tmp/resolv.conf gets changed back to /tmp/resolv.conf.auto (as the resolvfile matches). This means my DNS now leaks to my ISP instead of going trough my VPN tunnel.

I gave up on fighting "helpful" auto-configuration for things that are static. It doesn't sound like your DNS changes with time, especially if you don't "need" your ISP's DNS servers. I'd make the config static, in /etc and change the dnsmasq or unbound conf file used for the instance's invocation.

If you're using Google DNS for some of your devices, why not just send that in DHCP and don't bother with caching it in your router?

Also, you could run unbound and go straight to the root (through the VPN) if privacy is a concern. You can also configure it to send certain domains to certain servers, such as needed for corporate VPN access.

@VincentR - I think the relinking when resolv.conf.auto is configured is to ensure behaviour compatibility with old dnsmasq init. Note however that the init script only ever deals with /tmp/resolv.conf. The /etc/resolv.conf -> /tmp/resolv.conf symlink is shipped with the image but never altered. So if you want a persistent resolv.conf, simply drop the symlink and replace it with a plain file.

1 Like

Thanks for the info.

@jeff, sending DNS to devices doesn't mean they use the suggested settings. Also, my real scenario is quite a bit more complex.
@jow, since you mention it is for compatibility, I'm going to run a version of the init that doesn't relink. Mostly because my scenario involves switching between different static resolv.conf (and I don't want to persist the last used one at restart which would happen if I symlinked/hardcoded the /etc one).

I'm considering this closed. Thanks again

By the way, rereading this properly on a Monday as opposed to a Friday and things get clearer.

The question stemmed from my own misreading. I had already modified my dnsmasq.init to remove the rewriting of /tmp/resolv.conf in dnsmasq_start and this is why I didn't understand the dnsmasq_stop code anymore.

For reference, the code that modifies the file in the first place is:

these couple of lines...
	[ "$resolvfile" = "/tmp/resolv.conf.auto" ] && {
		rm -f /tmp/resolv.conf
		[ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
			echo "search $DOMAIN" >> /tmp/resolv.conf
		}
		DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
		for DNS_SERVER in $DNS_SERVERS ; do
			echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
		done
	}

Thanks again for help and sorry for the confusion

This topic was automatically closed 6 days after the last reply. New replies are no longer allowed.