I’ve recently been experimenting with Hashicorp’s Consul in my home infrastructure because I want to use it to provide service discovery and automatic DNS provisioning when I create Proxmox instances with Terraform. Consul is a bit of a hefty beast to get to grips with and getting DNS lookups working when you have ACLs enabled can be a little tricky - it’s taken me a day or two of going round in circles to figure this one out.

Consul’s security model

Once you enable ACLs in Consul and set the policy to deny by default, nothing works (understandably). You need to create an ACL for everything. Behind the scenes, DNS lookups for node names query the catalog’s node list, and DNS lookups for services query the catalog’s service list (note that unhealthy services will not return any records).

Queries to Consul must provide some form of authentication which is then checked against the policies that user is authorised to use - if this passes then the query succeeds. Note that a DNS query to Consul also results in a catalog lookup, but because there is no way to pass any kind of auth token during the lookup it automatically uses the built-in ‘anonymous’ token.

As such, the anonymous token also needs the correct permissions to query the catalog. If you wish to allow all nodes and services to be queried then the following policy will suffice:

node_prefix "" {
  policy = "read"
service_prefix "" {
  policy = "read"

To create a policy from this document, save it to a file and then apply it to Consul:

consul acl policy create -name anonymous-dns-read -rules @anonymous-dns-read.hcl

With the policy in place, you then need to allow the anonymous token to use it:

consul acl token update -id anonymous -policy-name=anonymous-dns-read

With that in place (and assuming your Consul domain is ‘consul’), you can test it:

$ dig ANY consul.service.consul @ -p 8600 +short