Getting started¶
Default configuration¶
By default, the role configures dnsmasq to act as a caching and forwarding DNS server for the local machine. Additional configuration like support for Consul DNS service and LXC subdomain managed by the debops.lxc role is enabled when detected.
The initial configuration is designed with nested hierarchy of DNS servers in mind: by default answers about private IP addresses from external DNS servers are blocked to avoid rebinding, but the hosts' own domain, as well as its parent domain are exempt from this, as long as the parent domain has 3 or more levels. The filtering of PTR requests will be disabled when the upstream nameservers are located in a private IP address ranges, or local LXC configuration is detected, to allow revDNS requests to be resolved.
If the host has the br2
network interface, it is assumed to be a local
private network, and DHCP/DNS/PXE services are configured for it. The role will
automatically create relevant configuration based on the IP addresses defined
on the interface, as well as publish a DNS domain based on the interface name;
this can be controlled using the dnsmasq__interfaces configuration
variables. The role will automatically configure support for iPXE service
managed by debops.ipxe role to allow customized PXE boot menus.
Example inventory¶
Hosts added to the debops_service_dnsmasq
inventory group will have the
dnsmasq
installed and configured.
[debops_service_dnsmasq]
hostname
Example playbook¶
If you are using this role without DebOps, here's an example Ansible playbook
that uses the debops.dnsmasq
role:
---
- name: Configure dnsmasq
collections: [ 'debops.debops', 'debops.roles01',
'debops.roles02', 'debops.roles03' ]
hosts: [ 'debops_service_dnsmasq' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Prepare dnsmasq environment
import_role:
name: 'dnsmasq'
tasks_from: 'main_env'
tags: [ 'role::dnsmasq', 'role::ferm', 'role::tcpwrappers' ]
roles:
- role: resolvconf
tags: [ 'role::resolvconf', 'skip::resolvconf' ]
resolvconf__dependent_services:
- 'dnsmasq'
- role: ferm
tags: [ 'role::ferm', 'skip::ferm' ]
ferm__dependent_rules:
- '{{ dnsmasq__ferm__dependent_rules }}'
- role: tcpwrappers
tags: [ 'role::tcpwrappers', 'skip::tcpwrappers' ]
tcpwrappers__dependent_allow:
- '{{ dnsmasq__env_tcpwrappers__dependent_allow }}'
- role: dnsmasq
tags: [ 'role::dnsmasq', 'skip::dnsmasq' ]
If you are using this role without DebOps, here's an example Ansible playbook
that uses debops.dnsmasq
together with the debops.persistent_paths:
---
- name: Configure dnsmasq and ensure persistence
collections: [ 'debops.debops', 'debops.roles01',
'debops.roles02', 'debops.roles03' ]
hosts: [ 'debops_service_dnsmasq_persistent_paths' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Prepare dnsmasq environment
import_role:
name: 'dnsmasq'
tasks_from: 'main_env'
tags: [ 'role::dnsmasq', 'role::ferm', 'role::tcpwrappers' ]
roles:
- role: resolvconf
tags: [ 'role::resolvconf', 'skip::resolvconf' ]
resolvconf__dependent_services:
- 'dnsmasq'
- role: ferm
tags: [ 'role::ferm', 'skip::ferm' ]
ferm__dependent_rules:
- '{{ dnsmasq__ferm__dependent_rules }}'
- role: tcpwrappers
tags: [ 'role::tcpwrappers', 'skip::tcpwrappers' ]
tcpwrappers__dependent_allow:
- '{{ dnsmasq__env_tcpwrappers__dependent_allow }}'
- role: dnsmasq
tags: [ 'role::dnsmasq', 'skip::dnsmasq' ]
- role: persistent_paths
tags: [ 'role::persistent_paths', 'skip::persistent_paths' ]
persistent_paths__dependent_paths: '{{ dnsmasq__persistent_paths__dependent_paths }}'
If you are using this role without DebOps, here's an example Ansible playbook
that uses debops.dnsmasq
together with the debops-contrib.apparmor
role:
---
## Basically the same playbook as the one in DebOps core with the difference
## that this playbook also uses the debops-contrib.apparmor role to configure
## AppArmor.
- name: Configure AppArmor for dnsmasq
collections: [ 'debops.debops' ]
hosts: [ 'debops_contrib_service_dnsmasq' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Prepare dnsmasq environment
import_role:
name: 'dnsmasq'
tasks_from: 'main_env'
tags: [ 'role::dnsmasq', 'role::ferm', 'role::tcpwrappers' ]
roles:
- role: apparmor
tags: [ 'role::apparmor' ]
apparmor__local_dependent_config: '{{ dnsmasq__apparmor__local_dependent_config }}'
- name: Configure dnsmasq
collections: [ 'debops.debops' ]
hosts: [ 'debops_contrib_service_dnsmasq' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
roles:
- role: ferm
tags: [ 'role::ferm', 'skip::ferm' ]
ferm__dependent_rules:
- '{{ dnsmasq__ferm__dependent_rules }}'
- role: dnsmasq
tags: [ 'role::dnsmasq' ]
debops.persistent_paths support¶
In case the host in question happens to be a TemplateBasedVM on Qubes OS or
another system where persistence is not the default, it should be absent in
debops_service_dnsmasq
and instead be added to the
debops_service_dnsmasq_persistent_paths
Ansible inventory group
so that the changes can be made persistent:
[debops_service_dnsmasq_persistent_paths]
hostname
The dnsmasq__base_packages
are expected to be present (typically
installed in the TemplateVM).
Note that you will need to set core__unsafe_writes
to True
when you
attempt to update the configuration on a system that uses bind mounts for
persistence. You can set core__unsafe_writes
directly in your inventory
without the need to run the debops.core
role for this special case.
Refer to Templating or updating persistent files for details.
Other resources¶
List of other useful resources related to the debops.dnsmasq
Ansible role:
- Manual pages: dnsmasq(8), dhcp-options(5)