diff --git a/bind/config.sls b/bind/config.sls index 3f9cb5e..fd15f33 100644 --- a/bind/config.sls +++ b/bind/config.sls @@ -20,6 +20,7 @@ bind_restart: {{ map.log_dir }}/query.log: file.managed: + - replace: False - user: {{ salt['pillar.get']('bind:config:user', map.user) }} - group: {{ salt['pillar.get']('bind:config:group', map.group) }} - mode: {{ salt['pillar.get']('bind:config:log_mode', map.log_mode) }} @@ -132,7 +133,7 @@ bind_default_zones: {% endif %} {% for zone, zone_data in salt['pillar.get']('bind:configured_zones', {}).items() -%} -{%- set file = salt['pillar.get']("bind:available_zones:" + zone + ":file") %} +{%- set file = salt['pillar.get']("bind:available_zones:" + zone + ":file", zone_data.get('file')) %} {% if file and zone_data['type'] == "master" -%} zones-{{ zone }}: file.managed: @@ -161,7 +162,7 @@ signed-{{ zone }}: {%- for view, view_data in salt['pillar.get']('bind:configured_views', {}).items() %} {% for zone, zone_data in view_data.get('configured_zones', {}).items() -%} -{%- set file = salt['pillar.get']("bind:available_zones:" + zone + ":file") %} +{%- set file = salt['pillar.get']("bind:available_zones:" + zone + ":file", zone_data.get('file')) %} {% if file and zone_data['type'] == "master" -%} zones-{{ view }}-{{ zone }}: file.managed: diff --git a/bind/files/redhat/named.conf b/bind/files/redhat/named.conf index 946f91f..11a10da 100644 --- a/bind/files/redhat/named.conf +++ b/bind/files/redhat/named.conf @@ -8,19 +8,23 @@ // options { - //listen-on port 53 { 127.0.0.1; }; - listen-on port 53 { any; }; - listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; - allow-query { any; }; - recursion yes; - dnssec-enable yes; - dnssec-validation yes; - dnssec-lookaside auto; +{#- Allow inclusion of arbitrary statements #} +{%- for statement, value in salt['pillar.get']('bind:config:options', map.get('options', {})).items() -%} + {%- if value is iterable and value is not string %} + {{ statement }} { + {%- for item in value %} + {{ item }}; + {%- endfor %} + }; + {%- else %} + {{ statement }} {{ value }}; + {%- endif %} +{%- endfor %} /* Path to ISC DLV key */ bindkeys-file "/etc/named.iscdlv.key"; @@ -33,6 +37,39 @@ logging { file "data/named.run"; severity dynamic; }; + +{%- for channel, value in salt['pillar.get']('bind:config:logging:channels', {}).items() -%} + {%- if value is iterable %} + channel {{ channel }} { + {%- for statement, item in value.items() %} + {{ statement }} {{ item }}; + {%- endfor %} + }; + {%- endif %} +{%- endfor %} + +{%- for statement, value in salt['pillar.get']('bind:config:logging:category', {}).items() %} + category {{ statement }} { + {%- for item in value %} + {{ item }}; + {%- endfor %} + }; +{%- endfor %} + +{%- for statement, value in salt['pillar.get']('bind:config:logging', {}).items() -%} + {%- if statement not in ( 'channels', 'category' ) %} + {%- if value is iterable and value is not string %} + {{ statement }} { + {%- for item in value %} + {{ item }}; + {%- endfor %} + }; + {%- else %} + {{ statement }} {{ value }}; + {%- endif %} + {%- endif %} +{%- endfor %} + }; zone "." IN { diff --git a/bind/files/redhat/named.conf.local b/bind/files/redhat/named.conf.local index f4a7128..fc5907a 100644 --- a/bind/files/redhat/named.conf.local +++ b/bind/files/redhat/named.conf.local @@ -6,35 +6,77 @@ // organization //include "/etc/bind/zones.rfc1918"; -{% for key,args in salt['pillar.get']('bind:configured_zones', {}).items() -%} -{%- set file = salt['pillar.get']("bind:available_zones:" + key + ":file") %} -{%- set masters = salt['pillar.get']("bind:available_zones:" + key + ":masters") %} -zone "{{ key }}" { - type {{ args['type'] }}; +{%- macro zone(key, args, file, masters) %} +zone "{{ key }}" IN { + type {{ args['type'] }}; {% if args['type'] == 'forward' -%} {% if args['forward'] is defined -%} - forward {{ args['forward'] }}; + forward {{ args['forward'] }}; {%- endif %} - forwarders { + forwarders { {% for forwarder in args.forwarders -%} - {{ forwarder }}; + {{ forwarder }}; {%- endfor %} }; {% else -%} - file "data/{{ file }}"; - {%- if args['also-notify'] is defined %} - also-notify { {{ args.get('also-notify', []) | join('; ') }}; }; - {%- endif %} - {% if args['type'] == "master" -%} - {% if args['notify'] -%} - notify yes; - {% else -%} - notify no; - {%- endif -%} + {% if args['dnssec'] is defined and args['dnssec'] -%} + file "{{ file }}.signed"; {% else -%} - notify no; - masters { {{ masters }} }; + file "{{ file }}"; + {%- endif %} + {%- if args['allow-update'] is defined %} + allow-update { {{args['allow-update']}}; }; + {%- endif %} + {%- if args.update_policy is defined %} + update-policy { + {%- for policy in args.update_policy %} + {{ policy }}; + {%- endfor %} + }; + {%- endif %} + {%- if args['allow-transfer'] is defined %} + allow-transfer { {{ args.get('allow-transfer', []) | join('; ') }}; }; + {%- endif %} + {%- if args['also-notify'] is defined %} + also-notify { {{ args.get('also-notify', []) | join('; ') }}; }; + {%- endif %} + {%- if args['type'] == 'slave' %} + {%- if args['allow-notify'] is defined %} + allow-notify { {{ args.get('allow-notify', []) | join('; ') }}; }; + {%- endif %} + {%- endif %} + {%- if args['type'] == "master" -%} + {% if args['notify'] %} + notify yes; + {% else %} + notify no; + {%- endif -%} + {% else %} + notify no; + {%- if masters is iterable and masters is not string %} + masters { + {%- for item in masters %} + {{ item }}; + {%- endfor %} + }; + {%- else %} + masters { {{ masters }} }; + {%- endif %} {%- endif %} {%- endif %} }; +{%- endmacro %} + +{% for key, args in salt['pillar.get']('bind:configured_zones', {}).items() -%} +{%- set file = args.get('file', salt['pillar.get']("bind:available_zones:" + key + ":file")) %} +{%- set masters = args.get('masters', salt['pillar.get']("bind:available_zones:" + key + ":masters")) %} +{{ zone(key, args, file, masters) }} {% endfor %} + +{%- for name, data in salt['pillar.get']('bind:configured_acls', {}).items() %} +acl {{ name }} { + {%- for d in data %} + {{ d }}; + {%- endfor %} +}; +{%- endfor %} diff --git a/bind/map.jinja b/bind/map.jinja index e3e6b1b..6178a17 100644 --- a/bind/map.jinja +++ b/bind/map.jinja @@ -25,12 +25,20 @@ 'config': '/etc/named.conf', 'local_config': '/etc/named.conf.local', 'default_config': '/etc/sysconfig/named', - 'named_directory': '/var/named/data', + 'named_directory': '/var/named', 'log_dir': '/var/log/named', 'log_mode': '640', 'user': 'root', 'group': 'named', - 'mode': '640' + 'mode': '640', + 'options': { + 'listen-on': 'port 53 { 127.0.0.1; }', + 'listen-on-v6': 'port 53 { ::1; }', + 'allow-query': '{ localhost; }', + 'recursion': 'yes', + 'dnssec-enable': 'yes', + 'dnssec-validation': 'yes' + } }, 'Arch': { 'pkgs': ['bind', 'bind-tools', 'dnssec-tools'], diff --git a/pillar.example b/pillar.example index f11b3dc..486230b 100644 --- a/pillar.example +++ b/pillar.example @@ -24,6 +24,14 @@ bind: mode: 640 # File & Directory mode options: allow-recursion: '{ any; }' # Never include this on a public resolver +# RedHat defaults, needed to generate default config file + listen-on: 'port 53 { 127.0.0.1; }' + listen-on-v6: 'port 53 { ::1; }' + allow-query: '{ localhost; }' + recursion: 'yes' + dnssec-enable: 'yes' + dnssec-validation: 'yes' +# End RedHat defaults protocol: 4 # Force bind to serve only one IP protocol # (ipv4: 4, ipv6: 6). Omitting this reverts to @@ -38,6 +46,7 @@ bind: # End Debian based systems + ### Keys, Zones, ACLs and Views ### bind: keys: