Systemd-resolved with Consul: Support both .consul and external domains?

I’m trying to set up systemd-resolved to forward DNS, using the guidance provided here. The catch is that I want all .consul queries to be directed towards Consul, but all other queries to be directed towards the default nameserver list.

To that end, I have two configuration files: consul.conf:


and default.conf:


The reason for having both is because queries to non-.consul domains fail until I add something for other domains, since I’m symlinking /etc/resolv.conf to the generated systemd-resolved stub.

Based on what I’m seeing, it works, but only until a non-.consul domain is queried. Here, it works at first, but only until I query a .com comain:

damien@nomad-server-ca-central-5a943497:~> sudo service systemd-resolved restart
damien@nomad-server-ca-central-5a943497:~> resolvectl query consul.service.consul
consul.service.consul: 2600:3c04::f03c:92ff:fe96:a166

-- Information acquired via protocol DNS in 4.7ms.
-- Data is authenticated: no
damien@nomad-server-ca-central-5a943497:~> resolvectl query                     -- link: eth0
            2607:f8b0:400b:802::200e           -- link: eth0

-- Information acquired via protocol DNS in 6.9ms.
-- Data is authenticated: no
damien@nomad-server-ca-central-5a943497:~> resolvectl query consul.service.consul
consul.service.consul: resolve call failed: 'consul.service.consul' not found

Queries to consul.service.consul work reliably until I query a non-.consul domain, and then it immediately breaks until I restart systemd-resolved.

Any idea what exactly is happening here? All I want to do really is direct .consul domains to one set of DNS servers, and all other domains to another. Is that possible with systemd-resolved?

hello same issue for me do you have found a solution to use diferent DNS in systemd-resolved?

No, I ended up switching to BIND which made this easier.

You’ll have to configure recursors instead of your default.conf:

This is quite an interesting question.

The reason the configuration with multiple configuration files isn’t working, is because it’s based on a misunderstanding - even if you put multiple files in /etc/systemd/resolved.conf.d/, this is only a convenience to allow you to build up a single configuration from multiple pieces. What you’ve effectively done is to create a configuration saying:

Domains=~consul ~.

which wasn’t your intent. (Check this by running resolvectl status.)

Now, systemd-resolved does have some ability to direct different DNS subtrees to different DNS servers… but it’s entirely based around network interfaces.

My first thought was to try to associate Consul with the loopback interface, but that’s not managed by systemd-networkd by default, and my initial attempts to make it so ended up breaking my system in various ways, and then later I looked at the systemd-resolved source code, and figured out it’s hardcoded to ignore loopback anyway.

I did eventually get the desired behaviour working by creating a dummy network interface I could attach the configuration to:






Apply and test

networkctl reload
systemctl restart systemd-resolved
resolvectl query consul.service.consul

It’s not exactly nice though - there’s a lot of config just to satisfy systemd-resolved’s opinionated choices.

The IP addresses I’m using there come from the “documentation and examples” reserved ranges, and the reason there’s an IPv4 and IPv6 one included, is systemd-resolved is using that to decide whether to ask for A or AAAA records or both from Consul!

Or, you could just do as @Wolfsrudel suggests and set recursors in Consul - although I’m not a fan of routing all of a system’s DNS traffic through Consul, IMO the service discovery system should be able to fail and not take down the rest of the system’s DNS resolution… so maybe my crazy systemd shenanigans above do have a use-case after all.

1 Like