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:

and this:

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:       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 ''
        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 ' allow'
        list access_control '::0/0 allow'
        option pidfile '/var/run/'
        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 ''

and then restart the knot resolver:

/etc/init.d/resolver restart

and try:


It returns:


Name:	canonical name =
Address 1:	canonical name =

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.

1 Like

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.