From 755f9b2e1a5f27a7a87ff81bebe2b748033c920b Mon Sep 17 00:00:00 2001 From: Ruakij Date: Sun, 21 May 2023 20:57:43 +0200 Subject: [PATCH] Initial role --- nftables/defaults/nftables.yml | 29 +++++++++++ nftables/tasks/apply-files.yml | 8 +++ nftables/tasks/deploy-rules/main.yml | 11 ++++ .../deploy-rules/per-group-template-file.yml | 51 +++++++++++++++++++ .../tasks/deploy-rules/per-group-template.yml | 48 +++++++++++++++++ nftables/tasks/install-package.yml | 4 ++ nftables/tasks/main.yml | 7 +++ nftables/tasks/prerequisites.yml | 13 +++++ nftables/tasks/remove-files.yml | 21 ++++++++ nftables/tasks/remove-per-group.yml | 20 ++++++++ nftables/tasks/setup-packages.yml | 15 ++++++ 11 files changed, 227 insertions(+) create mode 100644 nftables/defaults/nftables.yml create mode 100644 nftables/tasks/apply-files.yml create mode 100644 nftables/tasks/deploy-rules/main.yml create mode 100644 nftables/tasks/deploy-rules/per-group-template-file.yml create mode 100644 nftables/tasks/deploy-rules/per-group-template.yml create mode 100644 nftables/tasks/install-package.yml create mode 100644 nftables/tasks/main.yml create mode 100644 nftables/tasks/prerequisites.yml create mode 100644 nftables/tasks/remove-files.yml create mode 100644 nftables/tasks/remove-per-group.yml create mode 100644 nftables/tasks/setup-packages.yml diff --git a/nftables/defaults/nftables.yml b/nftables/defaults/nftables.yml new file mode 100644 index 0000000..ad4c51e --- /dev/null +++ b/nftables/defaults/nftables.yml @@ -0,0 +1,29 @@ +nftables: + # Rules to add + # Handled as templates + # Creates separate files for each entry. + # The identifier is necessary for ansible to be able to merge the keys (when 'hash_behaviour = merge') + # rule-ids have to be unique across files and raw + rules: + # Files with Rules to add + files: + #'': '' + #'': + # main: + # '': '' + + # Rules to add + raw: + #'': '' + #'': + # main: + # '': '' + + # Decides if /etc/nftables.conf is applied or separate files which have changed + # Separate changes require the files to be self-tyding to not end up with duplicate rules + # e.g. + # table ip mytable + # flush table ip mytable + # delete table ip mytable + # table ip mytable {} ... + apply_global: false diff --git a/nftables/tasks/apply-files.yml b/nftables/tasks/apply-files.yml new file mode 100644 index 0000000..b23e4f0 --- /dev/null +++ b/nftables/tasks/apply-files.yml @@ -0,0 +1,8 @@ +- name: Load group rules + command: "nft -f /etc/nftables/ansible-managed/{{ item }}.nft" + loop: "{{ combined_rules | list }}" + when: not nftables.apply_global + +- name: Load global rule file + command: "nft -f /etc/nftables.nft" + when: nftables.apply_global diff --git a/nftables/tasks/deploy-rules/main.yml b/nftables/tasks/deploy-rules/main.yml new file mode 100644 index 0000000..350bd4e --- /dev/null +++ b/nftables/tasks/deploy-rules/main.yml @@ -0,0 +1,11 @@ +- name: Deploying group files + include_tasks: ./per-group-template-file.yml + with_items: + - "{{ nftables.rules.files | list }}" + +- name: Deploying group raw-files + include_tasks: ./per-group-template.yml + with_items: + - "{{ nftables.rules.raw | list }}" + +- include_tasks: ./remove-files.yml diff --git a/nftables/tasks/deploy-rules/per-group-template-file.yml b/nftables/tasks/deploy-rules/per-group-template-file.yml new file mode 100644 index 0000000..26e0da8 --- /dev/null +++ b/nftables/tasks/deploy-rules/per-group-template-file.yml @@ -0,0 +1,51 @@ +- set_fact: + group_identifier: "{{ item }}" + value: "{{ nftables.rules.files[item] }}" + when: "item is defined" + + #'': '' +- block: + - name: Create main rule file + template: + src: "{{ value }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + when: value is string + + #'': + # main: + # '': '' +- block: + - set_fact: + items: "{{ nftables.rules.files[item] }}" + + - block: + - name: Create main rule file + template: + src: "{{ items['main'] }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + + - name: Include rule files + lineinfile: + path: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + regexp: "include\\s+(\"|')\\/etc\\/nftables\\/ansible-managed\\/{{ group_identifier }}\\/.*$" + line: 'include "/etc/nftables/ansible-managed/{{ group_identifier }}/*.nft"' + when: items['main'] is defined + + - name: Create group folder + file: + path: "/etc/nftables/ansible-managed/{{ group_identifier }}/" + state: directory + when: items|length > 0 + + - set_fact: + test: "{{ items | dict2items | selectattr('key', 'ne', 'main') }}" + + - name: Create included rule files + template: + src: "{{ fileItem.value }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}/{{ fileItem.key }}.nft" + loop: "{{ items | dict2items | selectattr('key', 'ne', 'main') }}" + loop_control: + loop_var: fileItem + + when: value is mapping diff --git a/nftables/tasks/deploy-rules/per-group-template.yml b/nftables/tasks/deploy-rules/per-group-template.yml new file mode 100644 index 0000000..4d2f6ea --- /dev/null +++ b/nftables/tasks/deploy-rules/per-group-template.yml @@ -0,0 +1,48 @@ +- set_fact: + group_identifier: "{{ item }}" + value: "{{ nftables.rules.raw[item] }}" + when: "item is defined" + + #'': '' +- block: + - name: Create main rule file + copy: + content: "{{ value }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + when: value is string + + #'': + # main: + # '': '' +- block: + - set_fact: + items: "{{ nftables.rules.raw[item] }}" + + - block: + - name: Create main rule file + copy: + content: "{{ items['main'] }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + + - name: Include rule files + lineinfile: + path: "/etc/nftables/ansible-managed/{{ group_identifier }}.nft" + regexp: "include\\s+(\"|')\\/etc\\/nftables\\/ansible-managed\\/{{ group_identifier }}\\/.*$" + line: 'include "/etc/nftables/ansible-managed/{{ group_identifier }}/*.nft"' + when: items['main'] is defined + + - name: Create group folder + file: + path: "/etc/nftables/ansible-managed/{{ group_identifier }}/" + state: directory + when: items|length > 0 + + - name: Create included rule files + copy: + content: "{{ included_item.value }}" + dest: "/etc/nftables/ansible-managed/{{ group_identifier }}/{{ included_item.key }}.nft" + loop: "{{ items | dict2items | selectattr('key', 'ne', 'main') }}" + loop_control: + loop_var: included_item + + when: value is mapping diff --git a/nftables/tasks/install-package.yml b/nftables/tasks/install-package.yml new file mode 100644 index 0000000..fc088e4 --- /dev/null +++ b/nftables/tasks/install-package.yml @@ -0,0 +1,4 @@ +- name: Install Packages + package: + name: + - nftables diff --git a/nftables/tasks/main.yml b/nftables/tasks/main.yml new file mode 100644 index 0000000..506f4c0 --- /dev/null +++ b/nftables/tasks/main.yml @@ -0,0 +1,7 @@ +- import_tasks: ./prerequisites.yml + +- import_tasks: ./setup-packages.yml + +- import_tasks: ./deploy-rules/main.yml + +- import_tasks: ./apply-files.yml diff --git a/nftables/tasks/prerequisites.yml b/nftables/tasks/prerequisites.yml new file mode 100644 index 0000000..83bd342 --- /dev/null +++ b/nftables/tasks/prerequisites.yml @@ -0,0 +1,13 @@ +# Defaults if missing +- name: Set defaults if missing + set_fact: + nftables: + rules: + files: "{{ nftables.rules.files | default({}) | combine({}) }}" + raw: "{{ nftables.rules.raw | default({}) | combine({}) }}" + combined_rules: "{{ nftables.rules.raw | combine(nftables.rules.files, recursive=true) }}" + +#- name: Check items for consistency +# assert: +# that: "{{ nftables.rules.files.values() | length }} + {{ nftables.rules.raw.values() | length }} == {{ combined_rules.values() | length }}" +# fail_msg: "files and raw rules share the same identifier" diff --git a/nftables/tasks/remove-files.yml b/nftables/tasks/remove-files.yml new file mode 100644 index 0000000..97b3266 --- /dev/null +++ b/nftables/tasks/remove-files.yml @@ -0,0 +1,21 @@ +- name: Handle removed group files + block: + - find: + paths: /etc/nftables/ansible-managed/ + file_type: 'any' + excludes: '{% for item in combined_rules %}{{ item }},{{ item }}.nft,{% endfor %}' + depth: 1 + register: removeFiles + + - file: + path: "{{ fileItem.path }}" + state: absent + loop: "{{ removeFiles.files }}" + loop_control: + label: "{{ fileItem.path }}" + loop_var: fileItem + +- name: Handle removed included files per group + include_tasks: ./remove-per-group.yml + with_items: + - "{{ combined_rules | list }}" diff --git a/nftables/tasks/remove-per-group.yml b/nftables/tasks/remove-per-group.yml new file mode 100644 index 0000000..fcd3aac --- /dev/null +++ b/nftables/tasks/remove-per-group.yml @@ -0,0 +1,20 @@ +- set_fact: + group_identifier: "{{ item }}" + group_items: "{{ combined_rules[item] }}" + +- block: + - find: + paths: "/etc/nftables/ansible-managed/{{ group_identifier }}/" + file_type: 'any' + excludes: '{% for item in group_items %}{{ item }}.nft,{% endfor %}' + register: removeFiles + + - file: + path: "{{ fileItem.path }}" + state: absent + loop: "{{ removeFiles.files }}" + loop_control: + label: "{{ fileItem.path }}" + loop_var: fileItem + + when: group_items is mapping diff --git a/nftables/tasks/setup-packages.yml b/nftables/tasks/setup-packages.yml new file mode 100644 index 0000000..caa80d2 --- /dev/null +++ b/nftables/tasks/setup-packages.yml @@ -0,0 +1,15 @@ +- name: Install nftables + package: + name: + - nftables + +- name: Create /etc/nftables/ansible-managed + file: + path: /etc/nftables/ansible-managed + state: directory + +- name: Include files in /etc/nftables/ansible-managed/ from /etc/nftables.conf + blockinfile: + path: /etc/nftables.conf + marker: "# {mark} ANSIBLE MANAGED BLOCK - nftables" + content: 'include "/etc/nftables/ansible-managed/*.nft"'