DEBOPS.DNSMASQ(5)

NAME
debops.dnsmasq - Install and configure dnsmasq

SYNOPSIS

debops service/dnsmasq [--limit group,host,...] [--diff] [--check] [--tags tag1,tag2,...] [--skip-tags tag1,tag2,...] [<ansible-playbook options>] ...

DESCRIPTION

dnsmasq <http://www.thekelleys.org.uk/dnsmasq/doc.html> is an application that provides DNS, DHCP, TFTP and Router Advertisement services in a compact package, suitable for small, internal networks. it's commonly used as a DNS cache and forwarder on desktop workstations or servers.

The debops.dnsmasq Ansible role can be used to configure dnsmasq on a given host. By default the DNS cache will be configured, but the role checks for presence of different services like lxc-net configured by the debops.lxc, consul and specific network interfaces defined by the debops.ifupdown, and adjusts the configuration automatically.

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 <https://en.wikipedia.org/wiki/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 <https://docs.debops.org/en/latest/ansible/roles/persistent_paths/guides.html#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) <https://manpages.debian.org/dnsmasq(8)>, dhcp-options(5) <https://manpages.debian.org/dhcp-options(5)>

DEFAULT VARIABLE DETAILS

Some of debops.dnsmasq default variables have more extensive configuration than simple strings or lists, here you can find documentation and examples for them.

  dnsmasq__interfaces

The dnsmasq__*_interfaces variables define per-interface configuration of dnsmasq. Each defined network interface has its own subdomain, IP address ranges taken from the interface configuration, and some other options. The result is merged with the main dnsmasq configuration defined in the dnsmasq__*_configuration variables, which can be used to refine the generated parameters if necessary.

The dnsmasq__*_interfaces entries are merged together, and Ansible inventory can be used to override the defaults provided in the role.

  Examples

Disable the interface configuration generated by default by the role:

dnsmasq__interfaces:
  - name: 'br2'
    state: 'absent'

Generate interface configuration with a custom DNS subdomain, IP address ranges for DHCP and disabled boot services:

dnsmasq__interfaces:
  - name: 'br2'
    addresses: [ '192.0.2.1/24', '2001:db8:feed:beef::1/64' ]
    domain: 'custom.{{ ansible_domain }}'
    boot_enabled: False

  Syntax

Each entry in the dnsmasq__*_interfaces lists is a YAML dictionary with specific parameters:

name
    Required. Network interface name for which to generate the configuration. This parameter is used as an anchor to merge multiple entries with the same name together.

filename
    Optional. Override the name of the generated configuration file stored in the /etc/dnsmasq.d/ directory. If not specified, the filename will be generated automatically based on the interface name.

state
    Optional. If not specified or present the interface configuration will be generated. If absent, the interface configuration will be not generated, and existing configuration file will be removed. If ignore, a given configuration entry will not be evaluated by the role.

    This parameter can be used to conditionally enable or disable interface configuration, for example when a given interface is present on a host.

tag Optional. A string that defines a "tag" for a given network which can be used to define DHCP options for that specific network. If not specified, the interface name will be used by default.

address / addressess
    Optional. List of IPv4 or IPv6 addresses in the "host/prefix" format which should be used in the interface configuration.

    You need to specify the IP address of the network interface and the subnet mask (prefix) in the CIDR format for it to be accepted by the role. The IP addresses will not be configured automatically, you can use the debops.ifupdown role to configure the network interfaces.

    The role automatically gathers the existing network interface configuration and uses existing IP addresses defined on the network interface, therefore you don't need to use this parameter unless required for a specific application.

hostname
    Optional. Specify the hostname which will be used in the interface DNS record. If not specified, the value in the dnsmasq__hostname variable is used by default.

domain
    Optional. Define a custom DNS domain for a given interface. If not specified, a DNS domain will be generated automatically using the interface name and the value of the dnsmasq__base_domain variable. This domain will be advertised over DHCP with the search option, new DHCP clients will be added to the DNS on this domain as well.

search
    Optional. List of additional DNS domains to add to the DHCP search option.

dhcp_enabled
    Optional, boolean. If not specified or True, the DHCP service will be configured on a specific network interface. To disable, set this parameter to False.

dhcp_range_state
    Optional. If not specified or present, the role will configure a range of dynamic IP addresses in the DHCP server for a given network. If absent, the DHCP range configuration will not be included in the generated configuration file.

dhcp_range_start
    Optional. Specify a positive number of IP addresses to reserve at the start of the subnet for static DHCP entries. If not specified, 10 IP addresses will be reserved by default.

dhcp_range_end
    Optional. Specify a negative number of IP addresses to reserve at the end of the subnet for static DHCP entries. If not specified, 10 IP addresses (specified as -10) will be reserved by default.

dhcp_lease
    Optional. Specify the lease time for IP addresses on a given network interface. If not specified, 24h will be used by default.

dhcp_ipv6_mode
    Optional. A string that defines DHCP IPv6 mode, see dnsmasq(8) <https://manpages.debian.org/dnsmasq(8)> for more details. If not specified, the value is defined as: ra-names,ra-stateless,slaac.

router_state
    Optional. If not specified or present or enabled, the router will be advertised for the DHCP clients on a given network interface. If disabled, the router advertisements will be disabled on a given network interface. If absent, the router configuration option will not be included in the generated configuration file.

router_gateway
    Optional. Specify the IP address of the default router advertised by dnsmasq on a given interface. If not specified, dnsmasq will advertise its own host as the default router.

boot_enabled
    Optional, boolean. If not specified or True, enable support for booting clients over the network using TFTP and PXE services. To disable, set the value to False.

boot_tftp_root
    Optional. Absolute path of the TFTP root directory used for boot services on this interface. If not specified, the value of the dnsmasq__boot_tftp_root variable will be used by default.

boot_filename
    Optional. The name of the file which the network boot clients should load and run at boot time. If not specified, the value of the dnsmasq__boot_filename variable will be used by default.

boot_server
    Optional. The IP address of the "next server" the network boot clients should contact for the TFTP service. If not specified, the dnsmasq will direct them to its own host automatically.

raw Optional. String or YAML text block with raw dnsmasq(8) <https://manpages.debian.org/dnsmasq(8)> configuration options, added at the end of a given interface configuration file. This can be used to add configuration not covered by the above parameters.

  dnsmasq__dhcp_hosts, dnsmasq__dns_records

The dnsmasq__dhcp_hosts and dnsmasq__dns_records variables can be used to define configuration for specific DHCP clients and custom DNS resource records. The syntax for both variables is the same.

Configuration defined in these variables is not converted to the dnsmasq__*_configuration variable format, and entries defined in these lists are not merged together. The dnsmasq configuration defined here will be stored in a separate config file, with its filename defined in the dnsmasq__dhcp_dns_filename variable.

  Examples of DHCP client configuration

Reserve a static IP address for a DHCP client with a particular MAC address:

dnsmasq__dhcp_hosts:
  - mac: '00:00:5e:00:53:01'
    ip: '192.0.2.1'

Override a hostname sent by a particular client, with reserved IP address:

dnsmasq__dhcp_hosts:
  - name: 'custom-hostname'
    comment: "This is a custom static host entry"
    mac: '00:00:5e:00:53:02'
    ip: '192.0.2.2'

Add a dbserver.example.org DNS resource record for a DHCP client on a specified domain:

dnsmasq__dhcp_hosts:
  - name: 'dbserver'
    domain: 'example.org'
    mac: '00:00:5e:00:53:03'
    ip: '192.0.2.3'

Define a webserver host with multiple CNAME records on a given domain, for different web services:

dnsmasq__dhcp_hosts:
  - name: 'webserver'
    comment: 'Internal web services'
    domain: 'example.org'
    mac: '00:00:5e:00:53:04'
    ip: '192.0.2.4'
    cname: [ 'code', 'dcim', 'ipam', 'cloud' ]

Ignore requests from a particular MAC address:

dnsmasq__dhcp_hosts:
  - mac: '00:00:5e:00:53:05'
    ignore: True

  Examples of DNS resource records

Define an MX resource record for a specific domain that points to the dnsmasq host for mail delivery:

dnsmasq__dns_records:
  - mx: 'example.org'

Define custom mail servers for a particular domain, with specific priority:

dnsmasq__dns_records:
  - mx: 'example.com'
    target: 'mx1.example.com'
    priority: 10
  - mx: 'example.com'
    target: 'mx2.example.com'
    priority: 20

Create an A resource record with a particular IP address:

dnsmasq__dns_records:
  - host: 'other.example.org'
    address: '192.0.2.30'

Define a TXT resource record with a DomainKeys Identified Mail (DKIM) entry:

dnsmasq__dns_records:
  - txt: 'mail._domainkeys.example.org'
    value: 'v=DKIM1; k=rsa; p=<base64-encoded public key>'

Define a multi-line TXT resource record with custom characters inside:

dnsmasq__dns_records:
  - txt: 'info.example.org'
    value:
      - "Custom string with it's value quoted"
      - "\"Additional string, with a comma\""

Create a SRV resource record that points to a service, with default values for weight and priority:

dnsmasq__dns_records:
  - srv: '_http._tcp.example.org'
    target: 'webserver.example.org'
    port: '80'

Define a CNAME resource record that points to a different host:

dnsmasq__dns_records:
  - cname: 'alias.example.org'
    target: 'service.example.org'

Define PTR resource records for hosts:

dnsmasq__dns_records:
  - ptr: '40.2.0.192.in-addr.arpa'
    target: 'host1.example.org'
  - ptr: '{{ "192.0.2.50" | ipaddr("revdns") }}'
    target: 'host2.example.org'

  Syntax

Each entry in the list is a YAML dictionary with specific parameters:

state
    Optional. If not specified or present, the entry will be added in the configuration file. If absent, the entry will be removed from the configuration file. If comment, the entry will be included in the configuration file, but commented out.

comment
    Optional. String or a YAML text block with a comment added to a given configuration entry.

address / ip / ipaddr
    Optional. Specify an IPv4 or IPv6 address, or a YAML list of addresses for a given entry.

    In DHCP host configuration this parameter specifies the IP addresses which will be reserved for a particular host.

    In DNS record configuration this parameter along with the host / a / aaaa parameter defines a DNS A record; in case of multiple IP addresses, the first IP address will be used to create the host's DNS PTR record.

cname
    Optional. If defined in a DHCP client configuration, it's a list of DNS subdomains to add in the DNS database (the domain parameter is also required in this case). All of the subdomains will point at a given host.

    If defined in a DNS record, it's a Fully Qualified Domain Name that can be used to reference a specific target name. The target parameter is required in this case.

raw Optional. A string or YAML text block with raw dnsmasq configuration, which will be included in the generated file as-is.

    The parameters below are related to DHCP host configuration:

name / hostname
    Optional. Specify the hostname for a given DHCP client which will be registered in the DNS. This overrides any hostname sent by the client.

hwaddr / mac
    Optional. Specify the media access control address <https://en.wikipedia.org/wiki/MAC_address> of a host to create a DHCP client entry for it. You can specify multiple MAC addresses as a YAML list to set DHCP options shared between multiple hosts with different MAC addresses.

id  Optional. Specify the DHCP Unique Identifier <https://en.wikipedia.org/wiki/DHCPv6#DHCP_Unique_Identifier> used in DHCPv6 configuration to identify a given DHCP client. Only one DUID can be used at a time.

tag Optional. Set a tag for a given DHCP client. This tag can be referenced by other dnsmasq configuration options to target specific DHCP clients or sets of clients.

lease
    Optional. Specify lease time for an IP address of a given DHCP client. If not specified, leases will be given for 24 hours (24h).

ignore
    Optional, boolean. If specified and True, dnsmasq will ignore DHCP client requests from a specific MAC address.

domain
    Optional. Specify a DNS domain on which a given DHCP client should be published. Only one domain at a time is allowed. The domain will be added to the DNS service managed by dnsmasq, the FQDN of the host will be pointed to its IPv4 and IPv6 addresses. Any subdomains specified with the cname parameter will be added to the DNS and pointed at the DHCP client.

    The parameters below are related to DNS record configuration:

host / a / aaaa
    Optional. Define a DNS A and/or AAAA record for a FQDN hostname. This parameter is used to define the hostname, and the address, ip, ipaddr or target parameter, which specifies the IP address, is required to complete the DNS record.

txt Optional. Define a DNS TXT record. This parameter specifies the resource name, the value or target parameters are required to complete the record.

value
    Optional. Specify the content of the DNS TXT record, either as a string or as a YAML list.

ptr Optional. Define the DNS PTR record. This parameter specifies the IP address in the Reverse DNS lookup <https://en.wikipedia.org/wiki/Reverse_DNS_lookup> format. The target parameter is required and specifies the corresponding DNS A or AAAA record.

mx  Optional. Define a DNS MX record for a particular domain. Specify only the domain part (example.org), not a FQDN address (other.example.org).

    If only the mx parameter is specified, the dnsmasq DNS server will point to its own host as the MX host. If you want to specify a different host instead, you can do so by adding the target parameter. Optional preference or prioritty parameters can be used to specify the MX record priority.

srv Optional. Define DNS SRV Records. The parameter value is the name of the SRV record; the target and port parameters are required while the preference, priority and weight parameters are optional, see DNS SRV Records for further details.

target
    Optional. This parameter is used in various DNS record entries to specify the "value" of a given DNS resource, usually a hostname, an IP address or other data.

preference / priority
    Optional. These parameters are used with SRV or MX records to define priority for a given record, and tell the clients the desired order in which they should connect when there are multiple targets. The lower priority wins.

weight
    Optional. This parameter is used in the SRV record to further order different targets with the same priority.

port
    Optional. This parameter is used in the SRV record to specify the TCP/UDP port to which a given client should connect to. You can specify different ports for different targets if needed.

    The DNS record names (A, AAAA, CNAME, PTR, SRV, TXT, MX) can be specified as uppercase or lowercase.

  dnsmasq__configuration

The dnsmasq__*_configuration variables define the contents of the /etc/dnsmasq.d/* configuration files. Each variable is a list of YAML dictionaries. The list entries with the same name parameter are merged together; this allows to change specific parameters in the Ansible inventory without the need to copy over the entire variable contents.

The interface configuration defined using the dnsmasq__*_interfaces variables is converted to this format via a lookup template, therefore it's possible to augment it using the dnsmasq__*_configuration variables.

  Examples

To see the examples of the configuration, you can look at the dnsmasq__default_configuration variable which defines the dnsmasq default configuration set by the role.

  Syntax

Each entry in the list is a YAML dictionary that describes one file in the /etc/dnsmasq.d/ directory, using specific parameters:

name
    Required. The filename of the generated configuration file, it should include a .conf extension. This parameter is used to merge multiple entries with the same name together.

filename
    Optional. This parameter can be used to override the filename used by the role, for example if you want to modify a different file than the name parameter would suggest.

state
    Optional. If not specified or present, the given configuration file will be generated. If absent, the configuration file will not be generated and existing configuration file will be removed. If ignore, a given configuration entry will not be evaluated by the role; this can be used to enable or disable configuration entries conditionally.

    If init, a given configuration entry will be prepared by the role, but it will not be activated by default - these entries can be activated via Ansible inventory by setting the parameter to present.

comment
    Optional. A string or YAML text block with a comment added at the top of the generated configuration file.

raw Optional. YAML text block with raw dnsmasq configuration file options. See dnsmasq(8) <https://manpages.debian.org/dnsmasq(8)> for syntax and possible options.

options
    Optional. A YAML list of dnsmasq configuration options defined in the configuration file. The options parameters from different configuration entries are merged together, therefore it's easy to modify specific parameters without the need to copy the entire value to the inventory.

    Each element of the options list is a YAML dictionary with specific parameters:

name
    Required. This parameter defines the option name, and it needs to be unique in a given configuration file. Parameters from different options lists with the same name are merged together when the configuration entries are merged.

option
    Optional. Because dnsmasq configuration files can specify the same options multiple times, and the name parameter has to be unique to correctly merge the options lists, the option parameter can be used to specify the "actual" option name to be used in the configuration file.

value
    Optional. Specify the option value for a given option.

raw Optional. Specify the raw dnsmasq(8) <https://manpages.debian.org/dnsmasq(8)> configuration options as a string or a YAML text block. You can use this parameter to define dnsmasq options that don't have specific values, for example bogus-priv or rebind-localhost-ok.

state
    Optional. If not specified or present, a given option will be included in the configuration file. If absent, an option will be removed from the configuration file. If comment, an option will be included in the configuration file but commented out.

    If init, the option will be prepared by the role but it will not be included in the configuration file. This can be used to activate certain options via Ansible inventory. If ignore, a given configuration entry will not be evaluated by the role. This can be used to conditionally enable or disable options in the configuration files.

comment
    Optional. A string or YAML text block with a comment added to a given option.

AUTHOR
Maciej Delmanowski, Robin Schneider

COPYRIGHT
2014-2022, Maciej Delmanowski, Nick Janetakis, Robin Schneider and others