From a783baad8d11c1dd7a5807a7c8d55d58107bd0b8 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Thu, 5 Sep 2024 16:48:41 +0200 Subject: [PATCH 01/18] fixed typo in comment --- tasks/unbound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index 61e8e19..b907f66 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -86,7 +86,7 @@ var: configured_unbound_domainoverrides_ip verbosity: 1 -# descr is otional +# descr is optional # FIXME: here the detection is not working in all cases # i.e. if you do not use descr in the first element of the # domainoverrides list From a216c70a810987d7d6549574f14b4e572eaa7fb3 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Tue, 10 Sep 2024 08:08:48 +0200 Subject: [PATCH 02/18] issue #38 - deprecate 'opn_unbound' settings --- tasks/unbound.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index b907f66..961f650 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -3,7 +3,9 @@ # example definition # -# opn_unbound: +# ! opn_unbound is deprecated, please use opn_unboundplus ! +# +# opn_unboundplus: # enable: 1 # forwarding: 1 # active_interface: lan @@ -29,6 +31,11 @@ # # entries apply here # ... +- name: fail if we have a deprecated config + delegate_to: localhost + ansible.builtin.fail: + msg: "found deprectated 'opn_unbound' setting! please use 'opn_unboundplus'!" + when: opn_unbound is defined - name: unbound general settings delegate_to: localhost From 5887afe4d4ccf3d34397741f21a1b6e00f5c50d5 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Tue, 10 Sep 2024 08:27:22 +0200 Subject: [PATCH 03/18] issue #38 - opn_unboundplus general settings --- tasks/unbound.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index 961f650..e94435a 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -6,12 +6,12 @@ # ! opn_unbound is deprecated, please use opn_unboundplus ! # # opn_unboundplus: -# enable: 1 -# forwarding: 1 -# active_interface: lan -# noreglladdr6: 1 -# regdhcp: 1 -# serveexpired: 1 +# general +# enabled: 1 +# port: 53 +# active_interface: lan,wan # default: empty => all +# outgoing_interface: +# local_zone_type: transparent # ... # domainoverrides: # list of domainoverrides dicts # - domain: example.xor @@ -41,14 +41,11 @@ delegate_to: localhost community.general.xml: path: "{{ local_config_path }}" - xpath: /opnsense/unbound/{{ item.key }} + xpath: /opnsense/OPNsense/unboundplus/general/{{ item.key }} value: "{{ item.value }}" pretty_print: true with_dict: - - "{{ opn_unbound | default({}) }}" - when: - - item.key != 'domainoverrides' - - item.key != 'acls' + - "{{ opn_unboundplus.general | default({}) }}" # unbound/domainoverrides From 98e7f90d7e86cd70bd860ad1c81e3b325fad16a2 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Tue, 10 Sep 2024 15:17:41 +0200 Subject: [PATCH 04/18] issue #38 - implemented first unbound tests --- test/test.yml | 1 + test/unbound-test1-expect.xml | 89 +++++++++++++++++++++++++++++++++++ test/unbound-test1.xml | 89 +++++++++++++++++++++++++++++++++++ test/unbound-test1.yml | 6 +++ test/unbound-test2-expect.xml | 89 +++++++++++++++++++++++++++++++++++ test/unbound-test2.xml | 89 +++++++++++++++++++++++++++++++++++ test/unbound-test2.yml | 9 ++++ 7 files changed, 372 insertions(+) create mode 100644 test/unbound-test1-expect.xml create mode 100644 test/unbound-test1.xml create mode 100644 test/unbound-test1.yml create mode 100644 test/unbound-test2-expect.xml create mode 100644 test/unbound-test2.xml create mode 100644 test/unbound-test2.yml diff --git a/test/test.yml b/test/test.yml index 2e8a39b..901f319 100644 --- a/test/test.yml +++ b/test/test.yml @@ -43,6 +43,7 @@ - wireguard - ipsec - dnsserver + - unbound - openvpn when: - test | default(_testtask) == _testtask diff --git a/test/unbound-test1-expect.xml b/test/unbound-test1-expect.xml new file mode 100644 index 0000000..9f5d89e --- /dev/null +++ b/test/unbound-test1-expect.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + lan,wan + + + + + + test.de + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/test/unbound-test1.xml b/test/unbound-test1.xml new file mode 100644 index 0000000..674ddee --- /dev/null +++ b/test/unbound-test1.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + diff --git a/test/unbound-test1.yml b/test/unbound-test1.yml new file mode 100644 index 0000000..3744a2f --- /dev/null +++ b/test/unbound-test1.yml @@ -0,0 +1,6 @@ +--- + +opn_unboundplus: + general: + active_interface: lan,wan + regdhcpdomain: test.de diff --git a/test/unbound-test2-expect.xml b/test/unbound-test2-expect.xml new file mode 100644 index 0000000..39ab76b --- /dev/null +++ b/test/unbound-test2-expect.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/test/unbound-test2.xml b/test/unbound-test2.xml new file mode 100644 index 0000000..2933cba --- /dev/null +++ b/test/unbound-test2.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + lan,wan + + + + + + test.de + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + diff --git a/test/unbound-test2.yml b/test/unbound-test2.yml new file mode 100644 index 0000000..6108ea9 --- /dev/null +++ b/test/unbound-test2.yml @@ -0,0 +1,9 @@ +--- + +# reset VARs + +opn_unboundplus: + general: + active_interface: + regdhcpdomain: + #enabled: 0 From fdf61d2ca1169cd5856402aed34422873bdae8ef Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Tue, 10 Sep 2024 15:18:15 +0200 Subject: [PATCH 05/18] fix for issue 8361 in community.general.xml --- tasks/unbound.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index e94435a..99b36df 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -44,9 +44,24 @@ xpath: /opnsense/OPNsense/unboundplus/general/{{ item.key }} value: "{{ item.value }}" pretty_print: true + register: _unbound_general_settings with_dict: - "{{ opn_unboundplus.general | default({}) }}" +# this is just a hackish fix for the strange empty tag handling in community.general.xml +# https://github.com/ansible-collections/community.general/issues/8361 +- name: ensure all empty tags are shortened + delegate_to: localhost + community.general.xml: + path: "{{ local_config_path }}" + xpath: /opnsense/OPNsense/unboundplus/general/fixemptytag + value: community.general.xml is strange + state: "{{ item }}" + with_items: + - present + - absent + when: _unbound_general_settings is changed + # unbound/domainoverrides - name: count unbound/domainoverrides From 44747bae75740b0456f97c8aa2e475f4a210ff01 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Tue, 10 Sep 2024 15:32:13 +0200 Subject: [PATCH 06/18] issue #38 - make lint happy --- tasks/unbound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index 99b36df..fc96f5b 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -50,7 +50,7 @@ # this is just a hackish fix for the strange empty tag handling in community.general.xml # https://github.com/ansible-collections/community.general/issues/8361 -- name: ensure all empty tags are shortened +- name: ensure all empty tags are shortened # noqa no-handler delegate_to: localhost community.general.xml: path: "{{ local_config_path }}" From 0f75966dc6c63741edd0bb614b29dedff864cf9b Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 17:22:56 +0200 Subject: [PATCH 07/18] task #38 - configure unboundplus uuid subsections --- defaults/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/defaults/main.yml b/defaults/main.yml index 0f7a097..232b51d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -36,4 +36,10 @@ opn_openvpn_overwrites_defaults: push_reset: 0 register_dns: 0 +opn_unboundplus_uuid_sections: + dots: dot + hosts: host + aliases: alias + domains: domain + ... From 809e41540304a14e7f867782b7772978467dd888 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 17:26:18 +0200 Subject: [PATCH 08/18] task #38 - generic unboundplus cfg with sections and uuid-subsections --- tasks/unbound.yml | 232 ++++---------------------------------- tasks/unboundplus.yml | 43 ++++--- tasks/unboundplusuuid.yml | 14 +++ 3 files changed, 56 insertions(+), 233 deletions(-) create mode 100644 tasks/unboundplusuuid.yml diff --git a/tasks/unbound.yml b/tasks/unbound.yml index fc96f5b..b7a8de0 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -12,24 +12,20 @@ # active_interface: lan,wan # default: empty => all # outgoing_interface: # local_zone_type: transparent +# hosts: +# 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad: # uuid +# enabled: 1 +# hostname: "*" +# domain: test.de +# rr: A +# mxprio: +# mx: +# server: 10.11.12.13 +# description: test de +# aliases: # ... -# domainoverrides: # list of domainoverrides dicts -# - domain: example.xor -# ip: 127.0..1.1 -# descr: xtra domain # descr is optional, but in order to work as expected -# # please do yourself a favor and be consistent and use -# # either in all entries or none of them -# ... -# acls: # list of acl dicts -# - aclname: dnsaclx # !!! please use uniq names !!! -# aclaction: allow -# description: dns acl for xtra -# rows: -# - acl_network: 172.0.0.0 -# mask: 24 -# description: this network # same restrictions as for domainoverrides descr -# # entries apply here -# ... +# +# see tests/unbound*.yml for more examples - name: fail if we have a deprecated config delegate_to: localhost @@ -37,16 +33,15 @@ msg: "found deprectated 'opn_unbound' setting! please use 'opn_unboundplus'!" when: opn_unbound is defined -- name: unbound general settings - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/OPNsense/unboundplus/general/{{ item.key }} - value: "{{ item.value }}" - pretty_print: true - register: _unbound_general_settings - with_dict: - - "{{ opn_unboundplus.general | default({}) }}" +- name: unboundplus + ansible.builtin.include_tasks: unboundplus.yml + vars: + unboundplussection: "{{ _opnunbndsettings.key }}" + unboundplussectionsettings: "{{ _opnunbndsettings.value }}" + when: opn_unboundplus is defined + with_dict: "{{ opn_unboundplus }}" + loop_control: + loop_var: _opnunbndsettings # this is just a hackish fix for the strange empty tag handling in community.general.xml # https://github.com/ansible-collections/community.general/issues/8361 @@ -60,187 +55,6 @@ with_items: - present - absent - when: _unbound_general_settings is changed - -# unbound/domainoverrides - -- name: count unbound/domainoverrides - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/domain - count: true - register: configured_unbound_domainoverrides_count - -- name: debug configured_unbound_domainoverrides_count - ansible.builtin.debug: - var: configured_unbound_domainoverrides_count - verbosity: 1 - -- name: get unbound/domainoverrides/domain entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/domain - content: "text" - register: configured_unbound_domainoverrides_domain - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides_domain - ansible.builtin.debug: - var: configured_unbound_domainoverrides_domain - verbosity: 1 - -- name: get unbound/domainoverrides/ip entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/ip - content: "text" - register: configured_unbound_domainoverrides_ip - when: configured_unbound_domainoverrides_count.count > 0 - -- name: denug configured_unbound_domainoverrides_ip - ansible.builtin.debug: - var: configured_unbound_domainoverrides_ip - verbosity: 1 - -# descr is optional -# FIXME: here the detection is not working in all cases -# i.e. if you do not use descr in the first element of the -# domainoverrides list -- name: get unbound/domainoverrides/descr entries - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides/descr - content: "text" - ignore_errors: true - register: configured_unbound_domainoverrides_descr - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides_descr - ansible.builtin.debug: - var: configured_unbound_domainoverrides_descr|default([]) - verbosity: 1 - -- name: init configured_unbound_domainoverrides - ansible.builtin.set_fact: - configured_unbound_domainoverrides: [] - -- name: populate configured_unbound_domainoverrides - ansible.builtin.set_fact: - configured_unbound_domainoverrides: "[ - {% for domaindict in configured_unbound_domainoverrides_domain.matches %} - { - 'domain':'{{ domaindict.domain }}', - 'ip':'{{ configured_unbound_domainoverrides_ip.matches[loop.index0].ip }}' - {% if configured_unbound_domainoverrides_descr.matches[loop.index0].descr is defined - and configured_unbound_domainoverrides_descr.matches[loop.index0].descr %} - ,'descr':'{{ configured_unbound_domainoverrides_descr.matches[loop.index0].descr }}' - {% endif %} - }, - {% endfor %} - ]" - when: configured_unbound_domainoverrides_count.count > 0 - -- name: debug configured_unbound_domainoverrides - ansible.builtin.debug: - var: configured_unbound_domainoverrides - verbosity: 1 -- name: debug opn_unbound.domainoverrides - ansible.builtin.debug: - var: opn_unbound.domainoverrides|default([]) - verbosity: 1 - -- name: compare configured and defined unbound domainoverrides - ansible.builtin.set_fact: - unbound_domainoverrides_delta: "{{ configured_unbound_domainoverrides | symmetric_difference(opn_unbound.domainoverrides | default([])) }}" -- name: debug delta between configured and defined unbound domainoverrides - ansible.builtin.debug: - var: unbound_domainoverrides_delta - verbosity: 1 -- name: check if a update of unbound domainoverrides is required - ansible.builtin.set_fact: - unbound_domainoverrides_update: true - when: unbound_domainoverrides_delta | length > 0 - -# opnsense uses one or more domainoverrides entries for one forward-zone -# in unbound multiple entries for the same zone are merged into one forward-zone -# with multiple forward-addr entries -# so here we just have one chance: remove all domainoverrides and recreate them in a bulk -- name: unbound domainoverrides - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound/domainoverrides - state: absent - pretty_print: true - when: unbound_domainoverrides_update | default(False) - -- name: unbound domainoverrides # noqa jinja[spacing] - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: /opnsense/unbound - add_children: "[ - {% for domainoverrides in opn_unbound.domainoverrides -%} - ' - {% for k, v in domainoverrides.items() | list -%} - <{{ k }}>{{ v }} - {%- endfor %} - ', - {%- endfor %} - ]" - input_type: xml - pretty_print: true - when: - - opn_unbound.domainoverrides is defined - - unbound_domainoverrides_update | default(False) - -# END unbound/domainoverrides - -# unbound/acls -# assumes uniq names and doesn't clean up undefined ACLs -# in order to remove stuff from the xml, use opn_unset - -- name: unbound acls aclaction - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ item.aclname }}']/aclaction" - value: "{{ item.aclaction }}" - pretty_print: true - with_items: - - "{{ opn_unbound.acls | default([]) }}" - -- name: unbound acls description - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ item.aclname }}']/description" - value: "{{ item.description }}" - pretty_print: true - with_items: - - "{{ opn_unbound.acls | default([]) }}" - when: item.description is defined - -# Invalid variable name in 'register' specified: 'configured_unbound_acls_rows_count['{{ item.0.aclname }}']' -# FIXME use block with_items and nested loop in block - -- name: unbound acls rows - ansible.builtin.include_tasks: unboundaclsrows.yml - vars: - aclname: "{{ item.aclname }}" - rows: "{{ item.rows }}" - when: item.rows is defined - with_items: - - "{{ opn_unbound.acls | default([]) }}" - -# END unbound/acls - -- name: unboundplus - ansible.builtin.include_tasks: unboundplus.yml - when: opn_unboundplus is defined + when: _unbound_settings is changed or _unbound_settings_uuid is changed ... diff --git a/tasks/unboundplus.yml b/tasks/unboundplus.yml index 5447077..de5f856 100644 --- a/tasks/unboundplus.yml +++ b/tasks/unboundplus.yml @@ -1,36 +1,31 @@ # vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 smartindent nu ft=yaml --- -# example definition: -# -# opn_unboundplus: -# dnsbl: -# enabled: 1 -# type: "aa,ag,bla0,bla" -# whitelists: "*.example.com,*.another.xyz" -# dots: DNSoverTLS is NOT YET IMPLEMENTED! -# miscellaneous: -# privatedomain: "..." -# insecuredomain: "..." +# handle different unboundlus sections -- name: unboundplus dnsbl +- name: unboundplus settings {{ unboundplussection }} delegate_to: localhost community.general.xml: path: "{{ local_config_path }}" - xpath: "/opnsense/OPNsense/unboundplus/dnsbl/{{ item.key }}" + xpath: "/opnsense/OPNsense/unboundplus/{{ unboundplussection }}/{{ item.key }}" value: "{{ item.value }}" pretty_print: true - with_dict: "{{ opn_unboundplus.dnsbl }}" - when: opn_unboundplus.dnsbl is defined + register: _unbound_settings + with_dict: "{{ unboundplussectionsettings }}" + when: + - unboundplussectionsettings is defined + - unboundplussection not in opn_unboundplus_uuid_sections.keys() -- name: unboundplus miscellaneous - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/OPNsense/unboundplus/miscellaneous/{{ item.key }}" - value: "{{ item.value }}" - pretty_print: true - with_dict: "{{ opn_unboundplus.miscellaneous }}" - when: opn_unboundplus.miscellaneous is defined +- name: unboundplus uuid settings for {{ unboundplussection }} + ansible.builtin.include_tasks: unboundplusuuid.yml + vars: + _uuid: "{{ _opnunbndsettingsuuid.key }}" + _uuidvalues: "{{ _opnunbndsettingsuuid.value }}" + with_dict: "{{ unboundplussectionsettings }}" + loop_control: + loop_var: _opnunbndsettingsuuid + when: + - unboundplussectionsettings is defined + - unboundplussection in opn_unboundplus_uuid_sections.keys() ... diff --git a/tasks/unboundplusuuid.yml b/tasks/unboundplusuuid.yml new file mode 100644 index 0000000..8fab5bc --- /dev/null +++ b/tasks/unboundplusuuid.yml @@ -0,0 +1,14 @@ +--- + +- name: unboundplus settings {{ unboundplussection }} + delegate_to: localhost + community.general.xml: + path: "{{ local_config_path }}" + xpath: "/opnsense/OPNsense/unboundplus/{{ unboundplussection }}/{{ opn_unboundplus_uuid_sections[unboundplussection] }}[@uuid='{{ _uuid }}']/{{ item.key }}" + value: "{{ item.value }}" + pretty_print: true + register: _unbound_settings_uuid + with_dict: "{{ _uuidvalues }}" + + +... From 0c3e93af66cb0620951d19f6e76ada795c0a79b2 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 17:27:28 +0200 Subject: [PATCH 09/18] task #38 - test unboundplus overrides and forwarding --- test/unbound-test-overrides-expect.xml | 149 +++++++++++++++++++++++++ test/unbound-test-overrides.xml | 89 +++++++++++++++ test/unbound-test-overrides.yml | 61 ++++++++++ 3 files changed, 299 insertions(+) create mode 100644 test/unbound-test-overrides-expect.xml create mode 100644 test/unbound-test-overrides.xml create mode 100644 test/unbound-test-overrides.yml diff --git a/test/unbound-test-overrides-expect.xml b/test/unbound-test-overrides-expect.xml new file mode 100644 index 0000000..1096a28 --- /dev/null +++ b/test/unbound-test-overrides-expect.xml @@ -0,0 +1,149 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + 1 + + + + 1 + forward + fck.fascists.org + 6.6.6.6 + 53 + + + + + + 1 + * + test.de + A + + + 10.11.12.13 + test de + + + 1 + pudding + toast.it + A + + + 10.1.2.3 + toast it + + + + + 1 + 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad + cloud + nosense.org + no sense cloud + + + 1 + 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad + mail + nosense.org + no sense mail service + + + 1 + 87c2cf23-aece-4c66-9ae4-171b9c7aa964 + pudding + tick.tack + pudding time + + + + + 0 + pudding.time + 10.0.0.1 + 0 + pudding time dom fwd + + + + + \ No newline at end of file diff --git a/test/unbound-test-overrides.xml b/test/unbound-test-overrides.xml new file mode 100644 index 0000000..674ddee --- /dev/null +++ b/test/unbound-test-overrides.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + diff --git a/test/unbound-test-overrides.yml b/test/unbound-test-overrides.yml new file mode 100644 index 0000000..5c8dc6e --- /dev/null +++ b/test/unbound-test-overrides.yml @@ -0,0 +1,61 @@ +--- + +opn_unboundplus: + general: + enabled: 1 + forwarding: + enabled: 1 + dots: + 06ee6261-e787-4434-8fac-b8a5d5412243: + enabled: 1 + type: forward + domain: fck.fascists.org + server: 6.6.6.6 + port: 53 + verify: + hosts: + "04ac0d40-ecd0-4a1c-8603-91ce9aed08ad": + enabled: 1 + hostname: "*" + domain: test.de + rr: A + mxprio: + mx: + server: 10.11.12.13 + description: test de + "87c2cf23-aece-4c66-9ae4-171b9c7aa964": + enabled: 1 + hostname: pudding + domain: toast.it + rr: A + mxprio: + mx: + server: 10.1.2.3 + description: toast it + aliases: + "50621c24-479b-4dae-97b6-ae35b285136a": + enabled: 1 + host: 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad + hostname: cloud + domain: nosense.org + description: no sense cloud + "9535a83c-7bbc-4cd1-ad67-f775ca23000a": + enabled: 1 + host: 04ac0d40-ecd0-4a1c-8603-91ce9aed08ad + hostname: mail + domain: nosense.org + description: no sense mail service + "44a62f0c-9a0e-4890-9c03-c314573ee713": + enabled: 1 + host: 87c2cf23-aece-4c66-9ae4-171b9c7aa964 + hostname: pudding + domain: tick.tack + description: pudding time + domains: + 848c33e3-7541-45e6-8c96-4507489ff978: + enabled: 0 + domain: pudding.time + server: 10.0.0.1 + forward_tcp_upstream: 0 + description: pudding time dom fwd + From 2a2374cbdd24bc2d713a104d0998a9aeaaf0909f Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 21:08:56 +0200 Subject: [PATCH 10/18] issue #38 - add acl to opn_unboundplus_uuid_sections --- defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/defaults/main.yml b/defaults/main.yml index 232b51d..b1962f4 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -41,5 +41,6 @@ opn_unboundplus_uuid_sections: hosts: host aliases: alias domains: domain + acls: acl ... From d40bc4bde41bf924710719653ee0e15186e0e167 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 21:10:10 +0200 Subject: [PATCH 11/18] issue #38 - allow generic mixing of flat key:value elements and uuid sub-sections in opn_unboundplus_uuid_sections --- tasks/unboundplus.yml | 3 ++- tasks/unboundplusuuid.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tasks/unboundplus.yml b/tasks/unboundplus.yml index de5f856..83632f3 100644 --- a/tasks/unboundplus.yml +++ b/tasks/unboundplus.yml @@ -14,7 +14,7 @@ with_dict: "{{ unboundplussectionsettings }}" when: - unboundplussectionsettings is defined - - unboundplussection not in opn_unboundplus_uuid_sections.keys() + - unboundplussection not in opn_unboundplus_uuid_sections.keys() or item.value is string - name: unboundplus uuid settings for {{ unboundplussection }} ansible.builtin.include_tasks: unboundplusuuid.yml @@ -27,5 +27,6 @@ when: - unboundplussectionsettings is defined - unboundplussection in opn_unboundplus_uuid_sections.keys() + - _opnunbndsettingsuuid.value is not string ... diff --git a/tasks/unboundplusuuid.yml b/tasks/unboundplusuuid.yml index 8fab5bc..9dabb5c 100644 --- a/tasks/unboundplusuuid.yml +++ b/tasks/unboundplusuuid.yml @@ -1,6 +1,6 @@ --- -- name: unboundplus settings {{ unboundplussection }} +- name: unboundplus settings {{ unboundplussection }} uuid {{ _uuid }} delegate_to: localhost community.general.xml: path: "{{ local_config_path }}" From 6ef6803c11b8a2a87c8ee44355072ca336df276e Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 21:10:44 +0200 Subject: [PATCH 12/18] issue #38 - unboundplus acl and dnsbl test --- test/unbound-test-acl-expect.xml | 103 +++++++++++++++++++++++++++++++ test/unbound-test-acl.xml | 89 ++++++++++++++++++++++++++ test/unbound-test-acl.yml | 28 +++++++++ 3 files changed, 220 insertions(+) create mode 100644 test/unbound-test-acl-expect.xml create mode 100644 test/unbound-test-acl.xml create mode 100644 test/unbound-test-acl.yml diff --git a/test/unbound-test-acl-expect.xml b/test/unbound-test-acl-expect.xml new file mode 100644 index 0000000..808e6fa --- /dev/null +++ b/test/unbound-test-acl-expect.xml @@ -0,0 +1,103 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + deny + + 0 + block the bad + deny + 8.8.8.8/32,1.1.1.1/32 + do not allow dns queries from 666 + + + 1 + the good son + allow + 192.168.0.0/20,10.0.0.0/12 + not the wayward son + + + + 1 + 0 + atf,bla0,blm,blp,blr + + rozarobota.org,esterwajcblum.org + goo.gl,google.com + microsoft.com,mcs.com +
+ 0 + + + + + + + + + + + \ No newline at end of file diff --git a/test/unbound-test-acl.xml b/test/unbound-test-acl.xml new file mode 100644 index 0000000..674ddee --- /dev/null +++ b/test/unbound-test-acl.xml @@ -0,0 +1,89 @@ + + + + + + + + 1 + 53 + + + + + + + + + + + + + + transparent + + + + + + + + + + 1 + + + + + + + + + + + + + 1 + 0 + + 0.0.0.0/8,10.0.0.0/8,100.64.0.0/10,169.254.0.0/16,172.16.0.0/12,192.0.2.0/24,192.168.0.0/16,198.18.0.0/15,198.51.100.0/24,203.0.113.0/24,233.252.0.0/24,::1/128,2001:db8::/32,fc00::/8,fd00::/8,fe80::/10 + + + + + + + + + + + + + + + + + + allow + + + 0 + + + + + + +
+ + + + + + + + + + + + diff --git a/test/unbound-test-acl.yml b/test/unbound-test-acl.yml new file mode 100644 index 0000000..2431117 --- /dev/null +++ b/test/unbound-test-acl.yml @@ -0,0 +1,28 @@ +--- + +opn_unboundplus: + acls: + default_action: deny + "195c3a6f-1307-4cf5-bec3-009cf956457d": + enabled: 0 + name: block the bad + action: deny + networks: 8.8.8.8/32,1.1.1.1/32 + description: do not allow dns queries from 666 + "72b8f6c5-780b-4d32-83f0-b51e84bd194b": + enabled: 1 + name: the good son + action: allow + networks: 192.168.0.0/20,10.0.0.0/12 + description: not the wayward son + dnsbl: + enabled: 1 + safesearch: 0 + type: atf,bla0,blm,blp,blr + lists: + whitelists: rozarobota.org,esterwajcblum.org + blocklists: goo.gl,google.com + wildcards: microsoft.com,mcs.com + address: + nxdomain: 0 + From cef6ed265c4d8fbd702c1ce799f52d096b1444a6 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 21:50:07 +0200 Subject: [PATCH 13/18] tests - optional running just one single test file --- test/Readme.md | 4 ++++ test/testsimpletask.yml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/Readme.md b/test/Readme.md index 33a76fa..eb2f540 100644 --- a/test/Readme.md +++ b/test/Readme.md @@ -18,6 +18,10 @@ A check consists of: `ansible-playbook -e test=filter test.yml` +### run test for just a task and one test-file + +`ansible-playbook -e test=unbound -e testfile=unbound-test-acl.yml -D test.yml` + ## Notes This is work in progress ... diff --git a/test/testsimpletask.yml b/test/testsimpletask.yml index ba1db87..720d3ed 100644 --- a/test/testsimpletask.yml +++ b/test/testsimpletask.yml @@ -7,7 +7,7 @@ - name: register tasks to run for {{ _testtask }} ansible.builtin.set_fact: - _taskfiles: "{{ query('ansible.builtin.fileglob', _testtask ~ '-test*.yml') | sort }}" + _taskfiles: "{{ query('ansible.builtin.fileglob', testfile | default(_testtask ~ '-test*.yml')) | sort }}" - name: "{{ _testtask }} test loop ..." ansible.builtin.include_tasks: testsimpletaskgeneric.yml From 55f3ce0f8d7ed2a649d206513320062f659665ab Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Wed, 11 Sep 2024 22:05:20 +0200 Subject: [PATCH 14/18] issue #38 - unboundplus handler --- handlers/main.yml | 35 +++++++++++++++++++++++++++++++++++ tasks/unboundplus.yml | 1 + tasks/unboundplusuuid.yml | 1 + test/test.yml | 6 ++++++ 4 files changed, 43 insertions(+) diff --git a/handlers/main.yml b/handlers/main.yml index 47da8fb..f5ce2af 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -50,6 +50,41 @@ - config is defined - config.changed | bool +# unbound +- name: reconfig unbound # noqa no-changed-when + ansible.builtin.command: configctl 'template reload OPNsense/Unbound/' + listen: + - reconfig unbound + - update dnsbl + when: + - config is defined + - config.changed | bool + +- name: update dnsbl # noqa no-changed-when + ansible.builtin.command: configctl unbound dnsbl + listen: + - update dnsbl + notify: reconfig unbound + when: + - config is defined + - config.changed | bool + +- name: reload dns # noqa no-changed-when + ansible.builtin.command: configctl dns reload + listen: + - reconfig unbound + when: + - config is defined + - config.changed | bool + +- name: restart unbound # noqa no-changed-when + ansible.builtin.command: configctl unbound restart + listen: + - reconfig unbound + when: + - config is defined + - config.changed | bool + # openvpn - name: configure openvpn instances # noqa no-changed-when ansible.builtin.command: configctl openvpn configure diff --git a/tasks/unboundplus.yml b/tasks/unboundplus.yml index 83632f3..d2b1e27 100644 --- a/tasks/unboundplus.yml +++ b/tasks/unboundplus.yml @@ -11,6 +11,7 @@ value: "{{ item.value }}" pretty_print: true register: _unbound_settings + notify: "{{ (unboundplussection == 'dnsbl') | ternary('update dnsbl', 'reconfig unbound') }}" with_dict: "{{ unboundplussectionsettings }}" when: - unboundplussectionsettings is defined diff --git a/tasks/unboundplusuuid.yml b/tasks/unboundplusuuid.yml index 9dabb5c..e15bf99 100644 --- a/tasks/unboundplusuuid.yml +++ b/tasks/unboundplusuuid.yml @@ -8,6 +8,7 @@ value: "{{ item.value }}" pretty_print: true register: _unbound_settings_uuid + notify: reconfig unbound with_dict: "{{ _uuidvalues }}" diff --git a/test/test.yml b/test/test.yml index 901f319..502bd27 100644 --- a/test/test.yml +++ b/test/test.yml @@ -26,6 +26,12 @@ - name: stop ipsec # TODO: test this action; use community.general.xml and add a tag to the resulting xml debug: msg: fake handler - stop ipsec + - name: reconfig unbound + debug: + msg: fake handler - reconfig unbound + - name: update dnsbl + debug: + msg: fake handler - update dnsbl tasks: - name: include default vars ansible.builtin.include_vars: From e8966ac1d98c9cfdb8a2806a7ce25aef531a6f17 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Thu, 12 Sep 2024 07:41:15 +0200 Subject: [PATCH 15/18] issue #38 - deleted old obsoleted task file 'unboundaclsrows' --- tasks/unboundaclsrows.yml | 127 -------------------------------------- 1 file changed, 127 deletions(-) delete mode 100644 tasks/unboundaclsrows.yml diff --git a/tasks/unboundaclsrows.yml b/tasks/unboundaclsrows.yml deleted file mode 100644 index 5c43636..0000000 --- a/tasks/unboundaclsrows.yml +++ /dev/null @@ -1,127 +0,0 @@ -# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2 smartindent nu ft=yaml ---- - -# required as ansible is not able to loop blocks - -- name: "count unbound acl {{ aclname }} rows" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']/row" - count: true - register: configured_unbound_acls_rows_count -- name: "debug configured_unbound_acls_rows_count for {{ aclname }}" - ansible.builtin.debug: - var: configured_unbound_acls_rows_count - verbosity: 1 - -- name: "get unbound acl {{ aclname }} row acl_network entries" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']/row/acl_network" - content: "text" - register: configured_unbound_acls_acl_network - when: configured_unbound_acls_rows_count.count > 0 -- name: "debug configured_unbound_acls_acl_network for {{ aclname }}" - ansible.builtin.debug: - var: configured_unbound_acls_acl_network - verbosity: 1 - -- name: "get unbound acl {{ aclname }} row mask entries" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']/row/mask" - content: "text" - register: configured_unbound_acls_mask - when: configured_unbound_acls_rows_count.count > 0 -- name: "debug configured_unbound_acls_mask for {{ aclname }}" - ansible.builtin.debug: - var: configured_unbound_acls_mask - verbosity: 1 - -# description is optional -# FIXME: here the detection is not working in all cases -# i.e. if you do not use descr in the first row element -- name: "get unbound acl {{ aclname }} row description entries" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']/row/description" - content: "text" - register: configured_unbound_acls_description - when: configured_unbound_acls_rows_count.count > 0 -- name: "debug configured_unbound_acls_description for {{ aclname }}" - ansible.builtin.debug: - var: configured_unbound_acls_description - verbosity: 1 - -- name: "init configured_unbound_acls for {{ aclname }}" - ansible.builtin.set_fact: - configured_unbound_acls: [] - -- name: "populate configured_unbound_acls for {{ aclname }}" - ansible.builtin.set_fact: - configured_unbound_acls: "[ - {% for acldict in configured_unbound_acls_acl_network.matches %} - { - 'acl_network':'{{ acldict.acl_network }}', - 'mask':{{ configured_unbound_acls_mask.matches[loop.index0].mask }} - {% if configured_unbound_acls_description.matches[loop.index0].description is defined - and configured_unbound_acls_description.matches[loop.index0].description %} - ,'description':'{{ configured_unbound_acls_description.matches[loop.index0].description }}' - {% endif %} - }, - {% endfor %} - ]" - when: configured_unbound_acls_rows_count.count > 0 - -- name: "debug configured_unbound_acls for {{ aclname }}" - ansible.builtin.debug: - var: configured_unbound_acls - verbosity: 1 -- name: "debug acl rows for {{ aclname }}" - ansible.builtin.debug: - var: rows - verbosity: 1 - -- name: "compare configured and defined acl rows for {{ aclname }}" - ansible.builtin.set_fact: - unbound_acls_delta: "{{ configured_unbound_acls | symmetric_difference(rows | default([])) }}" -- name: "debug unbound_acls_delta for {{ aclname }}" - ansible.builtin.debug: - var: unbound_acls_delta - verbosity: 1 - -- name: "check if a update of acl rows for {{ aclname }} is required" - ansible.builtin.set_fact: - unbound_acls_update: true - when: unbound_acls_delta | length > 0 - -- name: "clean up acl rows for {{ aclname }}" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']/row" - state: absent - pretty_print: true - when: unbound_acls_update | default(False) - -- name: "debug acl rows for {{ aclname }}" - ansible.builtin.debug: - msg: "xml add_children: [ {% for row in rows -%}'{% for k, v in row.items() | list -%}<{{ k }}>{{ v }}{%- endfor %}',{%- endfor %} ]" - verbosity: 1 -- name: "set acl rows for {{ aclname }}" - delegate_to: localhost - community.general.xml: - path: "{{ local_config_path }}" - xpath: "/opnsense/unbound/acls[aclname/text()='{{ aclname }}']" - add_children: "[ {% for row in rows -%}'{% for k, v in row.items() | list -%}<{{ k }}>{{ v }}{%- endfor %}',{%- endfor %} ]" - input_type: xml - pretty_print: true - when: - - unbound_acls_update | default(False) - - rows is defined - -... From 85142218799579de293647343c19c7cb3f83a416 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Thu, 12 Sep 2024 07:47:16 +0200 Subject: [PATCH 16/18] issue #38 - clean up old '/opnsense/unbound' tag --- tasks/unbound.yml | 7 +++++++ test/unbound-test1.xml | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index b7a8de0..d1c1b7f 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -33,6 +33,13 @@ msg: "found deprectated 'opn_unbound' setting! please use 'opn_unboundplus'!" when: opn_unbound is defined +- name: clean upold unbound tag + delegate_to: localhost + community.general.xml: + path: "{{ local_config_path }}" + xpath: /opnsense/unbound + state: absent + - name: unboundplus ansible.builtin.include_tasks: unboundplus.yml vars: diff --git a/test/unbound-test1.xml b/test/unbound-test1.xml index 674ddee..80ab3fd 100644 --- a/test/unbound-test1.xml +++ b/test/unbound-test1.xml @@ -86,4 +86,32 @@ + + 1 + 0 + lan + lan + 1 + 1 + 1 + 1 + 10 + 10000 + 900 + 200 + 1 + 4 + 4096 + 10 + + nsf + allow + ns front + + 10.3.2.0 + 28 + srv front DNS + + + From c34139fd9fcdea9a13e785a8fac23bf117748262 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Thu, 12 Sep 2024 07:55:41 +0200 Subject: [PATCH 17/18] issue #38 - document unset of subsections entries using uuid --- tasks/unbound.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index d1c1b7f..3e984ee 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -26,6 +26,10 @@ # ... # # see tests/unbound*.yml for more examples +# +# to unset a acl, host, etc. subsection, use opn_unset, for example +# opn_unset: +# - /opnsense/OPNsense/unboundplus/hosts/host[@uuid='04ac0d40-ecd0-4a1c-8603-91ce9aed08ad'] - name: fail if we have a deprecated config delegate_to: localhost From 1415616de29fc62a7aa12986fd7e5423dfa3a5e8 Mon Sep 17 00:00:00 2001 From: Klaus Zerwes Date: Thu, 12 Sep 2024 14:55:21 +0200 Subject: [PATCH 18/18] fixed typo --- tasks/unbound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/unbound.yml b/tasks/unbound.yml index 3e984ee..4c032a2 100644 --- a/tasks/unbound.yml +++ b/tasks/unbound.yml @@ -37,7 +37,7 @@ msg: "found deprectated 'opn_unbound' setting! please use 'opn_unboundplus'!" when: opn_unbound is defined -- name: clean upold unbound tag +- name: clean up old unbound tag delegate_to: localhost community.general.xml: path: "{{ local_config_path }}"