Files
ansible-bind9-role/CONFIGURATION_GRAMMAR.md
Daniel Akulenok db379be31f docs: Add BIND9 version comparison and migration guidance
- Generate BIND_VERSION_DIFFERENCES.md with detailed grammar comparison
- Document 44 breaking changes between BIND9 9.18.44 and 9.20.18
- Document 35 new options and 22 modified options in BIND9 9.20
- Document 3 newly deprecated options
- Add version compatibility section to CONFIGURATION_GRAMMAR.md
- Update CHANGELOG.md with version differences details
- Include migration guide for upgrading from 9.18 to 9.20

Closes #11
2026-02-07 23:43:51 +01:00

34 KiB

BIND9 Ansible Role - Configuration Grammar Reference

This document provides a comprehensive reference for all configuration options available in the BIND9 Ansible role.

Table of Contents


Overview

The BIND9 role uses YAML to replicate the official ISC BIND9 configuration format. Configuration section names match BIND's named.conf format, with kebab-case converted to snake_case:

  • allow-queryallow_query
  • max-cache-ttlmax_cache_ttl
  • dnssec-policydnssec_policy

Version Compatibility

This role and its configuration grammar are based on BIND9 9.18.x (LTS).

For information about upgrading to BIND9 9.20 or later, see BIND9 Version Differences which documents:

  • Breaking changes between versions
  • New features available in newer versions
  • Migration guidance for configuration updates

⚠️ Important: BIND9 9.20 introduces significant breaking changes. Please review the version differences document before upgrading configurations.

Configuration Structure

All configuration is defined through four precedence-based variables that are merged:

bind9_default_config: []   # Default role configuration
bind9_group_config: []     # Group-level overrides
bind9_site_config: []      # Site-level overrides
bind9_host_config: []      # Host-specific configuration (highest precedence)

Each configuration entry follows this structure:

bind9_*_config:
  - name: <filename>        # Configuration file name (e.g., "named.conf.options")
    backup: <bool>          # Optional: Override backup setting for this file
    <statement>: <value>    # One or more top-level statements

General Options

bind9_packages:           # List of packages to install
  - bind9
  - bind9-utils

bind9_cfgdir: /etc/bind                    # Configuration directory
bind9_working_directory: /var/cache/bind   # BIND working directory
bind9_libdir: /var/lib/bind                # Library directory
bind9_backup_dir: /data/backup/bind        # Backup directory

bind9_backup_config: true   # Create backups of config files
bind9_debug_config: false   # Print configuration YAML tree for debugging
bind9_config_indent: 4      # Indentation spaces in generated config files

Top-Level Statements

ACL

Access Control Lists define named groups of IP addresses.

Variable: acl
Type: List of dictionaries

acl:
  - name: <string>          # ACL name (required)
    addresses:              # List of address match elements (required)
      - <address_match>     # IP, CIDR, or named ACL
      - <address_match>

Example:

- name: named.conf.local
  acl:
    - name: mynetwork
      addresses:
        - 10.0.0.0/8
        - 192.168.1.0/24
        - localhost
    - name: trusted
      addresses:
        - mynetwork
        - 172.16.0.0/12

Controls

Defines the control channels for rndc (Remote Name Daemon Control).

Variable: controls
Type: List of dictionaries

controls:
  - inet: <address>         # IP address or '*' for all interfaces
    port: <integer>         # Optional: Control port (default: 953)
    allow:                  # Optional: ACL of allowed hosts
      - <address_match>
    keys:                   # Optional: List of key names for authentication
      - <key_name>
    read_only: <bool>       # Optional: Read-only access

Example:

- name: named.conf.options
  controls:
    - inet: 127.0.0.1
      port: 953
      allow:
        - localhost
      keys:
        - rndc-key

DLZ (Dynamically Loadable Zones)

DLZ allows loading zone data from external sources like databases.

Variable: dlz
Type: List of dictionaries

dlz:
  - name: <string>          # DLZ database name (required)
    database: <string>      # Database specification (required)
    search: <bool>          # Optional: Enable searching

Example:

- name: named.conf.local
  dlz:
    - name: mysql_zone
      database: "mysql bind_db bind_user password localhost"
      search: yes

DNSSEC Policy

Defines DNSSEC signing policies for automatic zone signing.

Variable: dnssec_policy
Type: List of dictionaries

dnssec_policy:
  - name: <string>                      # Policy name (required)
    keys:                               # Optional: Key configuration
      - role: <ksk|zsk>                 # Key role
        key_directory: <bool>           # Store in key-directory
        lifetime: <duration>            # Key lifetime
        algorithm: <algorithm>          # Algorithm (e.g., "ecdsap256sha256")
        keysize: <integer>              # Optional: Key size in bits
    
    # Timing parameters (all optional)
    dnskey_ttl: <duration>              # TTL for DNSKEY records
    max_zone_ttl: <duration>            # Maximum zone TTL
    parent_ds_ttl: <duration>           # Parent DS TTL
    parent_propagation_delay: <duration>
    parent_registration_delay: <duration>
    publish_safety: <duration>
    purge_keys: <duration>
    retire_safety: <duration>
    signatures_refresh: <duration>
    signatures_validity: <duration>
    signatures_validity_dnskey: <duration>
    zone_propagation_delay: <duration>
    
    # NSEC3 parameters (optional)
    nsec3param:
      iterations: <integer>
      optout: <bool>
      salt_length: <integer>

Example:

- name: named.conf.local
  dnssec_policy:
    - name: standard
      keys:
        - role: ksk
          lifetime: unlimited
          algorithm: ecdsap256sha256
        - role: zsk
          lifetime: 90d
          algorithm: ecdsap256sha256
      dnskey_ttl: 1h
      max_zone_ttl: 86400
      signatures_validity: 14d

DynDB

Dynamic database backend for BIND (used for plugins like LDAP).

Variable: dyndb
Type: List of dictionaries

dyndb:
  - name: <string>          # DynDB instance name (required)
    library: <path>         # Shared library path (required)
    arg: <string>           # Optional: Arguments to library

Example:

- name: named.conf.local
  dyndb:
    - name: ldap_zone
      library: /usr/lib/bind/ldap.so
      arg: "uri ldap://ldap.example.com base dc=example,dc=com"

HTTP

Configures HTTP endpoints for DNS-over-HTTPS (DoH).

Variable: http
Type: List of dictionaries

http:
  - name: <string>          # HTTP endpoint name (required)
    endpoints:              # List of URL paths
      - <path>
    listener_clients: <integer>  # Optional: Max clients
    streams_per_connection: <integer>  # Optional: Max streams

Example:

- name: named.conf.options
  http:
    - name: default
      endpoints:
        - /dns-query
      listener_clients: 100
      streams_per_connection: 100

Include

Includes external configuration files.

Variable: include
Type: List of strings

include:
  - <filepath>              # Absolute or relative path to include
  - <filepath>

Example:

- name: named.conf
  include:
    - /etc/bind/named.conf.options
    - /etc/bind/named.conf.local
    - /etc/bind/zones.rfc1918

Key

Defines cryptographic keys for TSIG authentication.

Variable: keylist (Note: 'key' is reserved in YAML)
Type: List of dictionaries

keylist:
  - name: <string>          # Key name (required)
    algorithm: <string>     # Algorithm (e.g., "hmac-sha256") (required)
    secret: <string>        # Base64-encoded secret (required)

Example:

- name: named.conf.keys
  keylist:
    - name: rndc-key
      algorithm: hmac-sha256
      secret: "c3Ryb25nIHNlY3JldCBoZXJl"
    - name: transfer-key
      algorithm: hmac-md5
      secret: "YW5vdGhlciBzZWNyZXQ="

Logging

Configures BIND's logging system with channels and categories.

Variable: logging
Type: Dictionary

logging:
  channels:                 # Define output channels
    - name: <string>        # Channel name (required)
      
      # Destination (choose one):
      file:                 # Log to file
        name: <path>        # File path (required)
        versions: <integer> # Optional: Number of versions to keep
        size: <size>        # Optional: Max file size
        suffix: <increment|timestamp>  # Optional: Rotation suffix type
      syslog: <facility>    # Log to syslog with facility
      stderr: <bool>        # Log to stderr
      null: <bool>          # Discard messages
      
      # Output formatting:
      severity: <level>     # Optional: Minimum severity (e.g., "info", "warning")
      print_category: <bool>  # Include category in output
      print_severity: <bool>  # Include severity in output
      print_time: <bool|iso8601|iso8601-utc|local>  # Timestamp format
      buffered: <bool>      # Buffer output
  
  categories:               # Map categories to channels
    - name: <category>      # Category name (required)
      channels:             # List of channel names
        - <channel_name>

Example:

- name: named.conf.options
  logging:
    channels:
      - name: default_log
        file:
          name: /var/log/bind/default.log
          versions: 3
          size: 5m
          suffix: increment
        severity: info
        print_category: yes
        print_severity: yes
        print_time: yes
      
      - name: query_log
        file:
          name: /var/log/bind/query.log
          versions: 10
          size: 50m
        severity: debug 3
        print_time: iso8601
    
    categories:
      - name: default
        channels:
          - default_log
      - name: queries
        channels:
          - query_log
      - name: security
        channels:
          - default_log

Options

Global server options and defaults. This is the most comprehensive section with hundreds of possible options.

Variable: options
Type: Dictionary

Common Options

options:
  # Directory and file paths
  directory: <path>                     # Working directory
  dump_file: <path>                     # Cache dump file
  pid_file: <path>                      # Process ID file
  statistics_file: <path>               # Statistics output file
  memstatistics_file: <path>            # Memory statistics file
  
  # Network interfaces
  listen_on:                            # IPv4 listen addresses
    - <address>
    - address: <address>
      port: <port>
  listen_on_v6:                         # IPv6 listen addresses
    - <address>
  
  # Query handling
  allow_query: <acl>                    # Who can query
  allow_query_cache: <acl>              # Who can query cache
  allow_recursion: <acl>                # Who can recurse
  recursion: <bool>                     # Enable recursion
  
  # Zone transfers
  allow_transfer: <acl>                 # Who can transfer zones
  also_notify:                          # Additional notify targets
    - <address>
  notify: <yes|no|explicit|master-only>  # Notify behavior
  
  # Forwarding
  forward: <first|only>                 # Forward mode
  forwarders:                           # Forwarding servers
    - <address>
    - address: <address>
      port: <port>
      tls: <tls_name>
  
  # DNSSEC
  dnssec_enable: <bool>                 # DEPRECATED in 9.15+
  dnssec_validation: <yes|no|auto>      # DNSSEC validation
  dnssec_lookaside: <domain>            # DLV domain
  
  # Performance tuning
  max_cache_size: <size>                # Maximum cache size
  max_cache_ttl: <duration>             # Maximum positive cache TTL
  max_ncache_ttl: <duration>            # Maximum negative cache TTL
  clients_per_query: <integer>          # Max clients per query
  max_clients_per_query: <integer>      # Hard max clients per query
  
  # Rate limiting
  rate_limit:
    responses_per_second: <integer>
    window: <integer>
    log_only: <bool>
    slip: <integer>
    exempt_clients: <acl>
    errors_per_second: <integer>
    nxdomains_per_second: <integer>
    all_per_second: <integer>
  
  # Response policy zones (RPZ)
  response_policy:
    zones:
      - zone: <zone_name>
        policy: <given|disabled|passthru|nxdomain|nodata|cname>
        max_policy_ttl: <duration>
        min_update_interval: <duration>
        add_soa: <bool>
        log: <bool>
        recursive_only: <bool>
    max_policy_ttl: <duration>
    min_update_interval: <duration>
    break_dnssec: <bool>
    recursive_only: <bool>
  
  # Other options
  version: <string>                     # Version string to report
  hostname: <string>                    # Hostname to report
  server_id: <string>                   # Server ID
  empty_zones_enable: <bool>            # Enable empty zones (RFC 6303)
  disable_empty_zone: <zone>            # Disable specific empty zone

All Available Options

The options section supports all BIND9 options. Here's an extensive list:

Boolean Options: Use yes/no or true/false

options:
  # Query and recursion control
  allow_new_zones: <bool>
  answer_cookie: <bool>
  automatic_interface_scan: <bool>
  avoid_v4_udp_ports: [<port>, ...]
  avoid_v6_udp_ports: [<port>, ...]
  
  # DNSSEC
  dnssec_accept_expired: <bool>
  dnssec_dnskey_kskonly: <bool>
  dnssec_loadkeys_interval: <duration>
  dnssec_secure_to_insecure: <bool>
  dnssec_update_mode: <maintain|no-resign>
  
  # Performance
  cleaning_interval: <duration>
  heartbeat_interval: <duration>
  interface_interval: <duration>
  max_rsa_exponent_size: <integer>
  max_udp_size: <integer>
  min_cache_ttl: <duration>
  min_ncache_ttl: <duration>
  prefetch: <integer> <integer>
  
  # Logging
  querylog: <bool>
  
  # DNSTAP - DNS traffic capture
  dnstap:                               # List of message types to capture
    - type: <auth|client|forwarder|resolver>  # Message type (required)
      log: <query|response>             # Optional: specific direction
  dnstap_output:                        # Output destination (required if dnstap is set)
    output_type: <file|unix>            # Output type: file or unix socket (required)
    output_file: <path>                 # File path or socket path (required)
    size: <size>                        # Optional: Max file size before rotation
    versions: <integer>                 # Optional: Number of versions to keep
    suffix: <increment|timestamp>       # Optional: Rotation suffix type
  dnstap_identity: <string>             # Optional: Identity string (defaults to hostname)
  dnstap_version: <string>              # Optional: Version string (defaults to BIND version)
  
  # Zone management
  check_names: <master|slave|response> <warn|fail|ignore>
  check_dup_records: <warn|fail|ignore>
  check_integrity: <bool>
  check_mx: <warn|fail|ignore>
  check_mx_cname: <warn|fail|ignore>
  check_sibling: <bool>
  check_spf: <warn|ignore>
  check_srv_cname: <warn|fail|ignore>
  check_wildcard: <bool>
  
  # Transfer control
  max_transfer_idle_in: <duration>
  max_transfer_idle_out: <duration>
  max_transfer_time_in: <duration>
  max_transfer_time_out: <duration>
  serial_query_rate: <integer>
  transfer_format: <one-answer|many-answers>
  transfer_source: <address>
  transfer_source_v6: <address>
  
  # Update control
  allow_update: <acl>
  allow_update_forwarding: <acl>
  
  # Notification
  notify_source: <address>
  notify_source_v6: <address>

Example:

- name: named.conf.options
  options:
    directory: /var/cache/bind
    
    listen_on:
      - 127.0.0.1
      - 192.168.1.1
    listen_on_v6:
      - "::1"
    
    allow_query:
      - any
    allow_recursion:
      - localhost
      - mynetwork
    
    recursion: yes
    
    forwarders:
      - 1.1.1.1
      - address: 8.8.8.8
        tls: dot-tls
    
    dnssec_validation: auto
    
    max_cache_size: 256m
    max_cache_ttl: 86400
    
    version: none
    querylog: yes

Parental Agents

Defines groups of parental agents for DNSSEC chain of trust management.

Variable: parental_agents
Type: List of dictionaries

parental_agents:
  - name: <string>          # Parental agents name (required)
    addresses:              # List of addresses (required)
      - <address>
      - address: <address>
        port: <port>
        key: <key_name>

Example:

- name: named.conf.local
  parental_agents:
    - name: parent_nameservers
      addresses:
        - 192.0.2.1
        - address: 192.0.2.2
          port: 53
          key: transfer-key

Primaries

Defines groups of primary servers for zone transfers (replaces 'masters' in BIND 9.16+).

Variable: primaries
Type: List of dictionaries

primaries:
  - name: <string>          # Primaries group name (required)
    addresses:              # List of primary server addresses (required)
      - <address>
      - address: <address>
        port: <port>
        key: <key_name>

Example:

- name: named.conf.local
  primaries:
    - name: internal_primaries
      addresses:
        - 10.0.0.1
        - address: 10.0.0.2
          port: 5353
          key: transfer-key

Server

Per-server options for fine-tuning communication with specific nameservers.

Variable: server
Type: List of dictionaries

server:
  - address: <address>      # Server address (required)
    bogus: <bool>           # Server is bogus
    edns: <bool>            # Use EDNS with this server
    edns_udp_size: <integer>  # EDNS UDP size
    edns_version: <integer>   # EDNS version
    keys: <key_name>        # TSIG key for this server
    max_udp_size: <integer>   # Maximum UDP packet size
    notify_source: <address>  # Source address for notifies
    provide_ixfr: <bool>    # Provide IXFR to this server
    query_source: <address>   # Source for queries to this server
    request_expire: <bool>  # Request EXPIRE
    request_ixfr: <bool>    # Request IXFR
    request_nsid: <bool>    # Request NSID
    send_cookie: <bool>     # Send DNS cookies
    tcp_keepalive: <bool>   # Use TCP keepalive
    tcp_only: <bool>        # Use TCP only
    transfer_format: <one-answer|many-answers>
    transfer_source: <address>
    transfers: <integer>    # Concurrent transfers

Example:

- name: named.conf.options
  server:
    - address: 192.0.2.1
      bogus: no
      edns: yes
      keys: server-key
      transfers: 2
    - address: 192.0.2.2
      tcp_only: yes

Statistics Channels

Configures HTTP/HTTPS endpoints for server statistics.

Variable: statistics_channels
Type: List of dictionaries

statistics_channels:
  - inet: <address>         # Listen address (required)
    port: <integer>         # Port number (required)
    allow:                  # Optional: ACL of allowed clients
      - <address_match>

Example:

- name: named.conf.options
  statistics_channels:
    - inet: 127.0.0.1
      port: 8053
      allow:
        - localhost
    - inet: 192.168.1.1
      port: 8053
      allow:
        - mynetwork

TLS

Defines TLS configurations for DNS-over-TLS (DoT).

Variable: tls
Type: List of dictionaries

tls:
  - name: <string>          # TLS configuration name (required)
    key_file: <path>        # Private key file (required)
    cert_file: <path>       # Certificate file (required)
    ca_file: <path>         # Optional: CA certificate file
    dhparam_file: <path>    # Optional: DH parameters file
    remote_hostname: <hostname>  # Optional: Expected remote hostname
    protocols:              # Optional: TLS protocol versions
      - <TLSv1.2|TLSv1.3>
    ciphers: <string>       # Optional: Cipher suite
    prefer_server_ciphers: <bool>  # Optional: Prefer server ciphers
    session_tickets: <bool>        # Optional: Enable session tickets

Example:

- name: named.conf.options
  tls:
    - name: dot-server
      key_file: /etc/bind/tls/privkey.pem
      cert_file: /etc/bind/tls/cert.pem
      ca_file: /etc/bind/tls/ca.pem
      protocols:
        - TLSv1.2
        - TLSv1.3
      prefer_server_ciphers: yes

Trust Anchors

Defines DNSSEC trust anchors for validation.

Variable: trust_anchors
Type: List of dictionaries

trust_anchors:
  - name: <domain>          # Domain name (required)
    type: <static-key|static-ds|initial-key|initial-ds>  # Anchor type
    keys:                   # List of keys/DS records
      - <key_data>

Example:

- name: named.conf.options
  trust_anchors:
    - name: "."
      type: initial-key
      keys:
        - "257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="

View

Views allow different responses based on client source.

Variable: view
Type: List of dictionaries

Views can contain most top-level statements (zones, options, etc.) and apply them only to matching clients.

view:
  - name: <string>          # View name (required)
    match_clients:          # Client match list (required)
      - <address_match>
    match_destinations:     # Optional: Destination match list
      - <address_match>
    
    # Any top-level statement can be included in a view:
    zones: [...]            # Zone definitions for this view
    options: {...}          # Options specific to this view
    # ... other statements

Example:

- name: named.conf.local
  view:
    - name: internal
      match_clients:
        - 10.0.0.0/8
        - 192.168.0.0/16
      zones:
        - name: example.com
          type: master
          file: /var/lib/bind/db.example.com.internal
      options:
        recursion: yes
        allow_query:
          - any
    
    - name: external
      match_clients:
        - any
      zones:
        - name: example.com
          type: master
          file: /var/lib/bind/db.example.com.external
      options:
        recursion: no
        allow_query:
          - any

Zone

Defines DNS zones (forward, reverse, master, slave, etc.).

Variable: zones (Note: singular 'zone' is reserved)
Type: List of dictionaries

zones:
  - name: <domain>          # Zone name (required)
    type: <master|slave|stub|hint|forward|redirect|mirror|static-stub>  # Zone type (required)
    
    # File and directory options
    file: <path>            # Zone file path
    journal: <path>         # Journal file path
    key_directory: <path>   # DNSSEC key directory
    
    # Transfer and notification
    allow_notify:           # Who can send NOTIFY
      - <address_match>
    allow_query:            # Who can query
      - <address_match>
    allow_transfer:         # Who can transfer
      - <address_match>
    allow_update:           # Who can update
      - <address_match>
    also_notify:            # Additional notify targets
      - <address>
      - address: <address>
        port: <port>
        key: <key_name>
    notify: <yes|no|explicit|master-only>
    primaries:              # Primary servers (for slave zones)
      - <address>
      - address: <address>
        port: <port>
        key: <key_name>
    parental_agents:        # Parental agents for DNSSEC
      - <address>
    
    # Forwarding (for forward zones)
    forward: <first|only>
    forwarders:
      - <address>
      - address: <address>
        port: <port>
        tls: <tls_name>
    
    # DNSSEC
    dnssec_policy: <policy_name>  # DNSSEC policy to use
    inline_signing: <bool>        # Enable inline signing
    auto_dnssec: <allow|maintain|off>  # DEPRECATED: Auto-DNSSEC
    key_directory: <path>         # DNSSEC key directory
    sig_validity_interval:        # Signature validity
      upper: <duration>
      lower: <duration>           # Optional
    
    # Dynamic update policy
    update_policy: <local|{...}>  # local or list of policies
    # When using structured update policies:
    # update_policy:
    #   - permission: <grant|deny>
    #     identity: <string>
    #     ruletype: <name|subdomain|wildcard|self|selfsub|selfwild|ms-self|ms-subdomain|krb5-self|krb5-subdomain|...>
    #     name: <pattern>         # Optional
    #     types: <type_list>
    
    # Zone behavior
    check_names: <warn|fail|ignore>
    dialup: <yes|no|notify|refresh|passive|notify-passive>
    ixfr_from_differences: <yes|no|master|slave>
    journal: <path>
    max_ixfr_ratio: <percent|unlimited>
    max_journal_size: <size|unlimited>
    max_records: <integer>
    max_transfer_idle_in: <duration>
    max_transfer_idle_out: <duration>
    max_transfer_time_in: <duration>
    max_transfer_time_out: <duration>
    max_zone_ttl: <duration|unlimited>
    notify_delay: <duration>
    notify_source: <address>
    notify_source_v6: <address>
    
    # Server configuration
    server_addresses:       # Local server addresses
      - <address>
    server_names:           # Local server names
      - <hostname>
    
    # Statistics and maintenance
    zone_statistics: <yes|no|terse|full>
    
    # Other options
    database: <string>      # Database specification for DLZ
    delegation_only: <bool>
    masterfile_format: <text|raw>
    masterfile_style: <full|relative>

Example - Master Zone:

- name: named.conf.local
  zones:
    - name: example.com
      type: master
      file: /var/lib/bind/db.example.com
      allow_transfer:
        - 192.0.2.1
        - 192.0.2.2
      also_notify:
        - 192.0.2.1
        - address: 192.0.2.2
          key: transfer-key
      dnssec_policy: standard
      zone_statistics: yes

Example - Slave Zone:

- name: named.conf.local
  zones:
    - name: example.org
      type: slave
      file: /var/cache/bind/db.example.org
      primaries:
        - 192.0.2.10
        - address: 192.0.2.11
          port: 5353
          key: transfer-key
      allow_notify:
        - 192.0.2.10
        - 192.0.2.11

Example - Forward Zone:

- name: named.conf.local
  zones:
    - name: internal.corp
      type: forward
      forward: only
      forwarders:
        - 10.0.0.1
        - address: 10.0.0.2
          tls: internal-tls

Data Types

Address Match Elements

Address match elements can be:

  • IP address: 192.168.1.1, 2001:db8::1
  • CIDR notation: 192.168.0.0/16, 10.0.0.0/8
  • Named ACL: localhost, localnets, any, none, or custom ACL name
  • Negation: !192.168.1.1, !mynetwork

Durations

Durations can be specified with units:

  • Seconds: 3600 or 3600s
  • Minutes: 60m
  • Hours: 24h
  • Days: 7d
  • Weeks: 4w
  • unlimited for no limit

Sizes

Sizes can be specified with units:

  • Bytes: 1024 or 1024B
  • Kilobytes: 512K
  • Megabytes: 256M
  • Gigabytes: 2G
  • unlimited or default for defaults

Boolean Values

YAML booleans (true/false, yes/no) are automatically converted to BIND's yes/no.

Special Values

Some options accept special keywords:

  • '0' - String zero (use quotes to distinguish from null)
  • 'null' - String null (use quotes)
  • none - BIND's none keyword
  • any - BIND's any keyword

Helper Functions

The role provides several helper macros for common patterns:

Address Lists

Simple list of addresses:

addresses:
  - 192.168.1.1
  - 192.168.1.2
  - 10.0.0.0/8

Address with Port/TLS

For options accepting address [port X] [tls Y] (e.g., forwarders):

# Simple list
forwarders:
  - 1.1.1.1
  - 8.8.8.8

# With global port/tls
forwarders:
  port: 853
  tls: dot-tls
  addresses:
    - 1.1.1.1
    - 8.8.8.8

# Per-address port/tls
forwarders:
  - address: 1.1.1.1
    port: 53
  - address: 8.8.8.8
    port: 853
    tls: cloudflare-tls

# Mixed format
forwarders:
  - 1.1.1.1
  - address: 8.8.8.8
    port: 853
    tls: dot-tls

Address with Key/TLS

For options accepting address [key X] [tls Y]:

primaries:
  - 192.0.2.1
  - address: 192.0.2.2
    key: transfer-key
  - address: 192.0.2.3
    key: transfer-key
    tls: dot-server

Examples

Complete Recursive Server

bind9_host_config:
  - name: named.conf
    include:
      - /etc/bind/named.conf.options
      - /etc/bind/named.conf.local
      - /etc/bind/zones.rfc1918
  
  - name: named.conf.local
    acl:
      - name: trusted
        addresses:
          - 192.168.0.0/16
          - 10.0.0.0/8
          - localhost
  
  - name: named.conf.options
    options:
      directory: /var/cache/bind
      
      recursion: yes
      allow_recursion:
        - trusted
      allow_query:
        - trusted
      
      forwarders:
        - 1.1.1.1
        - 8.8.8.8
      
      dnssec_validation: auto
      
      listen_on:
        - 192.168.1.1
      listen_on_v6:
        - none

Authoritative Server with DNSSEC

bind9_host_config:
  - name: named.conf.keys
    keylist:
      - name: transfer-key
        algorithm: hmac-sha256
        secret: "your-secret-here"
  
  - name: named.conf.local
    dnssec_policy:
      - name: standard
        keys:
          - role: ksk
            lifetime: unlimited
            algorithm: ecdsap256sha256
          - role: zsk
            lifetime: 90d
            algorithm: ecdsap256sha256
        dnskey_ttl: 1h
        signatures_validity: 14d
    
    zones:
      - name: example.com
        type: master
        file: /var/lib/bind/db.example.com
        dnssec_policy: standard
        allow_transfer:
          - address: 192.0.2.1
            key: transfer-key
        also_notify:
          - 192.0.2.1
        notify: yes
  
  - name: named.conf.options
    options:
      directory: /var/cache/bind
      recursion: no
      allow_query:
        - any

Split Horizon DNS with Views

bind9_host_config:
  - name: named.conf.local
    acl:
      - name: internal
        addresses:
          - 10.0.0.0/8
          - 192.168.0.0/16
    
    view:
      - name: internal_view
        match_clients:
          - internal
        zones:
          - name: example.com
            type: master
            file: /var/lib/bind/internal/db.example.com
        options:
          recursion: yes
          allow_query:
            - any
      
      - name: external_view
        match_clients:
          - any
        zones:
          - name: example.com
            type: master
            file: /var/lib/bind/external/db.example.com
        options:
          recursion: no
          allow_query:
            - any

Advanced Logging Configuration

bind9_host_config:
  - name: named.conf.options
    logging:
      channels:
        - name: default_log
          file:
            name: /var/log/bind/default.log
            versions: 5
            size: 10m
            suffix: increment
          severity: info
          print_category: yes
          print_severity: yes
          print_time: iso8601
        
        - name: query_log
          file:
            name: /var/log/bind/queries.log
            versions: 10
            size: 100m
          severity: debug 3
          print_time: yes
        
        - name: security_log
          file:
            name: /var/log/bind/security.log
            versions: 3
            size: 5m
          severity: warning
        
        - name: null_channel
          null: yes
      
      categories:
        - name: default
          channels:
            - default_log
        - name: queries
          channels:
            - query_log
        - name: security
          channels:
            - security_log
        - name: xfer-in
          channels:
            - default_log
        - name: xfer-out
          channels:
            - default_log
        - name: notify
          channels:
            - default_log
        - name: update
          channels:
            - default_log

Notes and Best Practices

  1. Reserved Keywords: key and keys are reserved in YAML/Python. Use keylist and keyname instead.

  2. Null vs Zero: Use quoted strings for literal values:

    • var: '0' for integer zero
    • var: 'null' for the string "null"
    • var: 0 becomes null/empty in Jinja
  3. File Organization: Keep related configurations together:

    • Put ACLs and keys in named.conf.local or separate files
    • Keep options in named.conf.options
    • Group zones logically
  4. Testing: Use bind9_debug_config: true to see the merged YAML before templating.

  5. Backups: Enable bind9_backup_config: true during initial setup, disable in production.

  6. Validation: The role automatically validates configuration before reloading BIND.

  7. Precedence: Configuration merges in order:

    • bind9_default_config (lowest)
    • bind9_group_config
    • bind9_site_config
    • bind9_host_config (highest)

Reference

For the complete BIND9 configuration reference, see:

For this role's implementation details, see: