diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..0769dbb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Attach using Process Id", + "type": "python", + "request": "attach", + "processId": "${command:pickProcess}", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/hidden_primary.yml b/hidden_primary.yml new file mode 100644 index 0000000..fd14943 --- /dev/null +++ b/hidden_primary.yml @@ -0,0 +1,4 @@ +- hosts: hidden_primary + gather_facts: no + roles: + - hidden_primary \ No newline at end of file diff --git a/library/build_axfr_list.py b/library/build_axfr_list.py new file mode 100644 index 0000000..250e4e5 --- /dev/null +++ b/library/build_axfr_list.py @@ -0,0 +1,135 @@ +#!/usr/bin/python + +# Copyright: (c) 2023, Adora Laura Kalb +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = r''' +--- +module: build_axfr_list + +short_description: builds list of IPs for AXFR allow list + +# If this is part of a collection, you need to use semantic versioning, +# i.e. the version is of the form "2.5.0" and not "2.4". +version_added: "0.0.1" + +description: This is my longer description explaining my test module. + +options: + key: + description: This is the dictionary key to use for building the list. + required: true + type: str + group: + description: This is the user group that we use to get the relevant hosts. + required: true + type: str +# Specify this value according to your collection +# in format of namespace.collection.doc_fragment_name +# extends_documentation_fragment: +# - my_namespace.my_collection.my_doc_fragment_name + +author: + - Adora Kalb (@lauralani) +''' + +EXAMPLES = r''' +# Pass in a message +- name: Test with a message + my_namespace.my_collection.my_test: + name: hello world + +# pass in a message and have changed true +- name: Test with a message and changed output + my_namespace.my_collection.my_test: + name: hello world + new: true + +# fail the module +- name: Test failure of the module + my_namespace.my_collection.my_test: + name: fail me +''' + +RETURN = r''' +# These are examples of possible return values, and in general should use other names for return values. +original_message: + description: The original name param that was passed in. + type: str + returned: always + sample: 'hello world' +message: + description: The output message that the test module generates. + type: str + returned: always + sample: 'goodbye' +''' + +from ansible.module_utils.basic import AnsibleModule + + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + key=dict(type='str', required=True), + group=dict(type='str', required=True), + hostvars=dict(type='dict', required=True), + hosts=dict(type='list', required=True) + ) + + # seed the result dict in the object + # we primarily care about changed and state + # changed is if this module effectively modified the target + # state will include any data that you want your module to pass back + # for consumption, for example, in a subsequent task + result = dict( + changed=False, + axfr_list=[] + ) + + # the AnsibleModule object will be our abstraction working with Ansible + # this includes instantiation, a couple of common attr would be the + # args/params passed to the execution, as well as if the module + # supports check mode + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=False # TODO + ) + + # if the user is working with this module in only check mode we do not + # want to make any changes to the environment, just return the current + # state with no modifications + + # TODO + #if module.check_mode: + # module.exit_json(**result) + + # manipulate or modify the state as needed (this is going to be the + # part where your module will do what it needs to do) + + + host_ips = [] + for hostname in module.params['hosts']: + + + + axfr_ip = module.params['hostvars'][hostname][module.params['key']] + host_ips.append(axfr_ip) + + + result['axfr_list'] = host_ips + + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/roles/powerdns-install/tasks/main.yml b/roles/autosecondaries/tasks/main.yml similarity index 100% rename from roles/powerdns-install/tasks/main.yml rename to roles/autosecondaries/tasks/main.yml diff --git a/roles/powerdns-install/templates/pdns.conf.j2 b/roles/autosecondaries/templates/pdns.conf.j2 similarity index 84% rename from roles/powerdns-install/templates/pdns.conf.j2 rename to roles/autosecondaries/templates/pdns.conf.j2 index f909e34..c9fab41 100644 --- a/roles/powerdns-install/templates/pdns.conf.j2 +++ b/roles/autosecondaries/templates/pdns.conf.j2 @@ -4,7 +4,7 @@ local-port=1053 secondary=yes -autosecondary=no +autosecondary=yes log-dns-details=yes log-dns-queries=yes diff --git a/roles/hidden_primary/filter_plugins/custom_filters.py b/roles/hidden_primary/filter_plugins/custom_filters.py new file mode 100644 index 0000000..322da0e --- /dev/null +++ b/roles/hidden_primary/filter_plugins/custom_filters.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +class FilterModule(object): + def filters(self): + return { + 'axfr_to_list': self.axfr_to_list + } + + def axfr_to_list(self, host_facts): + host_ips = [] + for host in host_facts: + host_ips.append(host['ipv6']) + + return ",".join(host_ips) \ No newline at end of file diff --git a/roles/hidden_primary/tasks/main.yml b/roles/hidden_primary/tasks/main.yml new file mode 100644 index 0000000..f369eb9 --- /dev/null +++ b/roles/hidden_primary/tasks/main.yml @@ -0,0 +1,57 @@ +#- name: Create /etc/apt/keyrings directory +# ansible.builtin.file: +# path: /etc/apt/keyrings +# state: directory +# mode: '0755' +# +#- name: Download PowerDNS Repo Signing Key +# ansible.builtin.get_url: +# url: https://repo.powerdns.com/FD380FBB-pub.asc +# dest: /etc/apt/keyrings/auth-48-pub.asc +# mode: '0644' +# +#- name: Add PowerDNS Repository +# ansible.builtin.apt_repository: +# repo: deb [signed-by=/etc/apt/keyrings/auth-48-pub.asc arch=amd64] http://repo.powerdns.com/debian bookworm-auth-48 main +# state: present +# +#- name: Install PowerDNS +# ansible.builtin.apt: +# pkg: +# - pdns-server +# - pdns-backend-sqlite3 +# state: latest +# update_cache: yes +# register: package_install + +- name: Print groups + ansible.builtin.debug: + var: groups['autosecondaries'] + verbosity: 2 + +- name: Print hostvars + ansible.builtin.debug: + var: hostvars + verbosity: 2 + +- name: Get AXFR IP List + build_axfr_list: + key: ipv6 + group: autosecondaries + hostvars: "{{ hostvars }}" + hosts: "{{ groups['autosecondaries'] }} " + register: axfr_list + +- name: Print return information from the previous task + ansible.builtin.debug: + var: axfr_list + verbosity: 2 + +- name: Configure PowerDNS + ansible.builtin.template: + src: pdns.conf.j2 + dest: /etc/powerdns/pdns.conf + owner: root + group: root + mode: '0640' + register: rsyslog_config \ No newline at end of file diff --git a/roles/hidden_primary/templates/pdns.conf.j2 b/roles/hidden_primary/templates/pdns.conf.j2 new file mode 100644 index 0000000..be8ad57 --- /dev/null +++ b/roles/hidden_primary/templates/pdns.conf.j2 @@ -0,0 +1,13 @@ +launch=gsqlite3 +gsqlite3-database=/var/lib/powerdns/powerdns.db +local-port=36419 + +allow-axfr-ips={{ axfr_list.axfr_list | join(",") }} + +secondary=no +autosecondary=no + +log-dns-details=yes +log-dns-queries=yes +log-timestamp=yes +loglevel=6 \ No newline at end of file diff --git a/roles/hidden_primary/vars/main.yml b/roles/hidden_primary/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/staging.yaml b/staging.yaml index 01871f7..07b7ef5 100644 --- a/staging.yaml +++ b/staging.yaml @@ -1,7 +1,15 @@ -primaries: +autosecondaries: hosts: auth-dns-01.test.lauka-home.net: -dbservers: - hosts: + ipv4: 130.61.98.23 + ipv6: 2603:c020:8008:753:d361:ad83:51fd:3644 auth-dns-02.test.lauka-home.net: - auth-dns-03.test.lauka-home.net: \ No newline at end of file + ipv4: 5.250.191.170 + ipv6: 2001:ba0:217:e400::1 + auth-dns-03.test.lauka-home.net: + ipv4: 194.164.17.227 + ipv6: 2a00:da00:f218:6300::1 +hidden_primary: + hosts: + queer-primary.lauka-home.net: + public_v6: 2a00:da00:f218:6300::1 # TODO \ No newline at end of file