From 536df4f7ddbcc9194d0c099c0990dcabee53ac07 Mon Sep 17 00:00:00 2001 From: nd Date: Sat, 7 Oct 2017 02:51:39 +0200 Subject: [PATCH] initial commit --- handlers/main.yml | 39 +++ tasks/main.yml | 41 +++ templates/bindbackend.conf.j2 | 28 ++ templates/pdns.conf.j2 | 519 ++++++++++++++++++++++++++++++++++ templates/zonefile.db.j2 | 26 ++ 5 files changed, 653 insertions(+) create mode 100644 handlers/main.yml create mode 100644 tasks/main.yml create mode 100644 templates/bindbackend.conf.j2 create mode 100644 templates/pdns.conf.j2 create mode 100644 templates/zonefile.db.j2 diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..681015c --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,39 @@ +- name: copy zone + copy: + src: "/etc/powerdns/tpl/{{ item.item }}" + dest: "/etc/powerdns/zones/db.{{ item.item }}" + remote_src: yes + with_items: "{{ zonefilestask.results }}" + loop_control: + label: "{{ item.item }}" + when: item.changed + +- name: set zone serial + replace: + regexp: "##sequence##" + replace: "{{ ansible_date_time.epoch }}" + dest: "/etc/powerdns/zones/db.{{ item.item }}" + with_items: "{{ zonefilestask.results }}" + loop_control: + label: "{{ item.item }}" + when: item.changed + +- name: restart powerdns + service: name=pdns state=restarted + register: powerdns_restarted + +- name: reload changed zones + command: "pdns_control bind-reload-now {{ zonefilestask.results|selectattr('changed')|join(' ', attribute='item') }}" + when: not powerdns_restarted | default(False) + +- name: purge cache + command: "pdns_control purge" + when: not powerdns_restarted | default(False) + +- name: notify slaves + command: "pdns_control notify {{ item.item }}" + with_items: "{{ zonefilestask.results }}" + loop_control: + label: "{{ item.item }}" + when: item.changed + diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..3eb43e4 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: install powerdns + apt: pkg="pdns-server" + +- name: copy powerdns config + template: + src: pdns.conf.j2 + dest: /etc/powerdns/pdns.conf + notify: + - restart powerdns + +- name: copy powerdns backend config + template: + src: bindbackend.conf.j2 + dest: /etc/powerdns/bindbackend.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 + template: + src: zonefile.db.j2 + dest: "/etc/powerdns/tpl/{{ item }}" + with_items: "{{ dnsserver.zones.keys() }}" + register: zonefilestask + notify: + - copy zone + - set zone serial + - reload changed zones + - purge cache + - notify slaves diff --git a/templates/bindbackend.conf.j2 b/templates/bindbackend.conf.j2 new file mode 100644 index 0000000..7b667ca --- /dev/null +++ b/templates/bindbackend.conf.j2 @@ -0,0 +1,28 @@ +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 new file mode 100644 index 0000000..3d4e9f9 --- /dev/null +++ b/templates/pdns.conf.j2 @@ -0,0 +1,519 @@ +################################# +# 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 + + diff --git a/templates/zonefile.db.j2 b/templates/zonefile.db.j2 new file mode 100644 index 0000000..8966d2d --- /dev/null +++ b/templates/zonefile.db.j2 @@ -0,0 +1,26 @@ +$ORIGIN {{ item }}. +$TTL 60 +@ SOA {{ dnsserver.zones[item].SOA }} +{% macro generate_records(records, scope='@') %} +{% for k, v in records.items() %} +{% if v is string %} +{% if k != 'SOA' %} +{{ scope }} {{ k }} {{ v }} +{% endif %} +{% elif v is not mapping %} +{% for v2 in v %} +{{ scope }} {{ k }} {{ v2 }} +{% endfor %} +{% endif %} +{% endfor %} +{% for k, v in records.items() %} +{% if v is mapping %} +{% if not k.endswith('.') %} +{{ generate_records(v, k + ('.' + scope if scope != '@' else '')) }} +{%- elif k.endswith('.' + item + '.') or k == (item + '.') %} +{{ generate_records(v, k) }} +{%- endif %} +{%- endif %} +{% endfor %} +{% endmacro %} +{{ generate_records(dnsserver.zones[item]) }}