Files
LogSeq/pages/Scripts/Configuring Consul DNS Forwarding in Ubuntu 16.04.md.bak
2025-12-11 06:26:12 -08:00

136 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Configuring Consul DNS Forwarding in Ubuntu 16.04
updated: 2021-09-01 13:45:43Z
created: 2021-09-01 13:45:43Z
source: https://andydote.co.uk/2019/05/29/consul-dns-forwarding/
---
## DEPRECATED - This doesnt work properly
[Please see this post for an updated version which works!](https://andydote.co.uk/2019/09/24/consul-ubuntu-dns-revisited/)
* * *
One of the advantages of using [Consul](https://www.consul.io/) for service discovery is that besides an HTTP API, you can also query it by DNS.
The DNS server is listening on port `8600` by default, and you can query both A records or SRV records from it. [SRV](https://en.wikipedia.org/wiki/SRV_record) records are useful as they contain additional properties (`priority`, `weight` and `port`), and you can get multiple records back from a single query, letting you do load balancing client side:
```bash
$ dig @localhost -p 8600 consul.service.consul SRV +short
1 10 8300 vagrant1.node.dc1.consul.
1 14 8300 vagrant2.node.dc1.consul.
2 100 8300 vagrant3.node.dc1.consul.
```
A Records are also useful, as it means we should be able to treat services registered to Consul like any other domain - but it doesnt work:
```bash
$ curl http://consul.service.consul:8500
curl: (6) Could not resolve host: consul.service.consul
```
The reason for this is that the systems built-in DNS resolver doesnt know how to query Consul. We can, however, configure it to forward any `*.consul` requests to Consul.
## [](#solution---forward-dns-queries-to-consul)Solution - Forward DNS queries to Consul
As I usually target Ubuntu based machines, this means configuring `systemd-resolved` to forward to Consul. However, we want to keep Consul listening on its default port (`8600`), and `systemd-resolved` can only forward requests to port `53`, so we need also to configure `iptables` to redirect the requests.
The steps are as follows:
1. Configure `systemd-resolved` to forward `.consul` TLD queries to the local consul agent
2. Configure `iptables` to redirect `53` to `8600`
So lets get to it!
### [](#1-make-iptables-persistent)1\. Make iptables persistent
IPTables configuration changes dont persist through reboots, so the easiest way to solve this is with the `iptables-persistent` package.
Typically I am scripting machines (using \[Packer\] or \[Vagrant\]), so I configure the install to be non-interactive:
```bash
echo iptables-persistent iptables-persistent/autosave_v4 boolean false | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean false | sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt install -yq iptables-persistent
```
### [](#2-update-systemd-resolved)2\. Update Systemd-Resolved
The file to change is `/etc/systemd/resolved.conf`. By default it looks like this:
```bash
[Resolve]
#DNS=
#FallbackDNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
#Domains=
#LLMNR=yes
#DNSSEC=no
```
We need to change the `DNS` and `Domains` lines - either editing the file by hand, or scripting a replacement with `sed`:
```bash
sudo sed -i 's/#DNS=/DNS=127.0.0.1/g; s/#Domains=/Domains=~consul/g' /etc/systemd/resolved.conf
```
The result of which is the file now reading like this:
```bash
[Resolve]
DNS=127.0.0.1
#FallbackDNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844 Domains=~consul
#LLMNR=yes
#DNSSEC=no
```
By specifying the `Domains` as `~consul`, we are telling resolvd to forward requests for the `consul` TLD to the server specified in the `DNS` line.
### [](#3-configure-resolvconf-too)3\. Configure Resolvconf too
For compatibility with some applications (e.g. `curl` and `ping`), we also need to update `/etc/resolv.conf` to specify our local nameserver. You do this **not** by editing the file directly!
Instead, we need to add `nameserver 127.0.0.1` to `/etc/resolvconf/resolv.conf.d/head`. Again, I will script this, and as we need `sudo` to write to the file, the easiest way is to use `tee` to append the line and then run `resolvconf -u` to apply the change:
```bash
echo "nameserver 127.0.0.1" | sudo tee --append /etc/resolvconf/resolv.conf.d/head
sudo resolvconf -u
```
### [](#configure-iptables)Configure iptables
Finally, we need to configure iptables so that when `systemd-resolved` sends a DNS query to localhost on port `53`, it gets redirected to port `8600`. Well do this for both TCP and UDP requests, and then use `netfilter-persistent` to make the rules persistent:
```bash
sudo iptables -t nat -A OUTPUT -d localhost -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600
sudo iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
sudo netfilter-persistent save
```
## [](#verification)Verification
First, we can test that both Consul and Systemd-Resolved return an address for a consul service:
```bash
$ dig @localhost -p 8600 consul.service.consul +short
10.0.2.15
$ dig @localhost consul.service.consul +short
10.0.2.15
```
And now we can try using `curl` to verify that we can resolve consul domains and normal domains still:
```bash
$ curl -s -o /dev/null -w "%{http_code}\n" http://consul.service.consul:8500/ui/
200
$ curl -s -o /dev/null -w "%{http_code}\n" http://google.com
301
```
## [](#end)End
There are also guides available on how to do this on [Hashicorps website](https://learn.hashicorp.com/consul/security-networking/forwarding), covering other DNS resolvers too (such as BIND, Dnsmasq, Unbound).