Configure kresd to resolve a WAN address to a LAN IP?

Can I configure the Knot resolver on my Turris Omnia to resolve a subset of WAN names to local IP addresses?

It excellently resolves .lan addresses based the DHCP configs I have in Luci. But here’s the scenario:

I have a cloud server on cloud.lan and cloud.mydomain.tld.

cloud.lan resolves to a local IP in form 192.168.0.nn and cloud.mydomain.tld resolves to my WAN IP.

I would like to configure the DNS so that cloud.mydomain.tld resolves to the local IP as well.

Is that possible, and if so how?

The reason for this is that I have a mobile device say that is configured to use cloud.mydomain.tld. It works fine, BUT when it’s on the LAN this causes (I expect) a hairpin data travel out of my LAN and back in (in presumably one hop, but still a hairpin out and in). This could be avoided if I can have cloud.mydomain.tld resolve to the internal LAN IP when the LAN DNS is used.

OK I found this:

https://wiki.turris.cz/doc/en/public/dns_knot_misc#adding_custom_configuration

and this:

https://man7.org/linux/man-pages/man5/hosts.5.html#EXAMPLES

But it doesn’t work :-(. How sweet if it did. The latter provides a clear exampleof exactly what I want. With this /etc/hosts line:

192.168.1.10    foo.mydomain.org       foo

But I follow directions and add to /etc/config/resolver the line:

    list hostname_config '/etc/hosts'

so it looks like this:

config resolver 'common'
        list interface '0.0.0.0'
        list interface '::0'
        list hostname_config '/etc/hosts'
        option port '53'
        option keyfile '/etc/root.keys'
        option verbose '0'
        option msg_buffer_size '4096'
        option msg_cache_size '20M'
        option net_ipv6 '1'
        option net_ipv4 '1'
        option forward_upstream '1'
        option prefered_resolver 'kresd'
        option ignore_root_key '0'
        option prefetch 'yes'
        option static_domains '1'
        option dynamic_domains '0'

config resolver 'kresd'
        option rundir '/tmp/kresd'
        option log_stderr '1'
        option log_stdout '1'
        option forks '1'
        option keep_cache '0'

config resolver 'unbound'
        option outgoing_range '60'
        option outgoing_num_tcp '1'
        option incoming_num_tcp '1'
        option msg_cache_slabs '1'
        option num_queries_per_thread '30'
        option rrset_cache_size '100K'
        option rrset_cache_slabs '1'
        option infra_cache_slabs '1'
        option infra_cache_numhosts '200'
        list access_control '0.0.0.0/0 allow'
        list access_control '::0/0 allow'
        option pidfile '/var/run/unbound.pid'
        option root_hints '/etc/unbound/named.cache'
        option target_fetch_policy '2 1 0 0 0'
        option harden_short_bufsize 'yes'
        option harden_large_queries 'yes'
        option qname_minimisation 'yes'
        option harden_below_nxdomain 'yes'
        option key_cache_size '100k'
        option key_cache_slabs '1'
        option neg_cache_size '10k'
        option prefetch_key 'yes'

config resolver 'unbound_remote_control'
        option control_enable 'yes'
        option control_use_cert 'no'
        list control_interface '127.0.0.1'

and then restart the knot resolver:

/etc/init.d/resolver restart

and try:

nslookup foo.mydomain.org

It returns:

Server: 127.0.0.1
Address: 127.0.0.1#53

Name:      foo.mydomain.org
foo.mydomain.org	canonical name = mydomain.org
Name:      mydomain.org
Address 1: 27.33.203.194
foo.mydomain.org	canonical name = mydomain.org

So sad. What have I misread? What isn’t working. This would a dream solution. So simple, so easy to maintain and is already documented in the second link above as a canonical method for achieving exactly what I want to avoid this hairpin for LAN devices.

I should add too, that on the Luci configs I have:

Though to be honest, I disabled Ignore /etc/hosts before I added list hostname_config '/etc/hosts' to /etc/config/resolver and was surprised that Luci hadn’t done that so wonder what the Luci checkbox does?

I should add, further that the last of these Foris options is unclear in its meaning:

What does this last option do? It doesn’t look like what I’m after as the the FQDN I’m trying to resolve to a LAN IP is not a DHCP client, the server in question is but under its LAN name.

Egads that was chore, but I did it. Bingo! Thanks to some more tips:

But to coax the Knot Resolver on the Omnia to respect /etc/hosts I found I needed to:

  1. Add option include_config '/etc/kresd/custom.conf' to the config resolver 'kresd' section in /etc/config/resolver
    • Of particular note option hostname_config '/etc/hosts' did not work! Why not, don’t know, it’s mentioned in threads above.
  2. Add one line hints.add_hosts() to the file /etc/kresd/custom.con

Then restart kresd /etc/init.d/resolver restart and flush DNS caches on my desktop (on Ubuntu /etc/init.d/dns-clean) and now my FQDN resolves to a local IP and the hairpin is averted. Phew.

As a side note I do wish this was better documented and not so hodge podge and experimental. But c’est la vie. May this rest as a findable evidence for anyone else wanting to do same.

I still don’t know what those Luci and Foris configs do.

.

The wiki article said “Extend section ‘kresd’”, meaning you should instead put it lower – somewhere under config resolver 'kresd'. There it works for me, but the other way with add_hosts is basically the same thing. I now modified the article to name the section more precisely.

The Luci page about “DHCP & DNS” has no (direct) effect on DNS. It’s designed for dnsmasq.

The last option in Foris/DNS is the typical way how people get the *.lan names in DNS.

This will enable your DNS resolver to place DHCP client’s names among the local DNS records.

I don’t know… perhaps you use a different approach.

2 Likes

Thanks for clarifying!

Re: how I get .lan names to resolve it’s via Luci configs.

But I did learn that I can see them in Knot Resolver by connecting to it and hints.get() and they are all listed. How they got there I can’t be 100% sure (by what config file, as in somewhere kresd knows to check the DHCP configs).

So you’re one of those who configure kresd to forward everything under lan to a dnsmasq listening on another port? (no, that doesn’t make sense in combination with hints.get())

There’s still option static_domains '1' that has no UI (I think), meaning that names with static address assignments (configurable in luci) will get there. You could have used that instead of /etc/hosts. Though I’m not really sure about all this.

The checkbox in Foris is to extend this also to names that get assigned dynamically, in config it’s option dynamic_domains '0', and if you check it you can also change the lan suffix (some people use their own domain, for example).

Is there clear documentation on what option static_domains and option dynamic_domains do? I can’t seem to find any.

I’m not aware of any. There’s some description in (re)Foris for the checkbox that switches dynamic_domains.

That’s a shame. Looks like Turris/Omnia specific features and would be nice if they had clear documentation for them. Seems a tad unprofessional for us to be grasping around in the dark (guesswork and snippets of info from support)

1 Like

@Bernd_Wechner I am not sure but you could also look at LUCI firewall option NAT Loopback. I remember I used to have some webservers running in a container and I think NAT Loopback was the option to achieve what you want. Its in the port forwarding section when you edit the rule. So you should go with nat loopback enabled.

Hello!

I’m going on with this thread, because I think my question is on the same topic.

On the LAN, to have Knot resolve a WAN domain with an RFC1918 IP address (simple case: the server is in the DMZ next door, it was Bernhard’s initial question), is it the paragraph in the documentation entitled “Replacing part of the DNS tree” that should be implemented?

I tried to use the example syntax given in the documentation to “graft” a domain onto the public DNS namespace, without success.

extraTrees = policy.todnames({'mon.sous.domain.fr.'})
policy.add(policy.suffix(policy.FLAGS({'NO_CACHE', 'NO_EDNS'}), extraTrees))
policy.add(policy.suffix(policy.STUB({'172.16.0.1'}), extraTrees))

This configuration being put in /etc/kresd/custom.conf, or similar.

Am I looking in a completely wrong direction, or is it just the syntax that I have clumsily adapted?

In practice, for light professional use, the total true acquisition cost of the Turris Omnia amounts to the first few hundred euros for the initial purchase of the hardware, plus the next few thousand euros for the days of investigating its operation, seeking technical support, testing and validating it after much trial and error.

I am answering my own question. The way to force Knot to resolve locally a fqdn domain is to add the following line to the custom configuration file:

line:

hints['mon.sous.domaine.fr'] = '192.0.2.18'

in:

/etc/kresd/custom.conf

The answer can be found more or less under different posts in the forum. None of them seemed very clear to me, some of them seem to confuse the hints directive with selective forward to a particular DNS, depending on the domain. Perhaps this short, more explicit post will be helpful to some. Or perhaps it is me who has not understood the deeper implications of the hints directive. Either way, it works for me.

This is where you can find the official Knot documentation page on the subject. It is easy to find… once you know the answer.

I know of two other ways that should work, too: Knot resolver (i.e. kresd) - DNS advanced settings for Omnia and MOX [Turris wiki]

Hi Vladimír,

I did my best to unify two of the three methods (“hints” and “hosts”) by rewriting the text of the community wiki, under the link you gave. I did not find there the third method you mentioned.

If you would like to go through my update of the wiki, and point out any errors, I will correct them. Unless you want to do it yourself directly.

Thanks for your guidance.

I saw it there in a warning box. Configuring the names in the luci GUI (with Turris OS 5.x, it said). That also should work, though I don’t remember details.

On a quick read I didn’t notice any issue in that part of wiki.

Hi!

This mention was temporary, I had placed it next to a fixme! warning, during the time I was writing this Wiki page. It didn’t describe a third method, it questioned the usefulness of keeping the paragraph about the “/etc/hosts” file, since the hostnames registered by LuCI in /etc/config/dhcp are well resolved by Knot too (provided you add the .lan “tld” to them).

Finally, the description of the /etc/hosts file is useful, as this is where you can register an fqdn, the paragraph explained. So it has kept its place in the wiki. In contrast, fqdn’s registered in /etc/config/dhcp, are not resolved by Knot.

Right, the DHCP-related names are nested in .lan (by default).