# 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](#overview) - [Configuration Structure](#configuration-structure) - [General Options](#general-options) - [Top-Level Statements](#top-level-statements) - [ACL](#acl) - [Controls](#controls) - [DLZ (Dynamically Loadable Zones)](#dlz-dynamically-loadable-zones) - [DNSSEC Policy](#dnssec-policy) - [DynDB](#dyndb) - [HTTP](#http) - [Include](#include) - [Key](#key) - [Logging](#logging) - [Options](#options) - [Parental Agents](#parental-agents) - [Primaries](#primaries) - [Server](#server) - [Statistics Channels](#statistics-channels) - [TLS](#tls) - [Trust Anchors](#trust-anchors) - [View](#view) - [Zone](#zone) - [Data Types](#data-types) - [Helper Functions](#helper-functions) - [Examples](#examples) --- ## 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-query` → `allow_query` - `max-cache-ttl` → `max_cache_ttl` - `dnssec-policy` → `dnssec_policy` ## Configuration Structure All configuration is defined through four precedence-based variables that are merged: ```yaml 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: ```yaml bind9_*_config: - name: # Configuration file name (e.g., "named.conf.options") backup: # Optional: Override backup setting for this file : # One or more top-level statements ``` ### General Options ```yaml 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 ```yaml acl: - name: # ACL name (required) addresses: # List of address match elements (required) - # IP, CIDR, or named ACL - ``` **Example:** ```yaml - 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 ```yaml controls: - inet:
# IP address or '*' for all interfaces port: # Optional: Control port (default: 953) allow: # Optional: ACL of allowed hosts - keys: # Optional: List of key names for authentication - read_only: # Optional: Read-only access ``` **Example:** ```yaml - 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 ```yaml dlz: - name: # DLZ database name (required) database: # Database specification (required) search: # Optional: Enable searching ``` **Example:** ```yaml - 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 ```yaml dnssec_policy: - name: # Policy name (required) keys: # Optional: Key configuration - role: # Key role key_directory: # Store in key-directory lifetime: # Key lifetime algorithm: # Algorithm (e.g., "ecdsap256sha256") keysize: # Optional: Key size in bits # Timing parameters (all optional) dnskey_ttl: # TTL for DNSKEY records max_zone_ttl: # Maximum zone TTL parent_ds_ttl: # Parent DS TTL parent_propagation_delay: parent_registration_delay: publish_safety: purge_keys: retire_safety: signatures_refresh: signatures_validity: signatures_validity_dnskey: zone_propagation_delay: # NSEC3 parameters (optional) nsec3param: iterations: optout: salt_length: ``` **Example:** ```yaml - 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 ```yaml dyndb: - name: # DynDB instance name (required) library: # Shared library path (required) arg: # Optional: Arguments to library ``` **Example:** ```yaml - 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 ```yaml http: - name: # HTTP endpoint name (required) endpoints: # List of URL paths - listener_clients: # Optional: Max clients streams_per_connection: # Optional: Max streams ``` **Example:** ```yaml - 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 ```yaml include: - # Absolute or relative path to include - ``` **Example:** ```yaml - 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 ```yaml keylist: - name: # Key name (required) algorithm: # Algorithm (e.g., "hmac-sha256") (required) secret: # Base64-encoded secret (required) ``` **Example:** ```yaml - 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 ```yaml logging: channels: # Define output channels - name: # Channel name (required) # Destination (choose one): file: # Log to file name: # File path (required) versions: # Optional: Number of versions to keep size: # Optional: Max file size suffix: # Optional: Rotation suffix type syslog: # Log to syslog with facility stderr: # Log to stderr null: # Discard messages # Output formatting: severity: # Optional: Minimum severity (e.g., "info", "warning") print_category: # Include category in output print_severity: # Include severity in output print_time: # Timestamp format buffered: # Buffer output categories: # Map categories to channels - name: # Category name (required) channels: # List of channel names - ``` **Example:** ```yaml - 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 ```yaml options: # Directory and file paths directory: # Working directory dump_file: # Cache dump file pid_file: # Process ID file statistics_file: # Statistics output file memstatistics_file: # Memory statistics file # Network interfaces listen_on: # IPv4 listen addresses -
- address:
port: listen_on_v6: # IPv6 listen addresses -
# Query handling allow_query: # Who can query allow_query_cache: # Who can query cache allow_recursion: # Who can recurse recursion: # Enable recursion # Zone transfers allow_transfer: # Who can transfer zones also_notify: # Additional notify targets -
notify: # Notify behavior # Forwarding forward: # Forward mode forwarders: # Forwarding servers -
- address:
port: tls: # DNSSEC dnssec_enable: # DEPRECATED in 9.15+ dnssec_validation: # DNSSEC validation dnssec_lookaside: # DLV domain # Performance tuning max_cache_size: # Maximum cache size max_cache_ttl: # Maximum positive cache TTL max_ncache_ttl: # Maximum negative cache TTL clients_per_query: # Max clients per query max_clients_per_query: # Hard max clients per query # Rate limiting rate_limit: responses_per_second: window: log_only: slip: exempt_clients: errors_per_second: nxdomains_per_second: all_per_second: # Response policy zones (RPZ) response_policy: zones: - zone: policy: max_policy_ttl: min_update_interval: add_soa: log: recursive_only: max_policy_ttl: min_update_interval: break_dnssec: recursive_only: # Other options version: # Version string to report hostname: # Hostname to report server_id: # Server ID empty_zones_enable: # Enable empty zones (RFC 6303) disable_empty_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` ```yaml options: # Query and recursion control allow_new_zones: answer_cookie: automatic_interface_scan: avoid_v4_udp_ports: [, ...] avoid_v6_udp_ports: [, ...] # DNSSEC dnssec_accept_expired: dnssec_dnskey_kskonly: dnssec_loadkeys_interval: dnssec_secure_to_insecure: dnssec_update_mode: # Performance cleaning_interval: heartbeat_interval: interface_interval: max_rsa_exponent_size: max_udp_size: min_cache_ttl: min_ncache_ttl: prefetch: # Logging querylog: # Zone management check_names: check_dup_records: check_integrity: check_mx: check_mx_cname: check_sibling: check_spf: check_srv_cname: check_wildcard: # Transfer control max_transfer_idle_in: max_transfer_idle_out: max_transfer_time_in: max_transfer_time_out: serial_query_rate: transfer_format: transfer_source:
transfer_source_v6:
# Update control allow_update: allow_update_forwarding: # Notification notify_source:
notify_source_v6:
``` **Example:** ```yaml - 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 ```yaml parental_agents: - name: # Parental agents name (required) addresses: # List of addresses (required) -
- address:
port: key: ``` **Example:** ```yaml - 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 ```yaml primaries: - name: # Primaries group name (required) addresses: # List of primary server addresses (required) -
- address:
port: key: ``` **Example:** ```yaml - 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 ```yaml server: - address:
# Server address (required) bogus: # Server is bogus edns: # Use EDNS with this server edns_udp_size: # EDNS UDP size edns_version: # EDNS version keys: # TSIG key for this server max_udp_size: # Maximum UDP packet size notify_source:
# Source address for notifies provide_ixfr: # Provide IXFR to this server query_source:
# Source for queries to this server request_expire: # Request EXPIRE request_ixfr: # Request IXFR request_nsid: # Request NSID send_cookie: # Send DNS cookies tcp_keepalive: # Use TCP keepalive tcp_only: # Use TCP only transfer_format: transfer_source:
transfers: # Concurrent transfers ``` **Example:** ```yaml - 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 ```yaml statistics_channels: - inet:
# Listen address (required) port: # Port number (required) allow: # Optional: ACL of allowed clients - ``` **Example:** ```yaml - 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 ```yaml tls: - name: # TLS configuration name (required) key_file: # Private key file (required) cert_file: # Certificate file (required) ca_file: # Optional: CA certificate file dhparam_file: # Optional: DH parameters file remote_hostname: # Optional: Expected remote hostname protocols: # Optional: TLS protocol versions - ciphers: # Optional: Cipher suite prefer_server_ciphers: # Optional: Prefer server ciphers session_tickets: # Optional: Enable session tickets ``` **Example:** ```yaml - 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 ```yaml trust_anchors: - name: # Domain name (required) type: # Anchor type keys: # List of keys/DS records - ``` **Example:** ```yaml - 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. ```yaml view: - name: # View name (required) match_clients: # Client match list (required) - match_destinations: # Optional: Destination match list - # 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:** ```yaml - 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 ```yaml zones: - name: # Zone name (required) type: # Zone type (required) # File and directory options file: # Zone file path journal: # Journal file path key_directory: # DNSSEC key directory # Transfer and notification allow_notify: # Who can send NOTIFY - allow_query: # Who can query - allow_transfer: # Who can transfer - allow_update: # Who can update - also_notify: # Additional notify targets -
- address:
port: key: notify: primaries: # Primary servers (for slave zones) -
- address:
port: key: parental_agents: # Parental agents for DNSSEC -
# Forwarding (for forward zones) forward: forwarders: -
- address:
port: tls: # DNSSEC dnssec_policy: # DNSSEC policy to use inline_signing: # Enable inline signing auto_dnssec: # DEPRECATED: Auto-DNSSEC key_directory: # DNSSEC key directory sig_validity_interval: # Signature validity upper: lower: # Optional # Dynamic update policy update_policy: # local or list of policies # When using structured update policies: # update_policy: # - permission: # identity: # ruletype: # name: # Optional # types: # Zone behavior check_names: dialup: ixfr_from_differences: journal: max_ixfr_ratio: max_journal_size: max_records: max_transfer_idle_in: max_transfer_idle_out: max_transfer_time_in: max_transfer_time_out: max_zone_ttl: notify_delay: notify_source:
notify_source_v6:
# Server configuration server_addresses: # Local server addresses -
server_names: # Local server names - # Statistics and maintenance zone_statistics: # Other options database: # Database specification for DLZ delegation_only: masterfile_format: masterfile_style: ``` **Example - Master Zone:** ```yaml - 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:** ```yaml - 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:** ```yaml - 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: ```yaml 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`): ```yaml # 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]`: ```yaml 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 ```yaml 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 ```yaml 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 ```yaml 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 ```yaml 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: - [BIND 9.18 Documentation](https://bind9.readthedocs.io/en/v9_18/) - [BIND 9.20 Documentation](https://bind9.readthedocs.io/en/v9_20/) For this role's implementation details, see: - [README.md](README.md) - [defaults/main.yml](defaults/main.yml) - [templates/](templates/)