Skip to content

dnsmasq – Local DNS for Blackcairn

Purpose

dnsmasq is used on Blackcairn to provide local DNS overrides for real public domains (e.g. *.blackcairn.uk) so that:

  • LAN clients resolve services to the internal IP
  • All traffic enters via Nginx Proxy Manager (NPM)
  • Hostnames are identical inside and outside the LAN
  • HTTPS works cleanly with real certificates

dnsmasq is not used for DHCP.


Design Principles

  • Bind dnsmasq to the physical LAN interface only
  • Do not bind to a fixed IP (avoids boot-time race conditions)
  • Do not interfere with Docker bridge networks
  • Override only the required domain (blackcairn.uk)
  • Let NPM handle all routing by hostname

Configuration File

Location

/etc/dnsmasq.d/blackcairn.conf

Contents

# Bind safely to LAN interface only
interface=eno1
bind-interfaces
except-interface=lo

# Local DNS override for Blackcairn
address=/blackcairn.uk/192.168.1.168

Notes

  • interface=eno1 ensures dnsmasq waits for the NIC, not an IP
  • bind-interfaces prevents listening on Docker bridges
  • except-interface=lo avoids conflicts with systemd-resolved
  • address=/blackcairn.uk/192.168.1.168 sends all subdomains to NPM

Why NOT listen-address=192.168.1.168

Binding dnsmasq to a specific IP caused startup failures:

failed to create listening socket for 192.168.1.168

Reason: - The IP is DHCP-assigned - dnsmasq can start before the IP exists - With bind-interfaces, dnsmasq refuses to start

Solution: bind to the interface, not the address.


systemd Override (Silencing resolvconf Warnings)

By default, dnsmasq tries to register itself with resolvconf, which fails on loopback (lo) and produces harmless but noisy logs.

Override File

Location

/etc/systemd/system/dnsmasq.service.d/override.conf

Contents

[Service]
ExecStartPost=

This clears the start-resolvconf hook while leaving dnsmasq fully functional.

Apply with:

sudo systemctl daemon-reload
sudo systemctl restart dnsmasq


Service Management

sudo systemctl restart dnsmasq
sudo systemctl status dnsmasq

Expected state:

Active: active (running)


Validation

Check dnsmasq is listening on port 53:

sudo ss -lntup | grep ':53'

Test resolution locally:

dig @192.168.1.168 portainer.blackcairn.uk

Expected result:

portainer.blackcairn.uk.  IN  A  192.168.1.168


Client Configuration

For LAN devices to benefit from local DNS:

  • Router DHCP must advertise:
  • DNS Server: 192.168.1.168

After renewing DHCP, clients should resolve all *.blackcairn.uk services internally via NPM.


Architecture Summary

Client
  ↓ DNS
dnsmasq (Blackcairn)
  ↓ 192.168.1.168
Nginx Proxy Manager
  ↓ Host header routing
Docker services

Rationale

This setup provides: - One hostname everywhere (LAN + WAN) - Clean HTTPS - Simple DNS rules - No Docker DNS leakage - Predictable boot behaviour

This file exists to prevent reintroducing listen-address or .lan domains in the future.