Daniel Akulenok af3a9c7f33 Documentation
2022-08-30 08:03:51 +00:00
2022-08-19 22:01:36 +02:00
2022-08-04 12:41:40 +02:00
2022-08-04 12:41:40 +02:00
2022-08-04 12:41:40 +02:00
2022-08-19 22:01:36 +02:00
2022-08-04 12:41:40 +02:00
2022-08-04 12:41:40 +02:00
2022-08-04 12:41:40 +02:00
2022-08-30 08:03:51 +00:00

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
  - 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.

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

An optional section for the role authors to include contact information, or a website (HTML is not allowed).

    options:
      forwarders:
        - 1.1.1.1
        - 1.0.0.1
      fetches_per_server: 200 fail
      prefetch: 4 10
      version: none
      hostname: l33t.h4x0r
      avoid_v4_udp_ports:
        - "range 5132 5232"
        - "range 1337 31337"
      servfail_ttl: 0
      allow_notify:
        - 10.0.0.0/8
      allow_query:
        - "!10.0.2.1"
        - 0/0
      blackhole:
        - 192.168.0.0/16
      allow_recursion: []
      empty_server: "empty.server.string"
      dns64_server: "server.name"
      dns64_contact: "dak.keepit.com"
      directory: "{{ bind9_cachedir }}"
      key_directory: "{{ bind9_cachedir }}/keys"
      statistics_file: "{{ bind9_cachedir }}/named.stats"
      rrset_order:
        - type: A
          name: foo.isc.org
          order: random
        - type: AAAA
          name: foo.isc.org
          order: cyclic
        - name: bar.isc.org
          order: random
        - name: "*.bar.isc.org"
          order: random
        - name: "*.baz.isc.org"
          order: cyclic
      response_policy:
        zones:
          - zone: smorg.bop
            max_policy_ttl: 30S
            min_update_interval: 30S
            policy: disabled
            add_soa: true
            log: true
            recursive_only: false
            nsip_enable: true
            nsdname_enable: true
        max_policy_ttl: 30S
        min_update_interval: 30S
        min_ns_dots: 2
        add_soa: false
        break_dnssec: false
        nsip_wait_recurse: true
        nsdname_wait_recurse: true
        qname_wait_recurse: true
        recursive_only: true
        nsip_enable: true
        nsdname_enable: true
        dnsrps_enable: false
        dnsrps_options:
          - simple
          - item
          - list
      response_padding:
        block_size: 4096
        addresses:
          - 0/0
      rate_limit:
        all_per_second: 0
        errors_per_second: 0
        responses_per_second: 0
        referrals_per_second: 0
        nodata_per_second: 0
        nxdomains_per_second: 0
        ipv4_prefix_length: 24
        ipv6_prefix_length: 54
        max_table_size: 20000
        min_table_size: 500
        qps_scale: 250
        slip: 2
        window: 15
        log_only: true
        exempt_clients:
          - 192.168.0.1
          - 10.20.30.40
      query_source_v6:
        address: "*"
        port: "*"
        dscp: 42
      parental_source_v6:
        address: "*"
        port: "*"
        dscp: 42
      notify_source_v6:
        address: "*"
      notify_source:
        address: "*"
      listen_on:
        - port: 53
          addresses:
            - 0.0.0.0
        - port: 5353
          dscp: 42
          addresses:
            - 0.0.0.0
            - 127.0.0.1
      listen_on_v6:
        - port: 5353
          dscp: 42
          addresses:
            - "::"
            - "de:ad::be:ef"
      dialup: false
      minimal_responses: true
      zone_statistics: full
      ixfr_from_differences: master
      dual_stack_servers:
        port: 4492
        addresses:
          - address: hostname.com
            port: 4421
            dscp: 42
          - address: 10.128.128.182
          - address: de:ad::be:ef
      dnstap:
        - type: auth
        - type: client
          log: response
        - type: resolver
          log: query
      dnstap_output:
        output_type: file
        output_file: /tmp/dnstap
        size: 10M
        versions: 200
        suffix: increment
  - name: named.conf.local
    acl:
      localstuff:
        - 10.0.0.0/8
        - 192.168.0.0/16
        - 172.16.0.0/12
      external:
        - 185.181.220.77
        - "!0.0.0.0/0"
    controls:
      - type: inet
        address: 127.0.0.1
        port: 533
        allow:
          - 127.0.0.0/8
          - "!127.13.37.1"
        readonly: false
      - type: inet
        address: 10.20.30.40
        allow:
          - 100.0.0.0/8
    view:
      - name: recursive-view
        match_clients:
          - localstuff
        match_destinations:
          - remote
        match-recursive-only: true
        options:
          transfer_source:
            address: 0.0.0.0
            port: '*'
            dscp: 42
          allow_recursion:
            - localstuff
        zones:
          - name: google.com
            type: forward
            forward: only
            forwarders:
              - 1.1.1.1
              - 1.0.0.1
    dnssec_policy:
      - name: mypolicy
        keylist:
          - role: ksk
            key_directory: true
            lifetime: unlimited
            algorithm: rsasha256
            keysize: 2048
          - role: zsk
            lifetime: P30D
            algorithm: 8
          - role: csk
            lifetime: P6MT12H3M15S
            algorithm: ecdsa256
        max_zone_ttl: P4D
        parent_ds_ttl: P14D
        nsec3param:
          iterations: '0'
          optout: false
          salt_length: '0'
    dyndb:
      - name: sample
        driver: example.so
        parameters:
          - example.nil. arpa.
          - example2.nil. arpa.
    http:
      - name: dohconf
        endpoints:
          - /dns-query
          - /dns
          - /query
        listener_clients: 4
        streams_per_connection: 1024
    keylist:
      - name: certbot.
        algorithm: hmac-sha512
        secret: "agyMWst4ZcbhGKqGuR6Pjgz1KJSHdcM0s5tz06n+ZxpfZYVWP67E2cr7Mru+HQRLl7HEBE5Zl4vS3S+SA4kXrA=="
      - name: certbot2.
        algorithm: hmac-sha512
        secret: "agyMWst4ZcbhGKqGuR6Pjgz1KJSHdcM0s5tz06n+ZxpfZYVWP67E2cr7Mru+HQRLl7HEBE5Zl4vS3S+SA4kXrA=="
    logging:
      categories:
        - name: default
          channels:
            - default_syslog
            - default_debug
            - tv2
            - dr1
        - name: unmatched
          channels:
            - tv3
      channels:
        - name: tv2
          buffered: true
          file:
            name: /var/log/named.log
            versions: 7
            size: 20m
            suffix: increment
          print_category: false
          print_severity: false
          print_time: iso8601-utc
          severity: info
        - name: tv3
          'null': true
        - name: dr1
          syslog: daemon
        - name: kanalkobenhavn
          stderr: true
          severity: debug 3
    parental_agents:
      - name: parents
        port: 53353
        dscp: 42
        addresses:
          - address: 10.20.30.40
            port: 53
            key: certbot.
          - address: 20.30.40.50
            port: 53
          - address: 30.40.50.60
            key: certbot2.
          - address: 40.50.60.70
      - name: notparents
        addresses:
          - address: 10.20.30.40
          - address: 30.40.50.60
          - address: 40.50.60.70
    primaries:
      - name: parents
        port: 53353
        dscp: 42
        addresses:
          - address: 10.20.30.40
            port: 53
            key: certbot.
          - address: 20.30.40.50
            port: 53
          - address: 30.40.50.60
            key: certbot2.
          - address: 40.50.60.70
      - name: notparents
        addresses:
          - address: 10.20.30.40
          - address: 30.40.50.60
          - address: 40.50.60.70
    tls:
      - name: certbot
        cert_file: /etc/ssl/private/snakeoil.pem
        key_file: /etc/ssl/private/snakeoil.key
        dhparam_file: /etc/ssl/dhparam.pem
        ca_file: /etc/ssl/certs/ca-certificates.crt
        remote_hostname: yourhostname
        ciphers: HIGH:!aNULL:!MD5:!SHA1:!SHA256:!SHA384
        protocols:
          - TLSv1.2
          - TLSv1.3
        prefer_server_ciphers: true
        session_tickets: true
    trust_anchors:
      - name: .
        type: initial-key
        flags: 257
        protocol: 3
        algorithm: 8
        key: "AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU="
      - name: hugs.dk
        type: static-ds
        flags: 64335
        protocol: 7
        algorithm: 2
        key: "D6AAECB1BA13D51F072A229C957ACADEA18118FB17DA2DC7D45A963428091372"
    server:
      - prefix: 1.1.1.1
        bogus: false
        edns: true
        tcp_only: false
        tcp_keepalive: false
        edns_version: '0'
        padding: '0'
        transfers: '0'
        keyname: certbot.
        query_source:
          address: "*"
          port: "*"
    statistics_channels:
      - address: 0.0.0.0
        port: 8080
        allow:
          - 0/0
  - name: named.conf.zones
    backup: false
    zones:
      - name: "_acme-challenge.hugs.dk"
        type: master
        file: master/_acme-challenge.hugs.dk.zone
        allow_query:
          - any
        dnssec_policy: default
        inline_signing: true
        serial_update_method: date
        update_policy:
          - permission: grant
            identity: certbot.
            ruletype: name
            name: _acme-challenge.hugs.dk
            types: txt
      - name: forward.net
        type: forward
        forwarders:
          port: 53
          addresses:
            - address: 1.1.1.1
              port: 53
              dscp: 42
            - address: 4.2.2.4
              port: 53
      - name: stub.com
        type: static-stub
        allow_query:
          - any
        server_addresses:
          - 1.1.1.1
          - 8.8.8.8
        zone_statistics: full
      - name: example.com
        type: slave
        allow_query:
          - 127.0.0.1
          - 10.0.0.1
          - 128.15.14.13
        allow_query_on:
          - 127.0.0.1
        primaries:
          port: 5522
          dscp: 42
          addresses:
            - address: 127.0.0.1
              port: 55222
            - address: 10.20.30.40
      - name: smorg.bop
        type: slave
        primaries:
          addresses:
            - address: 127.0.0.1
        allow_query:
          - 15.14.13.12
          - 10.20.30.40
          - 28.25.23.24
          - "!10.13.14.15"
        forwarders:
          port: 53
          dscp: 42
          addresses:
            - address: 127.0.0.1
              port: 53
              dscp: 42
            - address: 10.20.30.40
              port: 53
            - address: 20.30.40.50
            - address: 30.40.50.60
              port: 53
        allow_transfer:
          port: 5522
          transport: tls
          addresses:
            - 192.168.122.1
        also_notify:
          port: 5523
          dscp: 42
          addresses:
            - address: 127.0.0.1
              port: 5523
            - address: 127.0.0.2
        auto-dnssec: allow
        dnskey_sig_validity: 0
        dnssec-dnskey-kskonly: true
        dnssec_loadkeys_interval: 0
        file: "string"
        forward: first
        inline_signing: true
        ixfr_from_differences: true
        masterfile_format: raw
        masterfile_style: full
        max_ixfr_ratio: unlimited
        max_journal_size: default
        max_records: 0
        max_transfer_idle_out: 0
        max_transfer_time_out: 0
        notify: true
        notify_delay: '0'
        notify_to_soa: false
        parental_agents:
          port: 44332
          dscp: 42
          addresses:
            - address: 127.0.0.1
              port: 53
        sig_signing_nodes: '0'
        sig_signing_signatures: '0'
        sig_signing_type: 65281
        zero_no_soa_ttl: true
        zone_statistics: full
Description
Ansible role to install and configure bind9 on Debian systems
Readme 190 KiB
Languages
Jinja 100%