Add playbook

This commit is contained in:
Dryusdan 2020-07-01 10:44:00 +02:00
parent f7334f7f43
commit 4cc745983c
10 changed files with 473 additions and 0 deletions

20
files/ds-records Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
DOMAIN="$1"
if [ -z "$DOMAIN" ]; then
echo "Domain name must be defined" 1>&2
exit 1
fi
echo -e "\n> DS record 1 [Digest Type = SHA1] :"
ldns-key2ds -n -1 "/etc/nsd/zones/${DOMAIN}.signed"
echo -e "\n> DS record 2 [Digest Type = SHA256] :"
ldns-key2ds -n -2 "/etc/nsd/zones/${DOMAIN}.signed"
echo -e "\n> Public KSK Key :"
tail -n 1 "/etc/nsd/zones/K${DOMAIN}.ksk.key"
echo ""
exit 0

27
files/keygen Normal file
View File

@ -0,0 +1,27 @@
#!/bin/sh
DOMAIN="$1"
if [ -z "$DOMAIN" ]; then
echo "Domain name must be defined" 1>&2
exit 1
fi
cd /etc/nsd/zones || exit 1
if [ ! -f "K${DOMAIN}.zsk.key" ]
then
echo "Generating ZSK & KSK keys for '${DOMAIN}'"
ZSK=$(ldns-keygen -a ECDSAP384SHA384 -b 384 "$DOMAIN")
KSK=$(ldns-keygen -k -a ECDSAP384SHA384 -b 384 "$DOMAIN")
rm -f "$ZSK".ds "$KSK".ds
mv "$ZSK".key "K${DOMAIN}.zsk.key"
mv "$ZSK".private "K${DOMAIN}.zsk.private"
mv "$KSK".key "K${DOMAIN}.ksk.key"
mv "$KSK".private "K${DOMAIN}.ksk.private"
chmod 600 -- *.private
exit 0
fi

22
files/signzone Normal file
View File

@ -0,0 +1,22 @@
#!/bin/sh
DOMAIN="$1"
EXPIRATION_DATE="$2"
if [ -z "$DOMAIN" ]; then
echo "Domain name must be defined" 1>&2
exit 1
fi
if [ -n "$EXPIRATION_DATE" ]; then
arg="-e${EXPIRATION_DATE}"
fi
cd /etc/nsd/zones || exit 1
echo "Signing zone for ${DOMAIN}"
ldns-signzone -n -p ${arg} -s "$(head /dev/urandom | tr -dc A-Za-z0-9 | sha1sum | head -c 30)" \
-f "${DOMAIN}.zone.signed" "${DOMAIN}.zone" "K${DOMAIN}.zsk" "K${DOMAIN}.ksk"
updatezone "$DOMAIN"
exit 0

20
files/updatezone Normal file
View File

@ -0,0 +1,20 @@
#!/bin/sh
DOMAIN="$1"
if [ -z "$DOMAIN" ]; then
echo "Domain name must be defined" 1>&2
exit 1
fi
echo -n "NSD configuration rebuild... "
nsd-control reconfig
echo -n "Reloading zone for ${DOMAIN}... "
nsd-control reload "$DOMAIN"
echo -n "Notify slave servers... "
nsd-control notify "$DOMAIN"
echo "Done."
exit 0

7
handlers/main.yml Normal file
View File

@ -0,0 +1,7 @@
---
# handlers file for ansible-role-nsd
- name: restart nsd
service: name=nsd state=restarted
- name: reload nsd
shell: nsd-control reconfig

21
meta/main.yml Normal file
View File

@ -0,0 +1,21 @@
---
galaxy_info:
author: elnappo <elnappo@nerdpol.io>
description: Install and configure nsd name server
license: MIT
min_ansible_version: 2.2
platforms:
- name: Ubuntu
versions:
- trusty
- xenial
- bionic
- name: Debian
versions:
- jessie
- stretch
galaxy_tags:
- networking
- dns
dependencies: []

63
tasks/configure.yml Normal file
View File

@ -0,0 +1,63 @@
---
- name: NSD already installed ?
shell: dpkg-query -W 'nsd'
ignore_errors: true
register: nsd
- name: update apt-cache
apt: update_cache=yes
when: nsd is failed
- name: Create zone folder
file:
path: /etc/nsd/zones
state: directory
- name: Install nsd
apt:
pkg: "{{item}}"
state: latest
update_cache: yes
with_items:
- nsd
- dnsutils
- ldnsutils
when: nsd is failed
- name: Create SSL keys and certificates
command: nsd-control-setup creates=/etc/nsd/nsd_control.pem
when: nsd_remote_control_enable == "yes"
notify:
- restart nsd
- name: Add file for DNSSEC
copy:
src: ds-records
dest: /usr/local/bin/ds-records
owner: root
group: root
mode: 0755
- name: Add file for DNSSEC
copy:
src: keygen
dest: /usr/local/bin/keygen
owner: root
group: root
mode: 0755
- name: Add file for DNSSEC
copy:
src: signzone
dest: /usr/local/bin/signzone
owner: root
group: root
mode: 0755
- name: Add file for DNSSEC
copy:
src: updatezone
dest: /usr/local/bin/updatezone
owner: root
group: root
mode: 0755

54
tasks/main.yml Normal file
View File

@ -0,0 +1,54 @@
---
- include_tasks: configure.yml
- name: "{{ role_path|basename }} | get unix time"
shell: echo $(date +%s)
register: unix_time_stamp
delegate_to: localhost
run_once: true
become: no
- name: Create config file
template:
src: nsd.conf.j2
dest: /etc/nsd/nsd.conf
owner: root
group: root
mode: 0644
validate: 'nsd-checkconf %s'
notify:
- reload nsd
- name: "{{ role_path|basename }} setting execution facts"
set_fact:
serial: "{{ unix_time_stamp.stdout }}"
run_once: true
become: no
- name: Add zone
template:
src: zone.j2
dest: "/etc/nsd/zones/{{ item.name }}.zone"
loop: "{{ dns_zones }}"
when: "dns_zones is defined"
- name: Enable NSD on boot and start it
service: name=nsd state=started enabled=yes
- name: Generate key for dnssec
shell: "/usr/local/bin/keygen {{ item.name }}"
loop: "{{ dns_zones }}"
when: "dns_zones is defined"
- name: Generate key for dnssec
shell: "/usr/local/bin/signzone {{ item.name }}"
loop: "{{ dns_zones }}"
when: "dns_zones is defined"
- name: Get ds-record
shell: "/usr/local//bin/ds-records {{ item.name }}"
loop: "{{ dns_zones }}"
when: "dns_zones is defined"
register: dsrecord

231
templates/nsd.conf.j2 Normal file
View File

@ -0,0 +1,231 @@
# This file is ansible managed
{% macro bool(value) %}
{{ 'yes' if value | bool else 'no' -}}
{% endmacro %}
#
# nsd.conf -- the NSD(8) configuration file, nsd.conf(5).
#
# Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
#
# See LICENSE for the license.
#
# This is a comment.
# Sample configuration file
# include: "file" # include that file's text over here.
# options for the nsd server
server:
# Number of NSD servers to fork. Put the number of CPUs to use here.
server-count: {{ nsd_server_count }}
# uncomment to specify specific interfaces to bind (default are the
# wildcard interfaces 0.0.0.0 and ::0).
# For servers with multiple IP addresses, list them one by one,
# or the source address of replies could be wrong.
# Use ip-transparent to be able to list addresses that turn on later.
{% for ip in nsd_ip_listen %}
ip-address: {{ ip }}
{% endfor %}
# ip-address: 1.2.3.4@5678
# ip-address: 12fe::8ef0
# Allow binding to non local addresses. Default no.
ip-transparent: {{ bool(nsd_ip_transparent) }}
# enable debug mode, does not fork daemon process into the background.
# debug-mode: no
# listen on IPv4 connections
do-ip4: {{ bool(nsd_do_ip4) }}
# listen on IPv6 connections
do-ip6: {{ bool(nsd_do_ip6) }}
# port to answer queries on. default is 53.
port: {{ nsd_port }}
# Verbosity level.
# verbosity: 0
# After binding socket, drop user privileges.
# can be a username, id or id.gid.
# username: nsd
# Run NSD in a chroot-jail.
# make sure to have pidfile and database reachable from there.
# by default, no chroot-jail is used.
# chroot: "/etc/nsd"
# The directory for zonefile: files. The daemon chdirs here.
# zonesdir: "/etc/nsd"
# the list of dynamically added zones.
# zonelistfile: "/var/lib/nsd/zone.list"
# the database to use
# if set to "" then no disk-database is used, less memory usage.
# database: "/var/lib/nsd/nsd.db"
# log messages to file. Default to stderr and syslog (with
# facility LOG_DAEMON). stderr disappears when daemon goes to bg.
# logfile: "/var/log/nsd.log"
# File to store pid for nsd in.
# pidfile: "/run/nsd/nsd.pid"
# The file where secondary zone refresh and expire timeouts are kept.
# If you delete this file, all secondary zones are forced to be
# 'refreshing' (as if nsd got a notify). Set to "" to disable.
# xfrdfile: "/var/lib/nsd/xfrd.state"
# The directory where zone transfers are stored, in a subdir of it.
# xfrdir: "/tmp"
# don't answer VERSION.BIND and VERSION.SERVER CHAOS class queries
hide-version: {{ bool(nsd_hide_version) }}
# version string the server responds with for chaos queries.
# default is 'NSD x.y.z' with the server's version number.
# version: "NSD"
# identify the server (CH TXT ID.SERVER entry).
identity: "{{ nsd_identity }}"
# NSID identity (hex string, or "ascii_somestring"). default disabled.
# nsid: "aabbccdd"
# Maximum number of concurrent TCP connections per server.
# tcp-count: 100
# Maximum number of queries served on a single TCP connection.
# By default 0, which means no maximum.
# tcp-query-count: 0
# Override the default (120 seconds) TCP timeout.
# tcp-timeout: 120
# Preferred EDNS buffer size for IPv4.
# ipv4-edns-size: 4096
# Preferred EDNS buffer size for IPv6.
# ipv6-edns-size: 4096
# statistics are produced every number of seconds. Prints to log.
# Default is 0, meaning no statistics are produced.
# statistics: 3600
# Number of seconds between reloads triggered by xfrd.
# xfrd-reload-timeout: 1
# log timestamp in ascii (y-m-d h:m:s.msec), yes is default.
# log-time-ascii: yes
# round robin rotation of records in the answer.
# round-robin: no
# check mtime of all zone files on start and sighup
# zonefiles-check: yes
# write changed zonefiles to disk, every N seconds.
# default is 0(disabled) or 3600(if database is "").
# zonefiles-write: 3600
# RRLconfig
# Response Rate Limiting, size of the hashtable. Default 1000000.
# rrl-size: 1000000
# Response Rate Limiting, maximum QPS allowed (from one query source).
# If set to 0, ratelimiting is disabled. Also set
# rrl-whitelist-ratelimit to 0 to disable ratelimit processing.
# Default is on.
# rrl-ratelimit: 200
# Response Rate Limiting, number of packets to discard before
# sending a SLIP response (a truncated one, allowing an honest
# resolver to retry with TCP). Default is 2 (one half of the
# queries will receive a SLIP response, 0 disables SLIP (all
# packets are discarded), 1 means every request will get a
# SLIP response. When the ratelimit is hit the traffic is
# divided by the rrl-slip value.
# rrl-slip: 2
# Response Rate Limiting, IPv4 prefix length. Addresses are
# grouped by netblock.
# rrl-ipv4-prefix-length: 24
# Response Rate Limiting, IPv6 prefix length. Addresses are
# grouped by netblock.
# rrl-ipv6-prefix-length: 64
# Response Rate Limiting, maximum QPS allowed (from one query source)
# for whitelisted types. Default is on.
# rrl-whitelist-ratelimit: 2000
# RRLend
# Remote control config section.
remote-control:
# Enable remote control with nsd-control(8) here.
# set up the keys and certificates with nsd-control-setup.
control-enable: {{ bool(nsd_remote_control_enable) }}
# what interfaces are listened to for control, default is on localhost.
{% for control_interface in nsd_remote_control_interfaces %}
control-interface: {{ control_interface }}
{% endfor %}
# port number for remote control operations (uses TLS over TCP).
control-port: {{ nsd_remote_control_port }}
# nsd server key file for remote control.
server-key-file: "/etc/nsd/nsd_server.key"
# nsd server certificate file for remote control.
server-cert-file: "/etc/nsd/nsd_server.pem"
# nsd-control key file.
control-key-file: "/etc/nsd/nsd_control.key"
# nsd-control certificate file.
control-cert-file: "/etc/nsd/nsd_control.pem"
{% for zone in zones %}
{% if zone.secret is defined %}
key:
name: "{{ zone.name }}-key"
algorithm: {{ zone.algorithm|default('hmac-sha256') }}
secret: "{{ zone.secret }}"
{% endif %}
{% endfor %}
{% for zone in zones %}
zone:
name: "{{ zone.name }}"
zonefile: "zones/{{ zone.name }}.zone.signed"
{% if zone.slaves is defined %}
{% for slave in zone.slaves %}
{% if zone.secret is defined %}
notify: {{ slave }} {{ zone.name }}-key
provide-xfr: {{ slave }} {{ zone.name }}-key
{% else %}
notify: {{ slave }} NOKEY
provide-xfr: {{ slave }} NOKEY
{% endif %}
{% endfor %}
{% endif %}
{% if zone.masters is defined %}
{% for master in zone.masters %}
{% if zone.secret is defined %}
allow-notify: {{ master }} {{ zone.name }}-key
request-xfr: AXFR {{ master }}@53 {{ zone.name }}-key
{% else %}
allow-notify: {{ master }} NOKEY
request-xfr: AXFR {{ master }}@53 NOKEY
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

8
templates/zone.j2 Normal file
View File

@ -0,0 +1,8 @@
$ORIGIN {{ item.name }}.
$TTL {{ item.ttl }}
@ IN SOA {{ item.ns_master }}. {{ item.email | replace("@", ".") }}. ({{ serial }} {{ item.refresh or "86400" }} {{ item.retry or "7200" }} {{ item.expire or "3600000" }} {{ item.default_ttl or "600" }} )
{% for entry in item.records %}
{{ entry }}
{% endfor %}