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
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
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
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
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 }]
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
More information
For more information, like how to configure a static (reservation-only) server, check out the documentation!
Top comments (0)