CZ-NIC / knot-resolver

Knot Resolver - resolve DNS names like it's 2024
https://www.knot-resolver.cz/
Other
364 stars 59 forks source link

Setting upstream dns servers by resolv.conf #40

Closed exander77 closed 7 years ago

exander77 commented 7 years ago

How to set upstream dns servers by resolv.conf file similar to dnsmasq option: resolv-file=/etc/.../resolv.conf

This is needed to use kresd with NetworkManager.

vcunat commented 7 years ago

Knot-resolver iterates by default. Forwarding instead to other resolvers can be done via the policy module, e.g. with a ruleset like:

modules.load('policy');
policy:add(policy.all(policy.FORWARD('8.8.8.8')))
policy:add(policy.all(policy.FORWARD('etc.')))

That is what Turris Omnia uses.

exander77 commented 7 years ago

Yes, I know that, but I have resolv.conf created by NetworkManager and would like to load it as is in kresd configuration. Maybe it could be scripted in lua?

vcunat commented 7 years ago

I see now. That seems the best approach.

exander77 commented 7 years ago

It there a documentation to that lua configuration language? I would need something like open resolv.conf file, iterate lines, if line starts with !nameserver " than run: policy:add(policy.all(policy.FORWARD(rest_of_the_line)))

vcunat commented 7 years ago

It's just lua-5.1 (luajit implementation). The module only adds some values within policy, e.g. the :add method.

vcunat commented 7 years ago

It might be more difficult to reload the file whenever it changes, if you desire that.

exander77 commented 7 years ago

I know when it changes, I am using dispatcher script in NetworkManager. Is there a way to reload kresd configuration? In attached systemd configuration, there is only start and stop, no force-reload.

vcunat commented 7 years ago

You can certainly restart it. I don't think there's a better way currently. DNS records are in a persistent cache, so there isn't much to lose.

vavrusa commented 7 years ago

You can either periodically check for changes in the config, see http://knot-resolver.readthedocs.io/en/latest/daemon.html#events-and-services (the doc mentions "File watchers" but that isn't implemented yet).

Or change the live configuration, see http://knot-resolver.readthedocs.io/en/latest/daemon.html#scaling-out how you can change configuration of running instance with nc

exander77 commented 7 years ago

I am not sure how to connect with nc, what is rundir/tty/3008?

vavrusa commented 7 years ago

rundir is the working directory in which kresd is running, if you start it in non-interactive mode it will contain a directory tty which will have a local socket named by the PID of running process, e.g. 3008

vcunat commented 7 years ago

You can force starting in non-interactive mode by passing -f 1 (or with a different number of forks).

exander77 commented 7 years ago

I am starting kresd like this: /usr/sbin/kresd --config=/etc/knot-resolver/kresd.conf --verbose --forks=1 --keyfile=/usr/share/dns/root.key /run/knot-resolver/cache But /run/knot-resolver/cache/tty is empty.

oerdnj commented 7 years ago

The control socket on Debian is: /run/knot-resolver/control

exander77 commented 7 years ago

Thanks a lot! Is this documented somewhere?

exander77 commented 7 years ago

This solution seems to be working for me so far:

policy.forwarders = {}

function policy:reload_resolv_file()
  for i = 1, #policy.forwarders do
    print('removing forwarder rule:', policy.forwarders[i].id)
    policy.del(policy.forwarders[i].id)
  end

  policy.forwarders = {}

  for line in io.lines(policy.resolv_file) do
    if not line:match("^%s+#") then
      local split = string.gmatch(line, "[^%s]+")
      local name = split()
      local value = split()

      if name == 'nameserver' then
        print('adding new forwarder rule for:', value)
        table.insert(policy.forwarders, policy.add(policy.all(policy.FORWARD(value))))
      end
    end
  end
end

policy.resolv_file = '/var/run/NetworkManager/resolv.conf'

policy:reload_resolv_file()

I am reloading it with: echo "policy:reload_resolv_file()" | sudo nc -U /run/knot-resolver/control

It is not that clean, but fine so far. Could something like this be incorporated in kresd by default? Dnsmasq has resolv-file option: http://www.thekelleys.org.uk/dnsmasq/docs/setup.html

vcunat commented 7 years ago

Note: if a query matches multiple policy.FORWARD rules, only the first one is ever used. In 1.2.0 you can pass a list of at most 4 targets to a single policy.FORWARD to make kresd "choose the best" for each query (tracking RTT, bogus answers, etc.)

pspacek commented 7 years ago

I've transformed this to Gitlab wiki https://gitlab.labs.nic.cz/knot/knot-resolver/wikis/-Configuring-upstream-DNS-forwarders-from-resolv.conf, closing.