diff --git a/playbooks/ns.yml b/playbooks/ns.yml new file mode 100644 index 0000000..e29c441 --- /dev/null +++ b/playbooks/ns.yml @@ -0,0 +1,6 @@ +- name: Configure bind9 name server + hosts: all + tasks: + - name: Configure services to install in the server + import_role: + name: ns \ No newline at end of file diff --git a/roles/ns/defaults/main.yml b/roles/ns/defaults/main.yml new file mode 100644 index 0000000..f0be459 --- /dev/null +++ b/roles/ns/defaults/main.yml @@ -0,0 +1,28 @@ +bind_packages: + - bind9 + - bind9-dnsutils + - bind9-host + - bind9-libs + - bind9-utils + - dnsutils + - python3-pycurl +bind_config_templates: + - { src: 'named.conf.master.j2', dest: '/etc/bind/named.conf.master', mode: 'u=rw,g=r,o=r' } + - { src: 'named.conf.local.j2', dest: '/etc/bind/named.conf.local', mode: 'u=rw,g=r,o=r' } + - { src: 'named.conf.slave.j2', dest: '/etc/bind/named.conf.slave', mode: 'u=rw,g=r,o=r' } + - { src: 'certbot.key', dest: '/etc/bind/keys/certbot.key', mode: 'u=rw,g=r,o=' } + - { src: 'lan.key', dest: '/etc/bind/keys/lan.key', mode: 'u=rw,g=r,o=' } + - { src: 'wan.key', dest: '/etc/bind/keys/wan.key', mode: 'u=rw,g=r,o=' } + - { src: 'rndc.key', dest: '/etc/bind/rndc.key', mode: 'u=rw,g=r,o=' } + - { src: 'dhcp.key', dest: '/etc/bind/keys/dhcp.key', mode: 'u=rw,g=r,o=' } +directory: + - { path: '/root/scripts', owner: 'root', group: 'root', mode: 'u=rwx,g=rx,o=rx' } + - { path: '/etc/bind/keys', owner: 'root', group: 'bind', mode: 'u=rwx,g=rs,o=rx' } + - { path: '/root/scripts/switch-isp', owner: 'root', group: 'bind', mode: 'u=rwx,g=rs,o=rx' } +required_files: + - { src: 'delete.ns', dest: '/root/scripts/switch-isp', owner: 'root', group: 'bind', mode: 'u=rw,g=rw,o=r' } + - { src: 'isp1.ns', dest: '/root/scripts/switch-isp', owner: 'root', group: 'bind', mode: 'u=rw,g=rw,o=r' } + - { src: 'isp2.ns', dest: '/root/scripts/switch-isp', owner: 'root', group: 'bind', mode: 'u=rw,g=rw,o=r' } + - { src: 'switch-isp.sh', dest: '/root/scripts', owner: 'root', group: 'root', mode: 'u=rwx,g=rx,o=rx' } + - { src: 'sync-conf', dest: '/root/scripts', owner: 'root', group: 'root', mode: 'u=rwx,g=rx,o=rx' } + - { src: 'gen-key.sh', dest: '/root/scripts', owner: 'root', group: 'bind', mode: 'u=rwx,g=rx,o=rx' } diff --git a/roles/ns/files/delete.ns b/roles/ns/files/delete.ns new file mode 100644 index 0000000..cbb97ad --- /dev/null +++ b/roles/ns/files/delete.ns @@ -0,0 +1,14 @@ +update delete verdnatura.es A +update delete kube-proxy.verdnatura.es A +update delete smtp.verdnatura.es A +update delete imap.verdnatura.es A +update delete autodiscover.verdnatura.es A +update delete time1.verdnatura.es A +update delete time2.verdnatura.es A +update delete dc-ip01.verdnatura.es A +update delete dc-ip02.verdnatura.es A +update delete dc-ip03.verdnatura.es A +update delete dc-ip04.verdnatura.es A +update delete mailgw1.verdnatura.es A +update delete mailgw2.verdnatura.es A +send diff --git a/roles/ns/files/gen-key.sh b/roles/ns/files/gen-key.sh new file mode 100644 index 0000000..4c062a2 --- /dev/null +++ b/roles/ns/files/gen-key.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +KEYNAME=$1 + +if [ -z "$KEYNAME" ]; then + echo "Usage: $0 " + exit 1 +fi + +tsig-keygen -a hmac-sha512 "$KEYNAME" diff --git a/roles/ns/files/isp1.ns b/roles/ns/files/isp1.ns new file mode 100644 index 0000000..e9ed9b6 --- /dev/null +++ b/roles/ns/files/isp1.ns @@ -0,0 +1,16 @@ +update add verdnatura.es 3600 A 89.6.245.230 +update add verdnatura.es 3600 A 89.6.245.231 +update add kube-proxy.verdnatura.es 3600 A 89.6.245.230 +update add kube-proxy.verdnatura.es 3600 A 89.6.245.231 +update add smtp.verdnatura.es 3600 A 89.6.245.230 +update add imap.verdnatura.es 3600 A 89.6.245.230 +update add autodiscover.verdnatura.es 3600 A 89.6.245.230 +update add time1.verdnatura.es 3600 A 89.6.245.230 +update add time2.verdnatura.es 3600 A 89.6.245.230 +update add dc-ip01.verdnatura.es 3600 A 89.6.245.228 +update add dc-ip02.verdnatura.es 3600 A 89.6.245.229 +update add dc-ip03.verdnatura.es 3600 A 89.6.245.230 +update add dc-ip04.verdnatura.es 3600 A 89.6.245.231 +update add mailgw1.verdnatura.es 43200 A 89.6.245.232 +update add mailgw2.verdnatura.es 43200 A 89.6.245.233 +send diff --git a/roles/ns/files/isp2.ns b/roles/ns/files/isp2.ns new file mode 100644 index 0000000..f5bd027 --- /dev/null +++ b/roles/ns/files/isp2.ns @@ -0,0 +1,16 @@ +update add verdnatura.es 3600 A 195.77.191.180 +update add verdnatura.es 3600 A 195.77.191.181 +update add kube-proxy.verdnatura.es 3600 A 195.77.191.180 +update add kube-proxy.verdnatura.es 3600 A 195.77.191.181 +update add smtp.verdnatura.es 3600 A 195.77.191.180 +update add imap.verdnatura.es 3600 A 195.77.191.180 +update add autodiscover.verdnatura.es 3600 A 195.77.191.180 +update add time1.verdnatura.es 3600 A 195.77.191.180 +update add time2.verdnatura.es 3600 A 195.77.191.180 +update add dc-ip01.verdnatura.es 3600 A 195.77.191.178 +update add dc-ip02.verdnatura.es 3600 A 195.77.191.179 +update add dc-ip03.verdnatura.es 3600 A 195.77.191.180 +update add dc-ip04.verdnatura.es 3600 A 195.77.191.181 +update add mailgw1.verdnatura.es 43200 A 195.77.191.180 +update add mailgw2.verdnatura.es 43200 A 195.77.191.181 +send diff --git a/roles/ns/files/switch-isp.sh b/roles/ns/files/switch-isp.sh new file mode 100644 index 0000000..5444192 --- /dev/null +++ b/roles/ns/files/switch-isp.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +ISP=$1 + +if [ -z "$ISP" ]; then + echo "Usage: $0 " + exit 1 +fi + +KEY_FILE="/etc/bind/keys/wan.key" +NS_DIR="/root/scripts/switch-isp" +ISP_FILE="$NS_DIR/$ISP.ns" + +if [ ! -f "$ISP_FILE" ]; then + echo "ISP file for nsupdate not found: $ISP_FILE" + exit 2 +fi + +echo "Deleting ISP dependent DNS records." +nsupdate -k "$KEY_FILE" "$NS_DIR/delete.ns" + +echo "Registering $ISP DNS records." +nsupdate -k "$KEY_FILE" "$ISP_FILE" diff --git a/roles/ns/files/sync-conf b/roles/ns/files/sync-conf new file mode 100644 index 0000000..a3b947b --- /dev/null +++ b/roles/ns/files/sync-conf @@ -0,0 +1,27 @@ +#!/bin/bash + +if [ "$(hostname)" = "ns1" ]; then + partner=root@ns2.servers.dc.verdnatura.es +else + partner=root@ns1.servers.dc.verdnatura.es +fi + +confDir=/etc/bind + +echo "Restarting service." +service bind9 restart + +if [ $? -eq "0" ]; then + echo "Synchronizing partner configuration." + + scp "$confDir/named.conf.local" $partner:$confDir + scp "$confDir/named.conf.master" $partner:$confDir + scp "$confDir/named.conf.slave" $partner:$confDir + + ssh "$partner" rm -rf "$confDir/keys" + ssh "$partner" mkdir "$confDir/keys" + scp -r "$confDir/keys/"* $partner:"$confDir/keys" + + echo "Restarting partner service." + ssh $partner service bind9 restart +fi diff --git a/roles/ns/handlers/main.yml b/roles/ns/handlers/main.yml new file mode 100644 index 0000000..840d041 --- /dev/null +++ b/roles/ns/handlers/main.yml @@ -0,0 +1,4 @@ +- name: restart-dns + systemd: + name: bind9 + state: restarted \ No newline at end of file diff --git a/roles/ns/tasks/main.yml b/roles/ns/tasks/main.yml new file mode 100644 index 0000000..0948ab4 --- /dev/null +++ b/roles/ns/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: ns.yml + tags: ns diff --git a/roles/ns/tasks/ns.yml b/roles/ns/tasks/ns.yml new file mode 100644 index 0000000..7943efa --- /dev/null +++ b/roles/ns/tasks/ns.yml @@ -0,0 +1,34 @@ +- name: Update apt cache + apt: + update_cache: yes +- name: Install bind package requirements + apt: + name: "{{ bind_packages }}" + state: present + install_recommends: no +- name: Create directory + file: + path: "{{ item.path }}" + state: directory + owner: "{{ item.group }}" + group: "{{ item.group }}" + mode: "{{ item.mode }}" + loop: "{{ directory }}" +- name: Copy required files and scripts + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "{{ item.group }}" + group: "{{ item.group }}" + mode: "{{ item.mode }}" + loop: "{{ required_files }}" +- name: Deploy BIND config templates + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: bind + mode: "{{ item.mode }}" + loop: "{{ bind_config_templates }}" + notify: restart-dns + diff --git a/roles/ns/templates/certbot.key b/roles/ns/templates/certbot.key new file mode 100644 index 0000000..6e9f1b9 --- /dev/null +++ b/roles/ns/templates/certbot.key @@ -0,0 +1,4 @@ +key "certbot" { + algorithm hmac-sha512; + secret "{{ lookup(passbolt, 'certbot', folder_parent_id=passbolt_folder).password }}"; +}; diff --git a/roles/ns/templates/dhcp.key b/roles/ns/templates/dhcp.key new file mode 100644 index 0000000..a732d1e --- /dev/null +++ b/roles/ns/templates/dhcp.key @@ -0,0 +1,4 @@ +key "dhcp" { + algorithm hmac-sha512; + secret "{{ lookup(passbolt, 'dhcpkey', folder_parent_id=passbolt_folder).password }}"; +}; diff --git a/roles/ns/templates/lan.key b/roles/ns/templates/lan.key new file mode 100644 index 0000000..c99ad33 --- /dev/null +++ b/roles/ns/templates/lan.key @@ -0,0 +1,4 @@ +key "lan" { + algorithm hmac-sha512; + secret "{{ lookup(passbolt, 'lankey', folder_parent_id=passbolt_folder).password }}"; +}; diff --git a/roles/ns/templates/named.conf.local.j2 b/roles/ns/templates/named.conf.local.j2 new file mode 100644 index 0000000..45ac42f --- /dev/null +++ b/roles/ns/templates/named.conf.local.j2 @@ -0,0 +1,20 @@ +{% for path in bind_key_includes %} +include "{{ path }}"; +{% endfor %} + +{% for server in bind_bogus_servers %} +server {{ server }} { bogus yes; }; +{% endfor %} + +{% for acl_name, networks in bind_acls.items() %} +acl {{ acl_name }} { + {% for net in networks %} + {{ net }}; + {% endfor %} +}; +{% endfor %} + +controls { + inet {{ bind_controls["inet"] }} allow { {{ bind_controls["allow"] | join('; ') }}; } keys { {{ bind_controls["keys"] | map('regex_replace', '^(.*)$', '"\\1"') | join('; ') }}; }; +}; + diff --git a/roles/ns/templates/named.conf.master.j2 b/roles/ns/templates/named.conf.master.j2 new file mode 100644 index 0000000..814c5a8 --- /dev/null +++ b/roles/ns/templates/named.conf.master.j2 @@ -0,0 +1,72 @@ +options { + directory "{{ bind_cache_dir }}"; + max-cache-size {{ bind_max_cache_size }}; + auth-nxdomain no; + listen-on-v6 { none; }; + version "{{ bind_version }}"; + allow-update { none; }; + blackhole { rfc5735; }; + + allow-transfer { + {% for ip in bind_allow_transfer %} + {{ ip }}; + {% endfor %} + }; +}; + +view "lan" { + match-clients { + {% for item in bind_match_clients_lan %} + {{ item }}; + {% endfor %} + }; + + recursion yes; + allow-recursion { any; }; + empty-zones-enable yes; + notify {{ bind_notify_lan | default('yes') }}; + + include "/etc/bind/named.conf.default-zones"; + + {% for zone in bind_zones.lan %} + zone "{{ zone.name }}" { + type master; + forwarders {}; + allow-update { key {{ zone.key }}; }; + file "{{ zone.file }}"; + }; + {% endfor %} +}; + +view "wan" { + match-clients { any; }; + + recursion no; + allow-query-cache { none; }; + empty-zones-enable no; + + notify {{ bind_notify_wan }}; + + also-notify { + {% for entry in bind_also_notify %} + {{ entry.ip }} key {{ entry.key }}; + {% endfor %} + }; + + {% for zone in bind_zones.wan %} + {% if zone.in_view is defined %} + {% for z in zone.in_view %} + zone "{{ z }}" { + in-view "lan"; + }; + {% endfor %} + {% else %} + zone "{{ zone.name }}" { + type master; + forwarders {}; + allow-update { key {{ zone.key }}; }; + file "{{ zone.file }}"; + }; + {% endif %} + {% endfor %} +}; diff --git a/roles/ns/templates/named.conf.slave.j2 b/roles/ns/templates/named.conf.slave.j2 new file mode 100644 index 0000000..b4078b1 --- /dev/null +++ b/roles/ns/templates/named.conf.slave.j2 @@ -0,0 +1,68 @@ +options { + directory "{{ bind_cache_dir }}"; + + max-cache-size {{ bind_max_cache_size }}; + auth-nxdomain no; + listen-on-v6 { none; }; + version "{{ bind_version }}"; + allow-update { none; }; + blackhole { rfc5735; }; + + notify {{ bind_slave_notify }}; + allow-transfer { none; }; + masterfile-format {{ bind_masterfile_format }}; +}; + +masters master-ips { +{% for ip in bind_slave_masters %} + {{ ip }}; +{% endfor %} +}; + +view "lan" { + match-clients { + {% for item in bind_match_clients_lan %} + {{ item }}; + {% endfor %} + }; + + recursion yes; + allow-recursion { any; }; + empty-zones-enable yes; + + include "/etc/bind/named.conf.default-zones"; + + {% for zone in bind_zones.lan %} + zone "{{ zone.name }}" { + type slave; + masters { master-ips; }; + forwarders {}; + file "{{ zone.file }}"; + }; + {% endfor %} +}; + +view "wan" { + match-clients { any; }; + + recursion no; + allow-query-cache { none; }; + empty-zones-enable no; + + {% for zone in bind_zones.wan %} + {% if zone.in_view is defined %} + {% for z in zone.in_view %} + zone "{{ z }}" { + in-view "lan"; + }; + {% endfor %} + {% else %} + zone "{{ zone.name }}" { + type slave; + masters { {{ bind_slave_masters | join('; ') }} key {{ zone.key }}; }; + forwarders {}; + file "{{ zone.file }}"; + }; + {% endif %} + {% endfor %} +}; diff --git a/roles/ns/templates/rndc.key b/roles/ns/templates/rndc.key new file mode 100644 index 0000000..40d9600 --- /dev/null +++ b/roles/ns/templates/rndc.key @@ -0,0 +1,4 @@ +key "rndc-key" { + algorithm hmac-md5; + secret "{{ lookup(passbolt, 'rndc-key', folder_parent_id=passbolt_folder).password }}"; +}; diff --git a/roles/ns/templates/wan.key b/roles/ns/templates/wan.key new file mode 100644 index 0000000..daa655c --- /dev/null +++ b/roles/ns/templates/wan.key @@ -0,0 +1,4 @@ +key "wan-key" { + algorithm hmac-md5; + secret "{{ lookup(passbolt, 'wan-key', folder_parent_id=passbolt_folder).password }}"; +};