From 9032d8c024e4af5f497be30fded58298c0b26b66 Mon Sep 17 00:00:00 2001 From: Blallo Date: Mon, 3 Aug 2020 19:25:51 +0200 Subject: [PATCH] Init --- Vagrantfile | 39 ++++++++++++ ansible.cfg | 4 ++ handlers/main.yml | 15 +++++ inventory | 12 ++++ keys/gen_keys.py | 92 +++++++++++++++++++++++++++ keys/result.yml | 51 +++++++++++++++ keys/sagittariusAstar.pub | 1 + keys/sagittariusAstar.sec | 1 + keys/terminus.pub | 1 + keys/terminus.sec | 1 + keys/trantor.pub | 1 + keys/trantor.sec | 1 + playbook.yml | 8 +++ tasks/main.yml | 41 ++++++++++++ tasks/nsd.yml | 55 ++++++++++++++++ tasks/nsd_satellite.yml | 9 +++ tasks/nsd_star.yml | 85 +++++++++++++++++++++++++ tasks/unbound.yml | 28 +++++++++ tasks/wireguard.yml | 32 ++++++++++ templates/main_zone.conf.j2 | 24 +++++++ templates/nsd-satellite.conf.j2 | 8 +++ templates/nsd-star.conf.j2 | 13 ++++ templates/nsd.conf.j2 | 13 ++++ templates/unbound.conf.j2 | 26 ++++++++ templates/wireguard.conf.j2 | 14 +++++ templates/zone.conf.j2 | 20 ++++++ templates/zone_stub.conf.j2 | 10 +++ test_vars.yml | 108 ++++++++++++++++++++++++++++++++ 28 files changed, 713 insertions(+) create mode 100644 Vagrantfile create mode 100644 ansible.cfg create mode 100644 handlers/main.yml create mode 100644 inventory create mode 100755 keys/gen_keys.py create mode 100644 keys/result.yml create mode 100644 keys/sagittariusAstar.pub create mode 100644 keys/sagittariusAstar.sec create mode 100644 keys/terminus.pub create mode 100644 keys/terminus.sec create mode 100644 keys/trantor.pub create mode 100644 keys/trantor.sec create mode 100644 playbook.yml create mode 100644 tasks/main.yml create mode 100644 tasks/nsd.yml create mode 100644 tasks/nsd_satellite.yml create mode 100644 tasks/nsd_star.yml create mode 100644 tasks/unbound.yml create mode 100644 tasks/wireguard.yml create mode 100644 templates/main_zone.conf.j2 create mode 100644 templates/nsd-satellite.conf.j2 create mode 100644 templates/nsd-star.conf.j2 create mode 100644 templates/nsd.conf.j2 create mode 100644 templates/unbound.conf.j2 create mode 100644 templates/wireguard.conf.j2 create mode 100644 templates/zone.conf.j2 create mode 100644 templates/zone_stub.conf.j2 create mode 100644 test_vars.yml diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..231873d --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,39 @@ +# This guide is optimized for Vagrant 1.7 and above. +# Although versions 1.6.x should behave very similarly, it is recommended +# to upgrade instead of disabling the requirement below. +Vagrant.require_version ">= 1.7.0" + +Vagrant.configure(2) do |config| + + config.vm.box = "debian/buster64" + config.vm.synced_folder ".", "/vagrant", disabled: true + # Disable the new default behavior introduced in Vagrant 1.7, to + # ensure that all Vagrant machines will use the same SSH key pair. + # See https://github.com/mitchellh/vagrant/issues/5005 + config.ssh.insert_key = false + + config.vm.provider :libvirt do |lv| + lv.cpus = 1 + lv.memory = 512 + end + + config.vm.define "sagittariusAstar" do |m| + m.vm.hostname = "sagittariusAstar" + m.vm.network :private_network, ip: "192.168.123.20", libvirt__dhcp_enabled: false + end + config.vm.define "trantor" do |m| + m.vm.hostname = "trantor" + m.vm.network :private_network, ip: "192.168.123.21", libvirt__dhcp_enabled: false + end + config.vm.define "terminus" do |m| + m.vm.hostname = "terminus" + m.vm.network :private_network, ip: "192.168.123.22", libvirt__dhcp_enabled: false + end + + config.vm.provision "ansible" do |ansible| + ansible.become = true + ansible.verbose = "v" + ansible.playbook = "playbook.yml" + ansible.inventory_path = "inventory" + end +end diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..f0b3799 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +roles_path = ../ +vault_password_file = ./.ansible_vault_pw +ansible_python_interpreter = /usr/bin/python3 diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..6c52e8f --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,15 @@ +--- +- name: restart nsd + systemd: + name: nsd.service + state: restarted + +- name: restart unbound + systemd: + name: unbound.service + state: restarted + +- name: restart wireguard + systemd: + name: wg-quick@dns.service + state: restarted diff --git a/inventory b/inventory new file mode 100644 index 0000000..5a529cd --- /dev/null +++ b/inventory @@ -0,0 +1,12 @@ +--- +all: + hosts: + sagittariusAstar: + ansible_host: 192.168.123.20 + ansible_python_interpreter: /usr/bin/python3 + trantor: + ansible_host: 192.168.123.21 + ansible_python_interpreter: /usr/bin/python3 + terminus: + ansible_host: 192.168.123.22 + ansible_python_interpreter: /usr/bin/python3 diff --git a/keys/gen_keys.py b/keys/gen_keys.py new file mode 100755 index 0000000..456ca9c --- /dev/null +++ b/keys/gen_keys.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +import subprocess +import sys +import typing as T + +import yaml + +ENCODING = "utf-8" +HOSTS: T.Dict[T.Text, T.Dict[T.Text, T.Text]] = {} + + +# From: https://stackoverflow.com/a/43060743 +class DummyVault(yaml.YAMLObject): + yaml_tag = "!vault" + + def __init__(self, cyphertext): + self.cyphertext = "\n".join([e.strip() for e in cyphertext.split("\n")]) + + def __repr__(self): + return f"{self.__class__.__name__}({self.cyphertext[:10]}...)" + + @classmethod + def from_yaml(cls, loader, node): + return DummyVault(node.value) + + @classmethod + def to_yaml(cls, dumper, data): + return dumper.represent_scalar(cls.yaml_tag, data.cyphertext, style="|") + + +yaml.SafeLoader.add_constructor("!vault", DummyVault.from_yaml) +yaml.SafeDumper.add_multi_representer(DummyVault, DummyVault.to_yaml) + + +def load_hosts(inventory: T.Text) -> T.List[T.Text]: + with open(inventory, "r") as f: + data = yaml.load(f, Loader=yaml.SafeLoader) + + return [k for k in data["all"]["hosts"].keys()] + + +def gen_key(name: T.Text) -> None: + with open(f"{name}.sec", "w") as sec: + subprocess.call(["wg", "genkey"], stdout=sec) + with open(f"{name}.sec", "rb", 0) as sec_r, open(f"{name}.pub", "w") as pub: + subprocess.call(["wg", "pubkey"], stdin=sec_r, stdout=pub) + + +def to_vault(name: T.Text, passfile: T.Text) -> None: + with open(f"{name}.pub", "r") as pub: + pubkey = pub.readline() + enc_pub = subprocess.check_output( + [ + "ansible-vault", + "encrypt_string", + f"--vault-password-file={passfile}", + pubkey, + ] + ) + with open(f"{name}.sec", "r") as sec: + seckey = sec.readline() + enc_sec = subprocess.check_output( + [ + "ansible-vault", + "encrypt_string", + f"--vault-password-file={passfile}", + seckey, + ] + ) + HOSTS[name] = { + "public_key": yaml.load(enc_pub.decode(ENCODING), Loader=yaml.SafeLoader), + "private_key": yaml.load(enc_sec.decode(ENCODING), Loader=yaml.SafeLoader), + } + + +def usage() -> None: + print("Usage: \n\tgen_keys.py ") + + +if __name__ == "__main__": + if len(sys.argv) != 3: + usage() + sys.exit(-1) + + for host in load_hosts(sys.argv[1]): + gen_key(host) + to_vault(host, sys.argv[2]) + result = yaml.dump(HOSTS, Dumper=yaml.SafeDumper) + with open("result.yml", "w") as res: + res.write(result) + print(result) diff --git a/keys/result.yml b/keys/result.yml new file mode 100644 index 0000000..0f0c43a --- /dev/null +++ b/keys/result.yml @@ -0,0 +1,51 @@ +sagittariusAstar: + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 62346638623333623232376462346232316233653633343634376235393662396462326566633632 + 3538386564616436343138343832383362653730396532350a353632323562666333383066353437 + 31326366356139383636643663303263623537303730643236333363653135386636653064656163 + 3166656534663766300a383232323561303436343562363433636432613636653866636364613464 + 38663164646533656363613137353963643735633433303036316634373033306138306137356338 + 6239666465306638313037343231373663633833626130623462 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 65343336343938626332646439393065626636353837326166303239373463636664656535336365 + 6138326166653438346466336533656136653665313832350a616431646232306436366166666537 + 37313139303532663165343731666234633532323633646561353261613138666238353534633361 + 3931393637333339630a343465363766626536663530656535323265373864376165343737633033 + 31313262313133356364653964356537303761313135613464373031326334323933323033303733 + 3861373164663366313766663835636561356565383363373433 +terminus: + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 66623362633739316266376234363561656639376637666165323465643738323664643261613065 + 6463663063633163313432373564363636663234303264350a303032373336333133353766376364 + 37663965663837663936383265346164343563656636623133346132626664383262356465313836 + 3932666563326363660a306463383364386662613563653136333061326434373731323231323763 + 64353130336661306266636565626561376465393737663832303633633436343633363861616364 + 6436623833326632353363333862616634366133323534666166 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 66333135396638326166396264386535646633663730333632306166633166323230376563316466 + 3230383366336466623738613134346439303933346661630a626637313036613135656435343334 + 30643530363638326264316664393833666134613234333435333831353966383162633862303063 + 6665653534313461660a633566656130616562636337373434333037313030356336643266313135 + 35663563626137653065633463613966363961343138656566333731373833366164333136313032 + 3434343664333661346339373233373739393332636433363433 +trantor: + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 37646262626137633331326438306463353538636332353134306161333962356138663535666538 + 3064373263313763363630333733313966636665373130660a313163653136323634626431633161 + 35323831386164366534616265313532343961333734376362643637353332346434373461386362 + 3130656639303738620a313938376562373566646530383339376139623662633865306262393031 + 33623661313739653966643766613734653665353337663435336430633730643461346363613961 + 3531643132353633626333663539653839343963333037666536 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 64613433666138303634653661633536356362396431363134383736653539613237643839643565 + 6235326661333562646237623761356364376234383965300a666431663262346162633131363264 + 65623238663838643531343065353039306231323836326335323463303161333938613231303139 + 3132646335326339640a396162303436326231643364653637633036303137646666376138386637 + 66303465653361366565626139656665303162316663616634363361346534643161663932313434 + 6263316630323532346666373839613037303334316537366434 diff --git a/keys/sagittariusAstar.pub b/keys/sagittariusAstar.pub new file mode 100644 index 0000000..abb530d --- /dev/null +++ b/keys/sagittariusAstar.pub @@ -0,0 +1 @@ +DwC0MK70g3gvZ7iBQj0J58odoIh2ulGnepZiFkCXi1w= diff --git a/keys/sagittariusAstar.sec b/keys/sagittariusAstar.sec new file mode 100644 index 0000000..57c6d4b --- /dev/null +++ b/keys/sagittariusAstar.sec @@ -0,0 +1 @@ +8Hf8qcNX9j+1R3Z6EXx+bq6zk+YSAPpiqtEOp3HaAF0= diff --git a/keys/terminus.pub b/keys/terminus.pub new file mode 100644 index 0000000..632b48c --- /dev/null +++ b/keys/terminus.pub @@ -0,0 +1 @@ +P5l1kJKciHg8RQRrqoZkYojNxBXsqt3sRQutFJ6FbFc= diff --git a/keys/terminus.sec b/keys/terminus.sec new file mode 100644 index 0000000..bf78b6f --- /dev/null +++ b/keys/terminus.sec @@ -0,0 +1 @@ +8ALcicWoggVMku90Ndk9wmrC/0SvTkHvBm5dvJvIhmc= diff --git a/keys/trantor.pub b/keys/trantor.pub new file mode 100644 index 0000000..23a7ba7 --- /dev/null +++ b/keys/trantor.pub @@ -0,0 +1 @@ +IkJya851/bjJVHSxLc6HnSigWYSBoFC1NH9dEQ6o1iA= diff --git a/keys/trantor.sec b/keys/trantor.sec new file mode 100644 index 0000000..30fa268 --- /dev/null +++ b/keys/trantor.sec @@ -0,0 +1 @@ +eF2d3gMJgOBJMGrzG9p8PR57qtDY0lh8PLYX3Yjyo34= diff --git a/playbook.yml b/playbook.yml new file mode 100644 index 0000000..3db623d --- /dev/null +++ b/playbook.yml @@ -0,0 +1,8 @@ +--- +- hosts: all + gather_facts: yes + vars_files: + - ./test_vars.yml + roles: + - jnv.debian-backports + - dns diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..151310e --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- set_fact: + zones: "{{ [dns_server.main_zone] + dns_server.zones }}" + main_zone: "{{ dns_server.main_zone }}" + server: "{{ dns_server.servers|json_query(\"[?name=='\" + inventory_hostname + \"']\")|json_query('[0]') }}" + others: "{{ dns_server.servers|json_query(\"[?name!='\" + inventory_hostname + \"']\") }}" + star: "{{ dns_server.servers|json_query('[?star==`true`]')|json_query('[0]') }}" + satellites: "{{ dns_server.servers|json_query('[?satellite==`true`]') }}" + is_local_resolver: "{{ dns_server.servers|json_query(\"[?name=='\" + inventory_hostname + \"'].local_resolver\")|first|default(false) }}" + is_star: "{{ dns_server.servers|json_query(\"[?name=='\" + inventory_hostname + \"'].star\")|first|default(false) }}" + is_satellite: "{{ dns_server.servers|json_query(\"[?name=='\" + inventory_hostname + \"'].satellite\")|first|default(false) }}" + +- name: Ensure systemd-resolved is absent + systemd: + name: systemd-resolved + state: stopped + masked: yes + +- name: Ensure resolv.conf is appropriately configured + copy: + dest: /etc/resolv.conf + content: | + nameserver 8.8.8.8 + nameserver 1.1.1.1 + owner: root + group: root + mode: 0644 + +- include_tasks: wireguard.yml + +- include_tasks: nsd.yml + when: not wireguard.changed + +- include_tasks: nsd_star.yml + when: is_star and not wireguard.changed + +- include_tasks: nsd_satellite.yml + when: is_satellite and not wireguard.changed + +- include_tasks: unbound.yml + when: is_local_resolver and not wireguard.changed diff --git a/tasks/nsd.yml b/tasks/nsd.yml new file mode 100644 index 0000000..1bac46c --- /dev/null +++ b/tasks/nsd.yml @@ -0,0 +1,55 @@ +--- +- name: Ensure bullseye backports apt sources are present + copy: + content: | + deb http://http.debian.net/debian testing main contrib + dest: /etc/apt/sources.list.d/testing.list + owner: root + group: root + mode: 0600 + register: testing_sources + +- name: Ensure only nsd is taken from testing + copy: + content: | + Package: nsd + Pin: release a=testing + Pin-Priority: 999 + + Package: * + Pin: release a=stable + Pin-Priority: 700 + dest: /etc/apt/preferences.d/10-nsd-related + owner: root + group: root + mode: 0600 + register: repo_config + +- name: Ensure repo are up-to-date + apt: + update_cache: yes + when: repo_config.changed or testing_sources.changed + +- name: Ensure nsd is present + apt: + name: nsd + state: latest + +- fail: + msg: "Required nsd_addr is missing" + when: server.nsd_addr is not defined + +- fail: + msg: "Required nsd_port is missing" + when: server.nsd_port is not defined + +- name: Ensure main nsd conf is present + template: + src: templates/nsd.conf.j2 + dest: /etc/nsd/nsd.conf.d/00-server.conf + owner: root + group: root + mode: 0600 + notify: restart nsd + +- meta: flush_handlers diff --git a/tasks/nsd_satellite.yml b/tasks/nsd_satellite.yml new file mode 100644 index 0000000..8e6bdf5 --- /dev/null +++ b/tasks/nsd_satellite.yml @@ -0,0 +1,9 @@ +--- +- name: Ensure satellite nsd conf is present + template: + src: templates/nsd-satellite.conf.j2 + dest: /etc/nsd/nsd.conf.d/01-satellite.conf + owner: root + group: root + mode: 0600 + notify: restart nsd diff --git a/tasks/nsd_star.yml b/tasks/nsd_star.yml new file mode 100644 index 0000000..0519092 --- /dev/null +++ b/tasks/nsd_star.yml @@ -0,0 +1,85 @@ +--- +- name: Ensure zones directory is present + file: + path: /etc/nsd/zones + state: directory + owner: root + group: nsd + mode: 0750 + +- name: Ensure zones src directory is present + file: + path: /etc/nsd/src_zones + state: directory + owner: root + group: root + mode: 0750 + +- name: Ensure zone files are compiled + template: + src: templates/nsd-star.conf.j2 + dest: /etc/nsd/nsd.conf.d/10-zones.conf + owner: root + group: root + mode: 0640 + +- name: Ensure main zone stub is present + template: + src: templates/zone_stub.conf.j2 + dest: "/etc/nsd/src_zones/{{ main_zone.name }}.conf" + owner: root + group: root + mode: 0640 + vars: + name: "{{ main_zone.name }}" + mx_records: "{{ main_zone.records|json_query('[?type==`MX`]') }}" + records: "{{ main_zone.records|json_query('[?type!=`MX`]') }}" + register: main_zone_stub + +- name: Ensure main_zone is present + template: + src: templates/main_zone.conf.j2 + dest: "/etc/nsd/zones/{{ main_zone.name }}.conf" + owner: root + group: nsd + mode: 0640 + when: main_zone_stub.changed + notify: restart nsd + +- name: Ensure zones stubs are present + template: + src: templates/zone_stub.conf.j2 + dest: "/etc/nsd/src_zones/{{ item.name }}.conf" + owner: root + group: root + mode: 0640 + vars: + name: "{{ item.name }}" + mx_records: "{{ item.records|json_query('[?type==`MX`]') }}" + records: "{{ item.records|json_query('[?type!=`MX`]') }}" + loop: "{{ zones }}" + register: zone_stubs + +- name: Ensure zones are present + template: + src: templates/zone.conf.j2 + dest: "/etc/nsd/zones/{{ item.item.name }}.conf" + owner: root + group: nsd + mode: 0640 + vars: + zname: "{{ item.item.name }}" + zttl: "{{ item.item.ttl|default(3600) }}" + zsoa: "{{ item.item.soa }}" + zemail: "{{ item.item.email }}" + zmx_records: "{{ item.item.records|json_query('[?type==`MX`]') }}" + zrecords: "{{ item.item.records|json_query('[?type!=`MX`]') }}" + when: item.changed + loop: "{{ zone_stubs.results }}" + notify: restart nsd + +- name: Ensure nsd is started and enabled + systemd: + name: nsd.service + state: started + enabled: yes diff --git a/tasks/unbound.yml b/tasks/unbound.yml new file mode 100644 index 0000000..baf3638 --- /dev/null +++ b/tasks/unbound.yml @@ -0,0 +1,28 @@ +--- +- name: Ensure unbound is present + apt: + name: unbound + state: present + +- fail: + msg: "Required nsd_addr is missing" + when: server.nsd_addr is not defined + +- fail: + msg: "Required nsd_port is missing" + when: server.nsd_port is not defined + +- name: Ensure unbound config is present + template: + src: templates/unbound.conf.j2 + dest: /etc/unbound/unbound.conf + owner: root + group: root + mode: 0600 + notify: restart unbound + +- name: Ensure unbound service is enabled and started + systemd: + name: unbound.service + state: started + enabled: yes diff --git a/tasks/wireguard.yml b/tasks/wireguard.yml new file mode 100644 index 0000000..f4850f9 --- /dev/null +++ b/tasks/wireguard.yml @@ -0,0 +1,32 @@ +--- +- name: Ensure wireguard is present + apt: + name: wireguard-tools + state: present + default_release: buster-backports + register: wireguard + +- name: Ensure wireguard configuration is present + template: + src: templates/wireguard.conf.j2 + dest: "/etc/wireguard/dns.conf" + owner: root + group: root + mode: 0600 + notify: restart wireguard + +- name: Enable IPv4 forwarding + sysctl: + name: net.ipv4.ip_forward + value: 1 + reload: yes + +- name: Reboot to allow wireguard to start + reboot: + when: wireguard.changed + +- name: Ensure wireguard is enabled + systemd: + name: wg-quick@dns.service + state: started + enabled: yes diff --git a/templates/main_zone.conf.j2 b/templates/main_zone.conf.j2 new file mode 100644 index 0000000..aaaf473 --- /dev/null +++ b/templates/main_zone.conf.j2 @@ -0,0 +1,24 @@ +$ORIGIN {{ main_zone.name }}. +$TTL {{ main_zone.ttl|default(3600) }} + +{{ main_zone.name }}. SOA {{ main_zone.soa }}. {{ main_zone.email }}. ( + {{ ansible_date_time.epoch }} ; serial + 3600 ; refresh + 900 ; retry + 1209600 ; expire + 1800 ; ttl + ) + NS {{ server.hostname }}. +{% for satellite in satellites %} + NS {{ satellite.hostname }}. +{% endfor %} +{% for record in main_zone.records|default([])|json_query('[?type==`MX`]') %} + MX{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} +{{ server.hostname }}. IN A {{ server.public_ip }} +{% for satellite in satellites %} +{{ satellite.hostname }}. IN A {{ satellite.public_ip }} +{% endfor %} +{% for record in main_zone.records|default([])|json_query('[?type!=`MX`]') %} +{{ record.name }} IN {{ record.type }}{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} diff --git a/templates/nsd-satellite.conf.j2 b/templates/nsd-satellite.conf.j2 new file mode 100644 index 0000000..ecdcec8 --- /dev/null +++ b/templates/nsd-satellite.conf.j2 @@ -0,0 +1,8 @@ +{% for zone in zones -%} +zone: + name: {{ zone.name }}. + allow-notify: {{ star.vpn.address }} NOKEY + request-xfr: AXFR {{ star.vpn.address }}@{{ star.nsd_port }} NOKEY +{% endfor -%} + +# vim: set ft=yaml: diff --git a/templates/nsd-star.conf.j2 b/templates/nsd-star.conf.j2 new file mode 100644 index 0000000..4d076ff --- /dev/null +++ b/templates/nsd-star.conf.j2 @@ -0,0 +1,13 @@ +{% for zone in zones -%} +zone: + name: {{ zone.name }}. + zonefile: /etc/nsd/zones/{{ zone.name }}.conf + outgoing-interface: {{ server.vpn.address }} + {% for satellite in satellites -%} + notify: {{ satellite.vpn.address }}@{{ satellite.nsd_port }} NOKEY + provide-xfr: {{ satellite.vpn.address }} NOKEY + {% endfor %} + +{% endfor -%} + +# vim: set ft=yaml: diff --git a/templates/nsd.conf.j2 b/templates/nsd.conf.j2 new file mode 100644 index 0000000..62685d9 --- /dev/null +++ b/templates/nsd.conf.j2 @@ -0,0 +1,13 @@ +server: + server-count: {{ ansible_processor_vcpus|default(2) }} + ip-address: {{ server.nsd_addr }} + ip-address: {{ server.vpn.address }} + port: {{ server.nsd_port }} + do-ip4: {{ server.ipv4|default('yes') }} + do-ip6: {{ server.ipv6|default('no') }} + hide-version: yes + refuse-any: {{ server.refuse_any|default('yes') }} + log-only-syslog: yes + verbosity: {{ dns_server.verbosity }} + +# vim: set ft=yaml: diff --git a/templates/unbound.conf.j2 b/templates/unbound.conf.j2 new file mode 100644 index 0000000..0f22031 --- /dev/null +++ b/templates/unbound.conf.j2 @@ -0,0 +1,26 @@ +# handled by ansible + +server: + verbosity: {{ dns_server.verbosity }} + do-not-query-localhost: no + directory: "/etc/unbound" + username: unbound + pidfile: "/run/unbound.pid" + {% if server.verbosity is defined -%} + verbosity: {{ server.verbosity }} + {% endif -%} + {% for addr in server.bind_addr|default(['0.0.0.0']) -%} + interface: {{ addr }} + {% endfor -%} + {% for addr in server.access_control_allow|default([]) -%} + access-control: {{ addr }} allow + {% endfor -%} + {% for addr in server.access_control_deny|default([]) -%} + access-control: {{ addr }} deny + {% endfor -%} + + {% for zone in zones -%} + forward-zone: + name: {{ zone.name }}. + forward-addr: {{ server.nsd_addr }}@{{ server.nsd_port }} + {% endfor %} diff --git a/templates/wireguard.conf.j2 b/templates/wireguard.conf.j2 new file mode 100644 index 0000000..995407e --- /dev/null +++ b/templates/wireguard.conf.j2 @@ -0,0 +1,14 @@ +[Interface] +Address = {{ server.vpn.address }}/{{ server.vpn.net_size }} +PrivateKey = {{ server.vpn.private_key }} +ListenPort = {{ server.vpn.listen_port|default(1194) }} +{% for peer in others %} + +[Peer] +AllowedIps = {{ peer.vpn.address }}/32 +Endpoint = {{ peer.public_ip }}:{{ peer.vpn.listen_port|default(1194) }} +PublicKey = {{ peer.vpn.public_key }} +{% endfor %} + + +# vim: set ft=dosini: diff --git a/templates/zone.conf.j2 b/templates/zone.conf.j2 new file mode 100644 index 0000000..98ddf71 --- /dev/null +++ b/templates/zone.conf.j2 @@ -0,0 +1,20 @@ +$ORIGIN {{ zname }}. +$TTL {{ zttl }} + +{{ zname }}. SOA {{ zsoa }}. {{ zemail }}. ( + {{ ansible_date_time.epoch }} ; serial + 3600 ; refresh + 900 ; retry + 1209600 ; expire + 1800 ; ttl + ) + NS {{ server.hostname }}. +{% for satellite in satellites %} + NS {{ satellite.hostname }}. +{% endfor %} +{% for record in zmx_records %} + MX{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} +{% for record in zrecords %} +{{ record.name }} IN {{ record.type }}{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} diff --git a/templates/zone_stub.conf.j2 b/templates/zone_stub.conf.j2 new file mode 100644 index 0000000..44618bd --- /dev/null +++ b/templates/zone_stub.conf.j2 @@ -0,0 +1,10 @@ + NS {{ server.hostname }}. +{% for satellite in satellites %} + NS {{ satellite.hostname }}. +{% endfor %} +{% for record in mx_records %} + MX{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} +{% for record in records %} +{{ record.name }} IN {{ record.type }}{% if record.opts is defined %} {{ record.opts }}{% endif %} {{ record.value }} +{% endfor %} diff --git a/test_vars.yml b/test_vars.yml new file mode 100644 index 0000000..72a7205 --- /dev/null +++ b/test_vars.yml @@ -0,0 +1,108 @@ +--- +dns_server: + verbosity: 3 + main_zone: + name: foundation.lan + soa: sagittarius.foundation.lan + email: postmaster.foundation.lan + records: + - {name: "", type: MX, value: "10 terminus"} + - {name: "", type: MX, value: "20 trantor"} + zones: + - name: seldon.org + soa: sagittarius.seldon.org + email: postmaster.seldon.org + records: + - {name: sagittarius, type: A, value: 192.168.123.20} + - {name: hari, type: A, value: 192.168.123.21} + - {name: "", type: MX, value: "10 sagittarius"} + - {name: "", type: MX, value: "40 the.mule.net."} + - name: mule.net + soa: the.mule.net + email: postmaster@foundation.net + records: + - {name: the, type: A, value: 10.13.12.20} + - {name: "", type: MX, value: "10 sagittarius.seldon.org."} + - {name: "", type: MX, value: "40 the"} + - {name: _special_key, type: TXT, value: "GOTCHA"} + servers: + + - name: sagittariusAstar + hostname: sagittarius.foundation.lan + local_resolver: true + nsd_addr: 127.0.0.1 + nsd_port: 5353 + star: true + public_ip: 192.168.123.20 + vpn: + address: 10.13.12.20 + net_size: 24 + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 62346638623333623232376462346232316233653633343634376235393662396462326566633632 + 3538386564616436343138343832383362653730396532350a353632323562666333383066353437 + 31326366356139383636643663303263623537303730643236333363653135386636653064656163 + 3166656534663766300a383232323561303436343562363433636432613636653866636364613464 + 38663164646533656363613137353963643735633433303036316634373033306138306137356338 + 6239666465306638313037343231373663633833626130623462 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 65343336343938626332646439393065626636353837326166303239373463636664656535336365 + 6138326166653438346466336533656136653665313832350a616431646232306436366166666537 + 37313139303532663165343731666234633532323633646561353261613138666238353534633361 + 3931393637333339630a343465363766626536663530656535323265373864376165343737633033 + 31313262313133356364653964356537303761313135613464373031326334323933323033303733 + 3861373164663366313766663835636561356565383363373433 + + - name: trantor + hostname: trantor.foundation.lan + local_resolver: true + nsd_addr: 127.0.0.1 + nsd_port: 5353 + satellite: true + public_ip: 192.168.123.21 + vpn: + address: 10.13.12.21 + net_size: 24 + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 37646262626137633331326438306463353538636332353134306161333962356138663535666538 + 3064373263313763363630333733313966636665373130660a313163653136323634626431633161 + 35323831386164366534616265313532343961333734376362643637353332346434373461386362 + 3130656639303738620a313938376562373566646530383339376139623662633865306262393031 + 33623661313739653966643766613734653665353337663435336430633730643461346363613961 + 3531643132353633626333663539653839343963333037666536 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 64613433666138303634653661633536356362396431363134383736653539613237643839643565 + 6235326661333562646237623761356364376234383965300a666431663262346162633131363264 + 65623238663838643531343065353039306231323836326335323463303161333938613231303139 + 3132646335326339640a396162303436326231643364653637633036303137646666376138386637 + 66303465653361366565626139656665303162316663616634363361346534643161663932313434 + 6263316630323532346666373839613037303334316537366434 + + - name: terminus + hostname: terminus.foundation.lan + nsd_addr: 127.0.0.1 + nsd_port: 5353 + satellite: true + public_ip: 192.168.123.22 + vpn: + address: 10.13.12.22 + net_size: 24 + private_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 66623362633739316266376234363561656639376637666165323465643738323664643261613065 + 6463663063633163313432373564363636663234303264350a303032373336333133353766376364 + 37663965663837663936383265346164343563656636623133346132626664383262356465313836 + 3932666563326363660a306463383364386662613563653136333061326434373731323231323763 + 64353130336661306266636565626561376465393737663832303633633436343633363861616364 + 6436623833326632353363333862616634366133323534666166 + public_key: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 66333135396638326166396264386535646633663730333632306166633166323230376563316466 + 3230383366336466623738613134346439303933346661630a626637313036613135656435343334 + 30643530363638326264316664393833666134613234333435333831353966383162633862303063 + 6665653534313461660a633566656130616562636337373434333037313030356336643266313135 + 35663563626137653065633463613966363961343138656566333731373833366164333136313032 + 3434343664333661346339373233373739393332636433363433