[LXD] Built-in DNS server

Project LXD
Status Draft
Author(s) @stgraber
Approver(s) @stgraber @tomp @sdeziel
Release LXD 4.20
Internal ID LX006

Abstract

Implement a DNS server built into LXD which will offer AXFR (zone transfer) of auto-generated DNS zones including forward and reverse records for all instances running in LXD.

Rationale

When operating a LXD cluster that runs multiple projects and a variety of instances across a large set of networks, having valid forward and reverse records for all your instances can be quite important. It’s something that public clouds always provided (albeit with limited customization) and that can be quite important not only for ease of access to the instance but also to avoid hosted services getting flagged as potential spam due to lacking reverse DNS records.

The intent here is to have every address that LXD itself manages and which isn’t hidden behind an internal NAT to have valid forward and reverse DNS records.
LXD will then serve those zones for zone transfer to the operator’s production DNS servers.

Specification

Design

A new config key core.dns_address will be introduced to instruct LXD to listen for DNS traffic. This will enable a built-in authoritative DNS server in the LXD daemon which will listen on both UDP and TCP ports.

This DNS server will be authoritative only and will be intended to mostly serve zone transfer requests to an external DNS infrastructure.

LXD will be tracking DNS zones on a per project basis (part of the network feature) but DNS zones will have to be globally unique.

Networks can then be tied to DNS zones for both forward and reverse records. Doing so will populate the selected zones with records for each instance. This will only happen for instance addresses which aren’t behind NAT. It will also be restricted to addresses which are known by LXD directly through its database records (the instances can’t be trusted to provide this information).

Automatic records are expected for:

  • Gateway for IPv4 or IPv6 subnets on a LXD managed network when they’re not using NAT
  • Forward and reverse records for IPv4 and IPv6 addresses of instances when not from a NAT-ed subnet and when the address can be determined from a static record (ipv4.address/ipv6.address) or be derived from the MAC address of the instance (EUI64)

Config changes

  • core.dns_address in local server configuration
  • dns.zone in network configuration

API changes

  • /1.0/network-zones
  • /1.0/network-zones/<name>
  • /1.0/network-zones/<name>/records

CLI changes

  • lxc network zone list
  • lxc network zone create
  • lxc network zone delete
  • lxc network zone show
  • lxc network zone record list
  • lxc network zone record create
  • lxc network zone record delete

Database changes

  • network_zones table to track the zones
  • network_zones_config table to track additional configuration

Upgrade handling

This is an optional additional feature, no behavior changes will occur on upgrade.

Further information

TBD:

  • Security on AXFR
  • Zone defaults (SOA, TTL, SERIAL)

I’m not sure if you’re seeking review of this doc yet, but could you expand this section to give more info into how you see these commands working, I can’t visualise it yet.

If there are multiple networks assigned to the same zone (is this possible?), what will the gateway names be?

Will this DNS server only server AXFR requests, or also A/AAAA and PTR requests for the published names? The abstract suggests this to be the case, but the mostly here puts doubt into my mind :slight_smile:

I expect we’ll encode the network name in the record.

We’ll let it answer normal queries too, just no recursion. This should come in handy for those who want to integrate with resolved or similar.

1 Like

As you know, IP ACLs are pretty common to restrict who can request XFRs. TSIG would be a nice addition IMHO.

That’s indeed going to be convenient.

To reduce the amplification factor, I think the “ANY” query type should be handled according to RFC8482. The HINFO way would be best IMHO as it would reduce the cost of responding.

Something I thought about after our discussion on this yesterday @stgraber :

Although its not possible to have two instances with the same name connected to different networks in the same zone and same project (because instance names are unique per project), it would be possible to have multiple networks in the same project (and zone) and have a single instance connected to both of them via multiple NICs.

In that case we should think about and make clear what IP(s) the DNS name will point to - either we pick the first one (using some indicator for “first”) or we round-robin them?

I’d round robin in those cases.