diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..136ead6 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,23 @@ +powerdns: + config: + "allow-axfr-ips": + - ::1 + - 127.0.0.0/8 + "bind-config": /etc/powerdns/backends/bind.conf + "config-dir": /etc/powerdns + "daemon": "yes" + "default-ttl": 3600 + "guardian": "yes" + "include-dir": "/etc/powerdns/pdns.d" + "launch": + - bind + "master": no + "reuseport": "yes" + "setgid": pdns + "setuid": pdns + "slave": no + "soa-minimum-ttl": 300 + "tcp-control-secret": "{{ lookup('password', '/dev/null length=64') }}" + "version-string": "1" + zonemeta: {} + zones: {} diff --git a/handlers/main.yml b/handlers/main.yml index 681015c..2a3ea27 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,18 +1,18 @@ -- name: copy zone +- name: copy bind zone file copy: - src: "/etc/powerdns/tpl/{{ item.item }}" - dest: "/etc/powerdns/zones/db.{{ item.item }}" + src: "/var/lib/powerdns/tpl/{{ item.item }}" + dest: "/var/lib/powerdns/zones/db.{{ item.item }}" remote_src: yes with_items: "{{ zonefilestask.results }}" loop_control: label: "{{ item.item }}" when: item.changed -- name: set zone serial +- name: set bind zone serial replace: regexp: "##sequence##" replace: "{{ ansible_date_time.epoch }}" - dest: "/etc/powerdns/zones/db.{{ item.item }}" + dest: "/var/lib/powerdns/zones/db.{{ item.item }}" with_items: "{{ zonefilestask.results }}" loop_control: label: "{{ item.item }}" @@ -22,7 +22,7 @@ service: name=pdns state=restarted register: powerdns_restarted -- name: reload changed zones +- name: reload changed bind zones command: "pdns_control bind-reload-now {{ zonefilestask.results|selectattr('changed')|join(' ', attribute='item') }}" when: not powerdns_restarted | default(False) @@ -35,5 +35,7 @@ with_items: "{{ zonefilestask.results }}" loop_control: label: "{{ item.item }}" - when: item.changed + when: + - item.changed + - powerdns.config.master == "yes" diff --git a/tasks/main.yml b/tasks/main.yml index 15bcdba..39fb0be 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -5,6 +5,11 @@ - pdns-server - pdns-backend-bind +- name: delete debian defaults + file: + path: /etc/powerdns/named.conf + state: absent + - name: copy powerdns config template: src: pdns.conf.j2 @@ -12,33 +17,35 @@ notify: - restart powerdns -- name: copy powerdns backend config +- name: create folders + file: + path: "{{ item.path }}" + state: directory + owner: "{{ item.owner|d('pdns') }}" + group: "{{ item.group|d('pdns') }}" + mode: "{{ item.mode|d('0755') }}" + with_items: + - { "path": "/var/lib/powerdns/tpl/" } + - { "path": "/var/lib/powerdns/zones/" } + - { "path": "/etc/powerdns/pdns.d/" } + - { "path": "/etc/powerdns/backends/" } + +- name: copy powerdns bind backend config template: - src: bindbackend.conf.j2 - dest: /etc/powerdns/bindbackend.conf + src: backend-bind.conf.j2 + dest: /etc/powerdns/backends/bind.conf notify: - restart powerdns -- name: create folders - file: - path: "{{item}}" - state: directory - owner: pdns - group: pdns - mode: 0755 - with_items: - - "/etc/powerdns/tpl/" - - "/etc/powerdns/zones/" - -- name: create zonefile template +- name: create bind zonefile templates template: src: zonefile.db.j2 - dest: "/etc/powerdns/tpl/{{ item }}" - with_items: "{{ dnsserver.zones.keys()|list }}" + dest: "/var/lib/powerdns/tpl/{{ item }}" + with_items: "{{ powerdns.zones.keys()|list }}" register: zonefilestask notify: - - copy zone - - set zone serial - - reload changed zones + - copy bind zone file + - set bind zone serial + - reload changed bind zones - purge cache - notify slaves diff --git a/templates/backend-bind.conf.j2 b/templates/backend-bind.conf.j2 new file mode 100644 index 0000000..d633820 --- /dev/null +++ b/templates/backend-bind.conf.j2 @@ -0,0 +1,28 @@ +options { + directory "/var/lib/powerdns/zones/"; +}; + +{% for z in powerdns.zonemeta %} +zone "{{ z }}" IN { + type {{ powerdns.zonemeta[z].type }}; + file "/var/lib/powerdns/zones/db.{{z}}"; +{%if 'masters' in powerdns.zonemeta[z] %} + masters { + {{ powerdns.zonemeta[z]['masters']|join('; ') }}; + }; +{% endif %} + allow-query { + {{ powerdns.zonemeta[z]['allow-query']|default(['any'])|join('; ') }}; + }; + allow-update { + {{ powerdns.zonemeta[z]['allow-update']|default(['none'])|join('; ') }}; + }; + allow-transfer { + {{ powerdns.zonemeta[z]['allow-transfer']|default(['none'])|join('; ') }}; + }; +{%if 'notify' in powerdns.zonemeta[z] %} + notify {{ "yes" if powerdns.zonemeta[z].notify else "no" }}; +{% endif %} +}; + +{% endfor %} diff --git a/templates/bindbackend.conf.j2 b/templates/bindbackend.conf.j2 deleted file mode 100644 index 7b667ca..0000000 --- a/templates/bindbackend.conf.j2 +++ /dev/null @@ -1,28 +0,0 @@ -options { - directory "/etc/powerdns/zones/"; -}; - -{% for z in dnsserver.zonemeta %} -zone "{{ z }}" IN { - type {{ dnsserver.zonemeta[z].type }}; - file "/etc/powerdns/zones/db.{{z}}"; -{%if 'masters' in dnsserver.zonemeta[z] %} - masters { - {{ dnsserver.zonemeta[z]['masters']|join('; ') }}; - }; -{% endif %} - allow-query { - {{ dnsserver.zonemeta[z]['allow-query']|default(['any'])|join('; ') }}; - }; - allow-update { - {{ dnsserver.zonemeta[z]['allow-update']|default(['none'])|join('; ') }}; - }; - allow-transfer { - {{ dnsserver.zonemeta[z]['allow-transfer']|default(['none'])|join('; ') }}; - }; -{%if 'notify' in dnsserver.zonemeta[z] %} - notify {{ "yes" if dnsserver.zonemeta[z].notify else "no" }}; -{% endif %} -}; - -{% endfor %} diff --git a/templates/pdns.conf.j2 b/templates/pdns.conf.j2 index 3d4e9f9..4af1ba8 100644 --- a/templates/pdns.conf.j2 +++ b/templates/pdns.conf.j2 @@ -1,519 +1,6 @@ -################################# -# allow-axfr-ips Allow zonetransfers only to these subnets -# -allow-axfr-ips= {{ dnsserver['axfr-ips']|join(', ' ) }} - -################################# -# allow-dnsupdate-from A global setting to allow DNS updates from these IP ranges. -# -# allow-dnsupdate-from=127.0.0.0/8,::1 - -################################# -# allow-recursion List of subnets that are allowed to recurse -# -# allow-recursion=127.0.0.0/8, ::1/128, fe80::/10 - -################################# -# also-notify When notifying a domain, also notify these nameservers -# -# also-notify= - -################################# -# any-to-tcp Answer ANY queries with tc=1, shunting to TCP -# -# any-to-tcp=no - -################################# -# cache-ttl Seconds to store packets in the PacketCache -# -# cache-ttl=20 - -################################# -# carbon-interval Number of seconds between carbon (graphite) updates -# -# carbon-interval=30 - -################################# -# carbon-ourname If set, overrides our reported hostname for carbon stats -# -# carbon-ourname= - -################################# -# carbon-server If set, send metrics in carbon (graphite) format to this server -# -# carbon-server= - -################################# -# chroot If set, chroot to this directory for more security -# -# chroot= - -################################# -# config-dir Location of configuration directory (pdns.conf) -# -config-dir=/etc/powerdns - -################################# -# config-name Name of this virtual configuration - will rename the binary image -# -# config-name= - -################################# -# control-console Debugging switch - don't use -# -# control-console=no - -################################# -# daemon Operate as a daemon -# -daemon=yes - -################################# -# default-ksk-algorithms Default KSK algorithms -# -# default-ksk-algorithms=rsasha256 - -################################# -# default-ksk-size Default KSK size (0 means default) -# -# default-ksk-size=0 - -################################# -# default-soa-mail mail address to insert in the SOA record if none set in the backend -# -# default-soa-mail= - -################################# -# default-soa-name name to insert in the SOA record if none set in the backend -# -# default-soa-name=a.misconfigured.powerdns.server - -################################# -# default-ttl Seconds a result is valid if not set otherwise -# -# default-ttl=3600 - -################################# -# default-zsk-algorithms Default ZSK algorithms -# -# default-zsk-algorithms=rsasha256 - -################################# -# default-zsk-size Default ZSK size (0 means default) -# -# default-zsk-size=0 - -################################# -# direct-dnskey Fetch DNSKEY RRs from backend during DNSKEY synthesis -# -# direct-dnskey=no - -################################# -# disable-axfr Disable zonetransfers but do allow TCP queries -# -# disable-axfr=no - -################################# -# disable-axfr-rectify Disable the rectify step during an outgoing AXFR. Only required for regression testing. -# -# disable-axfr-rectify=no - -################################# -# disable-tcp Do not listen to TCP queries -# -# disable-tcp=no - -################################# -# distributor-threads Default number of Distributor (backend) threads to start -# -# distributor-threads=3 - -################################# -# do-ipv6-additional-processing Do AAAA additional processing -# -# do-ipv6-additional-processing=yes - -################################# -# edns-subnet-processing If we should act on EDNS Subnet options -# -# edns-subnet-processing=no - -################################# -# entropy-source If set, read entropy from this file -# -# entropy-source=/dev/urandom - -################################# -# experimental-api-key REST API Static authentication key (required for API use) -# -# experimental-api-key= - -################################# -# experimental-api-readonly If the JSON API should disallow data modification -# -# experimental-api-readonly=no - -################################# -# experimental-dname-processing If we should support DNAME records -# -# experimental-dname-processing=no - -################################# -# experimental-dnsupdate Enable/Disable DNS update (RFC2136) support. Default is no. -# -# experimental-dnsupdate=no - -################################# -# experimental-json-interface If the webserver should serve JSON data -# -# experimental-json-interface=no - -################################# -# experimental-logfile Filename of the log file for JSON parser -# -# experimental-logfile=/var/log/pdns.log - -################################# -# forward-dnsupdate A global setting to allow DNS update packages that are for a Slave domain, to be forwarded to the master. -# -# forward-dnsupdate=yes - -################################# -# guardian Run within a guardian process -# -guardian=yes - -################################# -# include-dir Include *.conf files from this directory -# -# include-dir= -#include-dir=/etc/powerdns/pdns.d - -################################# -# launch Which backends to launch and order to query them in -# -# launch= -launch=bind -bind-config=/etc/powerdns/bindbackend.conf - -################################# -# load-modules Load this module - supply absolute or relative path -# -# load-modules= - -################################# -# local-address Local IP addresses to which we bind -# -# local-address=0.0.0.0 - -################################# -# local-address-nonexist-fail Fail to start if one or more of the local-address's do not exist on this server -# -# local-address-nonexist-fail=yes - -################################# -# local-ipv6 Local IP address to which we bind -# -# local-ipv6= - -################################# -# local-ipv6-nonexist-fail Fail to start if one or more of the local-ipv6 addresses do not exist on this server -# -# local-ipv6-nonexist-fail=yes - -################################# -# local-port The port on which we listen -# -# local-port=53 - -################################# -# log-dns-details If PDNS should log DNS non-erroneous details -# -# log-dns-details=no - -################################# -# log-dns-queries If PDNS should log all incoming DNS queries -# -# log-dns-queries=no - -################################# -# logging-facility Log under a specific facility -# -# logging-facility= - -################################# -# loglevel Amount of logging. Higher is more. Do not set below 3 -# -# loglevel=4 - -################################# -# lua-prequery-script Lua script with prequery handler -# -# lua-prequery-script= - -################################# -# master Act as a master -# -master={{dnsserver.master}} - -################################# -# max-cache-entries Maximum number of cache entries -# -# max-cache-entries=1000000 - -################################# -# max-ent-entries Maximum number of empty non-terminals in a zone -# -# max-ent-entries=100000 - -################################# -# max-nsec3-iterations Limit the number of NSEC3 hash iterations -# -# max-nsec3-iterations=500 - -################################# -# max-queue-length Maximum queuelength before considering situation lost -# -# max-queue-length=5000 - -################################# -# max-signature-cache-entries Maximum number of signatures cache entries -# -# max-signature-cache-entries= - -################################# -# max-tcp-connections Maximum number of TCP connections -# -# max-tcp-connections=10 - -################################# -# module-dir Default directory for modules -# -# module-dir=/usr/lib/TRIPLET/pdns - -################################# -# negquery-cache-ttl Seconds to store negative query results in the QueryCache -# -# negquery-cache-ttl=60 - -################################# -# no-shuffle Set this to prevent random shuffling of answers - for regression testing -# -# no-shuffle=off - -################################# -# only-notify Only send AXFR NOTIFY to these IP addresses or netmasks -# -# only-notify=0.0.0.0/0,::/0 - -################################# -# out-of-zone-additional-processing Do out of zone additional processing -# -# out-of-zone-additional-processing=yes - -################################# -# overload-queue-length Maximum queuelength moving to packetcache only -# -# overload-queue-length=0 - -################################# -# pipebackend-abi-version Version of the pipe backend ABI -# -# pipebackend-abi-version=1 - -################################# -# prevent-self-notification Don't send notifications to what we think is ourself -# -# prevent-self-notification=yes - -################################# -# query-cache-ttl Seconds to store query results in the QueryCache -# -# query-cache-ttl=20 - -################################# -# query-local-address Source IP address for sending queries -# -# query-local-address=0.0.0.0 - -################################# -# query-local-address6 Source IPv6 address for sending queries -# -# query-local-address6=:: - -################################# -# query-logging Hint backends that queries should be logged -# -# query-logging=no - -################################# -# queue-limit Maximum number of milliseconds to queue a query -# -# queue-limit=1500 - -################################# -# receiver-threads Default number of receiver threads to start -# -# receiver-threads=1 - -################################# -# recursive-cache-ttl Seconds to store packets for recursive queries in the PacketCache -# -# recursive-cache-ttl=10 - -################################# -# recursor If recursion is desired, IP address of a recursing nameserver -# -#recursor= - -################################# -# retrieval-threads Number of AXFR-retrieval threads for slave operation -# -# retrieval-threads=2 - -################################# -# reuseport Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket -# -reuseport=yes - -################################# -# security-poll-suffix Domain name from which to query security update notifications -# -# security-poll-suffix=secpoll.powerdns.com. - -################################# -# send-root-referral Send out old-fashioned root-referral instead of ServFail in case of no authority -# -# send-root-referral=no - -################################# -# server-id Returned when queried for 'server.id' TXT or NSID, defaults to hostname - disabled or custom -# -# server-id= - -################################# -# setgid If set, change group id to this gid for more security -# -setgid=pdns - -################################# -# setuid If set, change user id to this uid for more security -# -setuid=pdns - -################################# -# signing-threads Default number of signer threads to start -# -# signing-threads=3 - -################################# -# slave Act as a slave -# -slave={{dnsserver.slave}} - -################################# -# slave-cycle-interval Reschedule failed SOA serial checks once every .. seconds -# -# slave-cycle-interval=60 - -################################# -# slave-renotify If we should send out notifications for slaved updates -# -# slave-renotify=no - -################################# -# soa-expire-default Default SOA expire -# -# soa-expire-default=604800 - -################################# -# soa-minimum-ttl Default SOA minimum ttl -# -soa-minimum-ttl={{dnsserver['soa-minimum-ttl']}} - -################################# -# soa-refresh-default Default SOA refresh -# -# soa-refresh-default=10800 - -################################# -# soa-retry-default Default SOA retry -# -# soa-retry-default=3600 - -################################# -# socket-dir Where the controlsocket will live -# -# socket-dir=/var/run - -################################# -# tcp-control-address If set, PowerDNS can be controlled over TCP on this address -# -# tcp-control-address= - -################################# -# tcp-control-port If set, PowerDNS can be controlled over TCP on this address -# -# tcp-control-port=53000 - -################################# -# tcp-control-range If set, remote control of PowerDNS is possible over these networks only -# -# tcp-control-range=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10 - -################################# -# tcp-control-secret If set, PowerDNS can be controlled over TCP after passing this secret -# -tcp-control-secret={{dnsserver['tcp-control-secret']}} - -################################# -# traceback-handler Enable the traceback handler (Linux only) -# -# traceback-handler=yes - -################################# -# trusted-notification-proxy IP address of incoming notification proxy -# -# trusted-notification-proxy= - -################################# -# udp-truncation-threshold Maximum UDP response size before we truncate -# -# udp-truncation-threshold=1680 - -################################# -# version-string PowerDNS version in packets - full, anonymous, powerdns or custom -# -version-string={{dnsserver['version-string']}} - -################################# -# webserver Start a webserver for monitoring -# -# webserver=no - -################################# -# webserver-address IP Address of webserver to listen on -# -# webserver-address=127.0.0.1 - -################################# -# webserver-allow-from Webserver access is only allowed from these subnets -# -# webserver-allow-from=0.0.0.0/0,::/0 - -################################# -# webserver-password Password required for accessing the webserver -# -# webserver-password= - -################################# -# webserver-port Port of webserver to listen on -# -# webserver-port=8081 - -################################# -# webserver-print-arguments If the webserver should print arguments -# -# webserver-print-arguments=no +{% set array_values = ['allow-axfr-ips', 'launch'] %} +{% for option in powerdns.config.keys()|sort %} +{{ option }}={% if option in array_values %}{{ powerdns.config[option]|join(',' ) }}{% else %}{{ powerdns.config[option] }}{% endif %} +{% endfor %} diff --git a/templates/zonefile.db.j2 b/templates/zonefile.db.j2 index 7176efa..49523b1 100644 --- a/templates/zonefile.db.j2 +++ b/templates/zonefile.db.j2 @@ -1,6 +1,6 @@ $ORIGIN {{ item }}. $TTL 60 -@ SOA {{ dnsserver.zones[item].SOA }} +@ SOA {{ powerdns.zones[item].SOA }} {% macro generate_records(records, scope='@') %} {% for k, v in records.items() %} {% if v is string %} @@ -23,4 +23,4 @@ $TTL 60 {%- endif %} {% endfor %} {% endmacro %} -{{ generate_records(dnsserver.zones[item]) }} +{{ generate_records(powerdns.zones[item]) }}