Files
ansible-bind9-role/README.md

9.6 KiB

bind9

A feature-complete ansible role for installing and configuring bind9. The purpose of this role is to fully template out the entire official bind9 configuration file format.

What the role does:

  • Fully configures named.conf
  • Checks that the config is valid
  • Loads the config into bind

What the role does not do:

  • Manage your zones and records
  • Maintain every aspect of bind (rndc config, etc)
  • Auto-generate and manage your secrets

Bugs

Or, as I call them "happy accidents".

  • If you need a variable to be 0 or null, you need to define it as var: '0' or var: 'null', otherwise jinja will assume you want it to be empty/null. Normal integers would be defined as var: 1, letting jinja type it as an integer.
  • If a named configuration option has the name 'key' or 'keys', it will be referenced as 'keyname' or 'keylist' respectively. key/keys are reserved values in most languages.

Configuration Grammar

The bind9 role tries to replicate the official ISC bind9 configuration format as close as possible, only re-implementing them in YAML format. This means that for the most part, section names are the same as in named.conf but kebab-case ('var-name') is replaced with snake_case ('var_name') If you are missing some statements in your resulting config, it is most likely because of this.

The main configuration variable used are a series of bind_*_config variables (See [Role Variables]) that have the following syntax

Every config starts by defining the file name. Each file can contain any amount of top-level statements, as permitted by named.conf

bind9_host_config:
  - name: FILENAME # The filename of your desired config file.
                   # You also need to specify a corresponding `include:` for the file
    SECTION_NAME: # The section name of the bind config you want to define.
                  # Can be 'acl', 'options', 'zone', etc.
                  # See: https://bind9.readthedocs.io/en/v9_18_4/reference.html#configuration-file-grammar
    SECTION_2_NAME: # Every file can have as many sections as needed. Generally, try to keep 
                    # all definitions and references together in a file.

Any option that can be defined multiple times in a named.conf, must be defined as a list

bind9_host_config:
  - name: named.conf.local
    acl:
      - name: ELEMENT_NAME
        addresses: 
          - 127.0.0.1
          - 127.0.0.2
      - name: ELEMENT_2_NAME
        addresses:
          - 127.0.0.3

Simple options are defined just as that.

      SIMPLE_OPTION: string, boolean or integer value

Some options have several optional parameters. For those, a somewhat flexible configuration format has been created

      IP_PORT_DSCP_OPTION: # Any option that is defined as one of:
      #  <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ dscp <dscp> ]; ... }
      #  <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ key <key> ] [ tls <tls> ]; ... }
      # has a few optional syntaxes 
      # Example 1: Simple address list
        - ADDRESS1
        - ADDRESS2
      # Example 2: To define source port/dscp, use 'addresses' sub-element
        [ port: PORT ]
        [ dscp: DSCP ]
        addresses:
          - ADDRESS1
          - ADDRESS2
          - 127.0.0.1
      # Example 3: To define target port/dscp, use 'addresses' as a list of dicts
        addresses:
          - address: ADDRESS
            [ port: PORT ]
            [ dscp: DSCP ]
          - address: 127.0.0.1
            port: 53
          - address: 127.0.0.1
            dscp: 42
          - address: 127.0.0.1
            port: 5353
            dscp: 42
      # Example 4: The various formats can be mixed and matched within the main element
        - ADDRESS1
        - address: ADDRESS2
          port: PORT

Role Variables

General configuration

Review the defaults for a full set of configurable parameters. Here are the most interesting ones:

bind9_backup_config: [true, false]: Backup each named.conf.* file or not. Default is 'true'. This setting is useful for testing out configuration changes but can clutter up the destination directory quite a bit if used across many updates.

bind9_debug_config: [true, false]: Print the resulting YAML configuration tree that was sent to the configuration template. Default is 'false'. Useful for comparing with the resulting named.conf files and comparing values.

bind9_config_indent: [integer]: Indentation level for the configuration template. Default is '4'. Set this value to suit your style. Tabs are not supported.

named.conf

bind configuration is set through the various bind9_*_config parameters. These are, in order of precedence:

  1. bind9_default_config
  2. bind9_group_config
  3. bind9_leaf_config
  4. bind9_host_config

All these configuration parameters are merged in a way where each successing config supercedes the previous one at a config-file level. To illustrate:

bind9_default_config:
  - name: named.conf.options
    options:
      recursion: true

bind9_group_config:
  - name: named.conf.options
    options:
      recursion: false
      notify: primary-only
  - name: named.conf.local
    zone:
      - name: "."
        type: mirror

bind9_leaf_config:
  - name: named.conf.local
    zone:
      - name: "."
        type: hint
        file: /etc/share/dns/root.hints

The resulting precedence and overwriting of variables will result in the following bind9_config passed to the configuration generator:

bind9_config:
  - name: named.conf.options
    options:
      recursion: false
      notify: primary-only
  - name: named.conf.local
    zone:
      - name: "."
        type: hint
        file: /etc/share/dns/root.hints

The named.conf.options block in bind9_default_config got completely overwritten by the bind9_group_config, and the bind9_leaf_config completely overwrote named.conf.local, however, named.conf.options was left intact after merging with bind9_leaf_config.

Configuration Grammar

The bind9 role tries to replicate the official ISC bind9 configuration format as close as possible, only re-implementing them in YAML format. This means that for the most part, section names are the same as in named.conf but kebab-case ('var-name') is replaced with snake_case ('var_name') If you are missing some statements in your resulting config, it is most likely because of this.

The main configuration variable used are a series of bind_*_config variables (See [Role Variables]) that have the following syntax

Every config starts by defining the file name. Each file can contain any amount of top-level statements, as permitted by named.conf

bind9_host_config:
  - name: FILENAME # The filename of your desired config file.
                   # You also need to specify a corresponding `include:` for the file
    SECTION_NAME: # The section name of the bind config you want to define.
                  # Can be 'acl', 'options', 'zone', etc.
                  # See: https://bind9.readthedocs.io/en/v9_18_4/reference.html#configuration-file-grammar
    SECTION_2_NAME: # Every file can have as many sections as needed. Generally, try to keep 
                    # all definitions and references together in a file.

Any option that can be defined multiple times in a named.conf, must be defined as a list

bind9_host_config:
  - name: named.conf.local
    acl:
      - name: ELEMENT_NAME
        addresses: 
          - 127.0.0.1
          - 127.0.0.2
      - name: ELEMENT_2_NAME
        addresses:
          - 127.0.0.3

Simple options are defined just as that.

      SIMPLE_OPTION: string, boolean or integer value

Some options have several optional parameters. For those, a somewhat flexible configuration format has been created

      IP_PORT_DSCP_OPTION: # Any option that is defined as one of:
      #  <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ dscp <dscp> ]; ... }
      #  <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ key <key> ] [ tls <tls> ]; ... }
      # has a few optional syntaxes 
      # Example 1: Simple address list
        - ADDRESS1
        - ADDRESS2
      # Example 2: To define source port/dscp, use 'addresses' sub-element
        [ port: PORT ]
        [ dscp: DSCP ]
        addresses:
          - ADDRESS1
          - ADDRESS2
          - 127.0.0.1
      # Example 3: To define target port/dscp, use 'addresses' as a list of dicts
        addresses:
          - address: ADDRESS
            [ port: PORT ]
            [ dscp: DSCP ]
          - address: 127.0.0.1
            port: 53
          - address: 127.0.0.1
            dscp: 42
          - address: 127.0.0.1
            port: 5353
            dscp: 42
      # Example 4: The various formats can be mixed and matched within the main element
        - ADDRESS1
        - address: ADDRESS2
          port: PORT

Dependencies

No dependencies

Example Playbook

Simple sample config of a recursive BIND server that allows your localnetwork to resolve addresses via

- hosts: servers
  roles:
     - bind9
  vars:
    bind9_host_config:
      - name: named.conf.local
        acl:
          - name: mylan
            addresses:
              - 10.0.0.0/8
      - name: named.conf.options
        options:
          forwarders:
            - 1.1.1.1
          allow-query:
            - mylan
          allow-recursion:
            - mylan

License

BSD

Author Information

Daniel Akulenok dak@keepit.com Keepit A/S - keepit.com