DEV Community

Adam Migus
Adam Migus

Posted on • Originally published at migus.org

Automating Dnsmasq with Ansible

Dnsmasq is a DHCP server and DNS forwarder designed for small networks. It's not built for scale but highly extendable and flexible. I used that extensibility to add some automation and manageability:

  • dnsmasq-web: a REST (JSON/HTTP) API that provides access to client, lease, and request data and reservation management.
  • amigus.dnsmasq: a collection of Ansible Roles available on Ansible Galaxy that install and configure Dnsmasq as a DHCP and/or DNS server

My main goal with the Ansible collection was to replace the terse configuration syntax of Dnsmasq with more readable YAML, e.g.,

---
dnsmasq_dns_servers:
  - address: 192.168.1.253
    domain: wired.lan
    network: 192.168.2.0/24
  - address: 192.168.1.1
Enter fullscreen mode Exit fullscreen mode

Translates to:

rev-server=192.168.2.0/24,192.168.1.253
server=192.168.1.1
server=/wired.lan/192.168.1.253
Enter fullscreen mode Exit fullscreen mode

A DHCP server that leases the entire subnet starting from .10 using .1 as the gateway:

---
dnsmasq_dhcp_interfaces:
  - device: eth0
    router: 1
    start: 10
Enter fullscreen mode Exit fullscreen mode

The YAML does not need to contain the IP subnet information because Ansible gets it from the interface.

For example, if the eth0 interface of the server is 192.168.100.2/24, the resulting configuration parameters are:

dhcp-range=interface:eth0,192.168.100.10,192.168.100.254
dhcp-option=interface:eth0,option:router,192.168.100.1
Enter fullscreen mode Exit fullscreen mode

SQLite Database

Dnsmasq does not use a database; it keeps current lease information in an (undocumented) flat file and does not have an API. However, lease management can be delegated via the dhcp-script configuration parameter.

The role collection contains an SQLite database schema and a shell script for implementing a lease management database. It has requests, leases, and clients tables.

REST API

Dnsmasq also supports reading DHCP lease reservations from files in a specific directory. The role collection installs dnsmasq-web, which uses that feature to enable management of DHCP lease reservations over HTTP and/or exposes the DHCP database data.

The database and REST API are optional and only present on the target system when the required options are in the configuration YAML.

Demo: run a server on localhost

Prerequisites

Ansible needs Python, and the role collection needs the Python netaddr library. The system must also be an Alpine (apk), Red Hat (dnf), or OpenSUSE (zypper) variant.

The variables below will configure DHCP to offer .1 as the network gateway and lease the whole IP subnet starting from .10. It will also set itself as the DNS server for all clients and forward all queries to 1.1.1.1.

To configure the DNS only, omit the dnsmasq_dhcp_interfaces variable. To offer the DHCP server as the gateway, omit the router attribute.

Target localhost

Create an Inventory, add the localhost to the dnsmasq group, add the required variables to vars, and save it as inventory.yaml:

---
dnsmasq:
  hosts:
    localhost:
      ansible_connection: local
  vars:
    dnsmasq_dhcp_interfaces: [{ device: eth0, router: 1, start: 10 }]
    dnsmasq_dns_options: [bogus-priv, domain-needed, no-resolv]
    dnsmasq_dns_servers: [{ address: 1.1.1.1 }]
Enter fullscreen mode Exit fullscreen mode

Run the playbook

Then install Ansible and the amigus.dnsmasq collection, and run the Playbook:

pip install ansible-core
ansible-galaxy collection install amigus.dnsmasq
ansible-playbook -i inventory.yaml amigus.dnsmasq.dnsmasq
Enter fullscreen mode Exit fullscreen mode

More information

For more information, like how to configure a static (reservation-only) server, check out the documentation!

Top comments (0)