diff --git a/roles/nsd/handlers/main.yml b/roles/nsd/handlers/main.yml new file mode 100644 index 0000000..2dace3e --- /dev/null +++ b/roles/nsd/handlers/main.yml @@ -0,0 +1,14 @@ +--- +- name: Reload s6-rc + service: + name: s6-rc + state: reloaded + +- name: Reload nsd + command: s6-svc -h /run/service/nsd + +- name: Restart nsd + command: s6-svc -wR -T 5000 -ru /run/service/nsd + +- name: Restart nsd log + command: s6-svc -wR -T 5000 -ru /run/service/nsd-log diff --git a/roles/nsd/tasks/main.yml b/roles/nsd/tasks/main.yml new file mode 100644 index 0000000..c51a411 --- /dev/null +++ b/roles/nsd/tasks/main.yml @@ -0,0 +1,84 @@ +--- +- name: Install nsd + package: + name: nsd + state: present + +- name: Add /var/log/nsd to fstab + mount: + path: /var/log/nsd + src: tmpfs + fstype: tmpfs + opts: 'rw,size={{ nsd_log_size }},mode={{ nsd_log_mode }},uid={{ nsd_log_uid }},gid={{ nsd_log_gid }},late' + state: mounted + +- name: Create nsd service directories + file: + path: '/etc/s6-rc/service/{{ item }}' + state: directory + owner: root + group: wheel + mode: 0755 + with_items: '{{ nsd_service_dirs }}' + notify: + - Reload s6-rc + - Restart nsd log + - Restart nsd + +- name: Generate nsd service scripts + template: + dest: '/etc/s6-rc/service/{{ item }}' + src: '{{ item }}.j2' + mode: 0555 + owner: root + group: wheel + with_items: '{{ nsd_service_scripts }}' + notify: + - Reload s6-rc + - Restart nsd log + - Restart nsd + +- name: Generate nsd service configuration + copy: + dest: '/etc/s6-rc/service/{{ item.name }}' + content: '{{ item.content }}' + mode: 0444 + owner: root + group: wheel + loop_control: + label: '{{ item.name }} = {{ item.content }}' + notify: + - Reload s6-rc + - Restart nsd log + - Restart nsd + with_items: '{{ nsd_service_config }}' + +- name: Configure nsd + template: + dest: /usr/local/etc/nsd/nsd.conf + src: nsd.conf.j2 + mode: 0444 + owner: root + group: wheel + notify: + - Reload nsd + +- name: Flush handlers + meta: flush_handlers + +- name: Start nsd + command: fdmove -c 2 1 s6-rc -u -v 2 -t 15000 change nsd + register: change + changed_when: change.stdout | length > 0 + +- name: Enable nsd + lineinfile: + path: /etc/s6-rc/service/enabled/contents + regexp: "^nsd$" + line: nsd + state: present + notify: + - Reload s6-rc + +- name: Flush handlers (again) + meta: flush_handlers diff --git a/roles/nsd/templates/nsd-log/finish.j2 b/roles/nsd/templates/nsd-log/finish.j2 new file mode 100644 index 0000000..37c3bce --- /dev/null +++ b/roles/nsd/templates/nsd-log/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}-log: Stopped." +} + echo "${NAME}-log: Failed with exit status (${1}, ${2})." diff --git a/roles/nsd/templates/nsd-log/run.j2 b/roles/nsd/templates/nsd-log/run.j2 new file mode 100644 index 0000000..1f9904f --- /dev/null +++ b/roles/nsd/templates/nsd-log/run.j2 @@ -0,0 +1,23 @@ +#!/usr/local/bin/execlineb +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME + importas -i -u USER USER + importas -i -u GROUP GROUP + importas -i -u MODE MODE + importas -i -u DIR DIR +} + +foreground { fdmove -c 1 2 echo "${NAME} log: Starting." } + +ifelse -n { install -d -o "${USER}" -g "${GROUP}" -m "${MODE}" "$DIR" } { + foreground { fdmove -c 1 2 echo "${NAME} log: Failed to create logging directory." } + false +} + +fdmove -c 2 1 + +s6-envuidgid $USER +s6-log -d 3 T $DIR diff --git a/roles/nsd/templates/nsd.conf.j2 b/roles/nsd/templates/nsd.conf.j2 new file mode 100644 index 0000000..b987751 --- /dev/null +++ b/roles/nsd/templates/nsd.conf.j2 @@ -0,0 +1,40 @@ +# {{ ansible_managed }} + +server: + ip-address: 127.0.0.1@5353 + ip-address: ::1@5353 + + # policy + statistics: 3600 + round-robin: yes + minimal-responses: yes + hide-version: yes + hide-identity: no + + # performance + server-count: 1 + tcp-timeout: 12 + + # place nice with s6-rc + log-time-ascii: no + debug-mode: yes + +# Remote control config section. +remote-control: + control-enable: yes + control-interface: /var/run/nsd/control + +zone: + name: "." + request-xfr: 192.228.79.201 NOKEY # b.root-servers.net + request-xfr: 192.33.4.12 NOKEY # c.root-servers.net + request-xfr: 192.5.5.241 NOKEY # f.root-servers.net + request-xfr: 192.112.36.4 NOKEY # g.root-servers.net + request-xfr: 193.0.14.129 NOKEY # k.root-servers.net + request-xfr: 192.0.47.132 NOKEY # xfr.cjr.dns.icann.org + request-xfr: 192.0.32.132 NOKEY # xfr.lax.dns.icann.org + request-xfr: 2001:500:84::b NOKEY # b.root-servers.net + request-xfr: 2001:500:2f::f NOKEY # f.root-servers.net + request-xfr: 2001:7fd::1 NOKEY # k.root-servers.net + request-xfr: 2620:0:2830:202::132 NOKEY # xfr.cjr.dns.icann.org + request-xfr: 2620:0:2d0:202::132 NOKEY # xfr.lax.dns.icann.org diff --git a/roles/nsd/templates/nsd/data/check.j2 b/roles/nsd/templates/nsd/data/check.j2 new file mode 100644 index 0000000..d7b8b33 --- /dev/null +++ b/roles/nsd/templates/nsd/data/check.j2 @@ -0,0 +1,18 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +ifelse { + redirfd -w 1 /dev/null + fdmove -c 2 1 + nsd-control status +} { + foreground { fdmove -c 1 2 echo "${NAME}: Ready." } + true +} + foreground { fdmove -c 1 2 echo "${NAME}: Poll." } + false diff --git a/roles/nsd/templates/nsd/finish.j2 b/roles/nsd/templates/nsd/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/nsd/templates/nsd/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/nsd/templates/nsd/run.j2 b/roles/nsd/templates/nsd/run.j2 new file mode 100644 index 0000000..fa71eda --- /dev/null +++ b/roles/nsd/templates/nsd/run.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +foreground { fdmove -c 1 2 echo "${NAME}: Starting." } +s6-notifyoncheck -d -w 100 -n 70 + +fdmove -c 2 1 +nsd diff --git a/roles/nsd/vars/main.yml b/roles/nsd/vars/main.yml new file mode 100644 index 0000000..90d8fa7 --- /dev/null +++ b/roles/nsd/vars/main.yml @@ -0,0 +1,50 @@ +--- +nsd_log_size: '32m' +nsd_log_mode: '750' +nsd_log_uid: '20000' +nsd_log_gid: '20000' + +nsd_service_dirs: + - nsd + - nsd/env + - nsd/data + - nsd-log + - nsd-log/env + +nsd_service_scripts: + - nsd/run + - nsd/finish + - nsd/data/check + - nsd-log/run + - nsd-log/finish + +nsd_service_config: + - name: nsd/type + content: longrun + - name: nsd/producer-for + content: nsd-log + - name: nsd/notification-fd + content: 3 + - name: nsd/env/NAME + content: nsd + - name: nsd/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + + - name: nsd-log/type + content: longrun + - name: nsd-log/notification-fd + content: 3 + - name: nsd-log/consumer-for + content: nsd + - name: nsd-log/env/NAME + content: nsd + - name: nsd-log/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: nsd-log/env/MODE + content: '750' + - name: nsd-log/env/USER + content: s6-log + - name: nsd-log/env/GROUP + content: s6-log + - name: nsd-log/env/DIR + content: /var/log/nsd diff --git a/roles/unbound/handlers/main.yml b/roles/unbound/handlers/main.yml new file mode 100644 index 0000000..ddcd7b8 --- /dev/null +++ b/roles/unbound/handlers/main.yml @@ -0,0 +1,14 @@ +--- +- name: Reload s6-rc + service: + name: s6-rc + state: reloaded + +- name: Reload unbound + command: s6-svc -h /run/service/unbound + +- name: Restart unbound + command: s6-svc -wR -T 5000 -ru /run/service/unbound + +- name: Restart unbound log + command: s6-svc -wR -T 5000 -ru /run/service/unbound-log diff --git a/roles/unbound/tasks/main.yml b/roles/unbound/tasks/main.yml new file mode 100644 index 0000000..4767093 --- /dev/null +++ b/roles/unbound/tasks/main.yml @@ -0,0 +1,84 @@ +--- +- name: Install unbound + package: + name: unbound + state: present + +- name: Add /var/log/unbound to fstab + mount: + path: /var/log/unbound + src: tmpfs + fstype: tmpfs + opts: 'rw,size={{ unbound_log_size }},mode={{ unbound_log_mode }},uid={{ unbound_log_uid }},gid={{ unbound_log_gid }},late' + state: mounted + +- name: Create unbound service directories + file: + path: '/etc/s6-rc/service/{{ item }}' + state: directory + owner: root + group: wheel + mode: 0755 + with_items: '{{ unbound_service_dirs }}' + notify: + - Reload s6-rc + - Restart unbound log + - Restart unbound + +- name: Generate unbound service scripts + template: + dest: '/etc/s6-rc/service/{{ item }}' + src: '{{ item }}.j2' + mode: 0555 + owner: root + group: wheel + with_items: '{{ unbound_service_scripts }}' + notify: + - Reload s6-rc + - Restart unbound log + - Restart unbound + +- name: Generate unbound service configuration + copy: + dest: '/etc/s6-rc/service/{{ item.name }}' + content: '{{ item.content }}' + mode: 0444 + owner: root + group: wheel + loop_control: + label: '{{ item.name }} = {{ item.content }}' + notify: + - Reload s6-rc + - Restart unbound log + - Restart unbound + with_items: '{{ unbound_service_config }}' + +- name: Configure unbound + template: + dest: /usr/local/etc/unbound/unbound.conf + src: unbound.conf.j2 + mode: 0444 + owner: root + group: wheel + notify: + - Reload unbound + +- name: Flush handlers + meta: flush_handlers + +- name: Start unbound + command: fdmove -c 2 1 s6-rc -u -v 2 -t 15000 change unbound + register: change + changed_when: change.stdout | length > 0 + +- name: Enable unbound + lineinfile: + path: /etc/s6-rc/service/enabled/contents + regexp: "^unbound$" + line: unbound + state: present + notify: + - Reload s6-rc + +- name: Flush handlers (again) + meta: flush_handlers diff --git a/roles/unbound/templates/unbound-log/finish.j2 b/roles/unbound/templates/unbound-log/finish.j2 new file mode 100644 index 0000000..37c3bce --- /dev/null +++ b/roles/unbound/templates/unbound-log/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}-log: Stopped." +} + echo "${NAME}-log: Failed with exit status (${1}, ${2})." diff --git a/roles/unbound/templates/unbound-log/run.j2 b/roles/unbound/templates/unbound-log/run.j2 new file mode 100644 index 0000000..1f9904f --- /dev/null +++ b/roles/unbound/templates/unbound-log/run.j2 @@ -0,0 +1,23 @@ +#!/usr/local/bin/execlineb +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME + importas -i -u USER USER + importas -i -u GROUP GROUP + importas -i -u MODE MODE + importas -i -u DIR DIR +} + +foreground { fdmove -c 1 2 echo "${NAME} log: Starting." } + +ifelse -n { install -d -o "${USER}" -g "${GROUP}" -m "${MODE}" "$DIR" } { + foreground { fdmove -c 1 2 echo "${NAME} log: Failed to create logging directory." } + false +} + +fdmove -c 2 1 + +s6-envuidgid $USER +s6-log -d 3 T $DIR diff --git a/roles/unbound/templates/unbound.conf.j2 b/roles/unbound/templates/unbound.conf.j2 new file mode 100644 index 0000000..68c0258 --- /dev/null +++ b/roles/unbound/templates/unbound.conf.j2 @@ -0,0 +1,74 @@ +# {{ ansible_managed }} +# +server: + num-threads: 1 + interface: 127.0.0.1 + interface: ::1 + + outgoing-num-tcp: 128 + incoming-num-tcp: 128 + so-rcvbuf: 1m + so-sndbuf: 1m + + do-ip4: yes + do-ip6: yes + do-udp: yes + do-tcp: yes + + access-control: ::0/0 refuse + access-control: 0.0.0.0/0 refuse + access-control: ::1 allow + access-control: 127.0.0.0/8 allow + access-control: 2a01:4f8:150:926f::0/64 allow + access-control: 10.0.0.0/24 allow + + chroot: "/usr/local/etc/unbound" + + username: "unbound" + directory: "/usr/local/etc/unbound" + + use-systemd: no + do-daemonize: no + use-syslog: no + logfile: "" + + pidfile: "/usr/local/etc/unbound/unbound.pid" + + hide-identity: yes + hide-version: yes + hide-trustanchor: yes + harden-dnssec-stripped: yes + harden-below-nxdomain: yes + qname-minimisation: yes + qname-minimisation-strict: yes + use-caps-for-id: yes + + private-address: 10.0.0.0/8 + private-address: 172.16.0.0/12 + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: fd00::/8 + private-address: fe80::/10 + private-address: ::ffff:0:0/96 + + do-not-query-localhost: no + + prefetch: yes + prefetch-key: yes + deny-any: no + rrset-roundrobin: yes + minimal-responses: yes + disable-dnssec-lame-check: no + + module-config: "validator iterator" + + local-zone: "10.in-addr.arpa" nodefault + +remote-control: + control-enable: yes + control-interface: /usr/local/etc/unbound/control + +stub-zone: + name: "." + stub-prime: no + stub-addr: 127.0.0.1@5353 diff --git a/roles/unbound/templates/unbound/data/check.j2 b/roles/unbound/templates/unbound/data/check.j2 new file mode 100644 index 0000000..ba08d7b --- /dev/null +++ b/roles/unbound/templates/unbound/data/check.j2 @@ -0,0 +1,18 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +ifelse { + redirfd -w 1 /dev/null + fdmove -c 2 1 + unbound-control status +} { + foreground { fdmove -c 1 2 echo "${NAME}: Ready." } + true +} + foreground { fdmove -c 1 2 echo "${NAME}: Poll." } + false diff --git a/roles/unbound/templates/unbound/finish.j2 b/roles/unbound/templates/unbound/finish.j2 new file mode 100644 index 0000000..00e3945 --- /dev/null +++ b/roles/unbound/templates/unbound/finish.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -S2 +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +fdmove -c 1 2 +ifelse { test "${1}" -eq 0 } { + echo "${NAME}: Stopped." +} + echo "${NAME}: Failed with exit status (${1}, ${2})." diff --git a/roles/unbound/templates/unbound/run.j2 b/roles/unbound/templates/unbound/run.j2 new file mode 100644 index 0000000..8edf182 --- /dev/null +++ b/roles/unbound/templates/unbound/run.j2 @@ -0,0 +1,13 @@ +#!/usr/local/bin/execlineb -P +# {{ ansible_managed }} + +s6-envdir ./env +multisubstitute { + importas -i -u NAME NAME +} + +foreground { fdmove -c 1 2 echo "${NAME}: Starting." } +s6-notifyoncheck -d -w 100 -n 70 + +fdmove -c 2 1 +unbound diff --git a/roles/unbound/vars/main.yml b/roles/unbound/vars/main.yml new file mode 100644 index 0000000..1f84df9 --- /dev/null +++ b/roles/unbound/vars/main.yml @@ -0,0 +1,52 @@ +--- +unbound_log_size: '32m' +unbound_log_mode: '750' +unbound_log_uid: '20000' +unbound_log_gid: '20000' + +unbound_service_dirs: + - unbound + - unbound/env + - unbound/data + - unbound-log + - unbound-log/env + +unbound_service_scripts: + - unbound/run + - unbound/finish + - unbound/data/check + - unbound-log/run + - unbound-log/finish + +unbound_service_config: + - name: unbound/type + content: longrun + - name: unbound/producer-for + content: unbound-log + - name: unbound/notification-fd + content: 3 + - name: unbound/env/NAME + content: unbound + - name: unbound/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: unbound/dependencies + content: nsd + + - name: unbound-log/type + content: longrun + - name: unbound-log/notification-fd + content: 3 + - name: unbound-log/consumer-for + content: unbound + - name: unbound-log/env/NAME + content: unbound + - name: unbound-log/env/PATH + content: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin + - name: unbound-log/env/MODE + content: '750' + - name: unbound-log/env/USER + content: s6-log + - name: unbound-log/env/GROUP + content: s6-log + - name: unbound-log/env/DIR + content: /var/log/unbound diff --git a/site.yml b/site.yml index 604de38..7643a22 100644 --- a/site.yml +++ b/site.yml @@ -1,5 +1,7 @@ --- - import_playbook: s6.yml +- import_playbook: dns.yml +- import_playbook: ntp.yml - import_playbook: haproxy.yml - import_playbook: bhyve.yml - import_playbook: mail.yml