nsd icon indicating copy to clipboard operation
nsd copied to clipboard

Default config should gracefully skip interfaces/ip-adresses where socket is already in use

Open asciiprod opened this issue 3 years ago • 12 comments

Many distributions today use systemd-resolved, which runs on 127.0.0.53:53. Since it is impossible to know which IP addresses or interface will be present on a system, distributions will ship NSD with a more or less empty/default config. This however means that NSD will not start in most cases, which is not the best user experience and leads to unnecessary bug reports like this: https://bugs.launchpad.net/ubuntu/+source/nsd/+bug/1880795

In comparison bind9 without explicit config will simply skip over interfaces/sockets which are already in use and knot-dns will not bind itself to anywhere.

Personally I would consider the first approach more distro-friendly, while the second one might be more admin-friendly.

asciiprod avatar Aug 03 '20 10:08 asciiprod

When I try to replicate this, and I set reuseport: yes this succeeds just fine.

This defines SO_REUSEPORT on the interface, which is faster. But it also permits several programs to bind to the same socket address. And this works for me to bind both 127.0.0.53 and 0.0.0.0 at the same time with different servers.

So I guess if you were to set the reuseport option in the default config file that could solve your problem. Perhaps bind enables this socket option by default (for speed or load balancing reasons perhaps)?

wcawijngaards avatar Aug 03 '20 11:08 wcawijngaards

With a bit more testing, for this to work you have to enable the reuseport option for both servers. And that means also for the systemd-resolvd service, perhaps it already does this, and this is why bind is working.

wcawijngaards avatar Aug 03 '20 11:08 wcawijngaards

Interesting idea, but systemd-resolved may not be the only conflicting service (e.g. libvirt+dnsmasq). Also packages must not change the settings of other packages. On Ubuntu 20.04 (still has 4.1.26), setting reuseport: yes does not lead to successful start

asciiprod avatar Aug 03 '20 11:08 asciiprod

What do you want? Because, I thought it would be SO_REUSEPORT, but it is not. NSD attempts to open the 0.0.0.0 interface and this fails. This is what it does by default.

NSD also offers ip-freebind: yes and ip-transparent: yes that allow binding more interfaces more easily. Does that solve it for you? It may be worth a try.

wcawijngaards avatar Aug 03 '20 11:08 wcawijngaards

Basically I am looking for maintainer-friendly defaults, so distros can ship NSD without extra configuration.

asciiprod avatar Aug 03 '20 12:08 asciiprod

Okay, so I would like that too. I cannot really change the actual default so much because of backwards compatibility, but I am looking at what option you would need to be able to set it in extra configuration you can ship that would make it work.

In this case, however, I don't see a way to change a default either. Because there is no setting that makes it work, it seems.

Is PR #113 something that you would want to solve this? If that feature is added, (and it is just waiting for time now), then that still means shipping extra configuration.

Or perhaps you could list the network interfaces in the post-install script, for NSD to bind to. By using ifconfig or ipcfg and then pipe to grep, then sed to get the addresses, then grep -v to omit 127.0.0.1 and 127.0.0.53 and then perhaps sed again to put interface: "" around it, and then put it in a config snippet file that is shipped as empty in the distribution, and included in the main config file with a include: statement. Then it would bind to interfaces except a couple?

wcawijngaards avatar Aug 03 '20 12:08 wcawijngaards

I am not sure if this helps you, but this script prints a nice list of interface: xx lines for me. ip -o address | sed -e 's/^.*inet //' -e 's/^.*inet6 //' | sed -e 's;^\([^ /]*\).*;interface: \1;' | grep -v -e " 127.0.0.1" -e " ::1" -e " 127.0.0.53" -e " fe80::" You can then > /etc/nsd-interfaces.conf that and include: "/etc/nsd-interfaces.conf" from the nsd.conf file (assuming the nsd config file is in /etc). If you are interested in this style of set up, perhaps this script line can be useful.

wcawijngaards avatar Aug 03 '20 13:08 wcawijngaards

Thanks Wouter, but this kind of shell magic is exactly what I want to avoid. The distro default should be working while being as simple as possible. I would rather ship a config with only ip-address: 127.0.0.1 than generate a list of ip addresses in post-install. However both approaches might brake existing setups on upgrade. That is why I initially asked for a bind-like behavior.

asciiprod avatar Aug 03 '20 13:08 asciiprod

Not sure what that behaviour really is. I think it may do the same as that shell script but as an option, hence my oneliner and reference to the pullrequest with a (similar) option.

What I can do to avoid having ship of config is add a configure --with-some_option=value added flag that allows you to specify a different config option default at package compile time. Perhaps that still surprises some users though?

wcawijngaards avatar Aug 03 '20 13:08 wcawijngaards

The PR might be what I am looking for. Will need to check

asciiprod avatar Aug 03 '20 13:08 asciiprod

The proposed patch does not skip already bind ip address. The patch allow to use interface name to avoid hard coded ip addresses in the configuration file.

iirc to allow gracefully skip ip-adresses where socket is already bind we have to change the behavior of the figure_sockets function to log an warning or error message instead of stop NSD server.

gearnode avatar Aug 04 '20 09:08 gearnode

Yes gearnode, you are right, but if I do that, and NSD skips binding the 0.0.0.0 interface, it would not be bound to any interface at all, and not answer to anything. So it needs to connect to something, hence my suggestion to look at your PR because that may allow the requester to express what to connect to. (We could change what you suggest, in another code commit, but maybe that needs to build upon the PR or have some different functionality).

wcawijngaards avatar Aug 04 '20 09:08 wcawijngaards