diff --git a/roles/edpm_nftables/files/00-base-rules.yaml b/roles/edpm_nftables/files/00-base-rules.yaml index 20d8311d0..2fc0263e1 100644 --- a/roles/edpm_nftables/files/00-base-rules.yaml +++ b/roles/edpm_nftables/files/00-base-rules.yaml @@ -1,8 +1,10 @@ +--- + - rule: proto: all state: - - RELATED - - ESTABLISHED + - RELATED + - ESTABLISHED rule_name: 000 accept related established rules - rule: ipversion: ipv4 @@ -24,7 +26,7 @@ ipversion: ipv6 proto: udp state: - - NEW + - NEW rule_name: 004 accept ipv6 dhcpv6 - rule: jump: LOG diff --git a/roles/edpm_nftables/tasks/cleanup.yml b/roles/edpm_nftables/tasks/cleanup.yml index 7a76eca99..d5945dd41 100644 --- a/roles/edpm_nftables/tasks/cleanup.yml +++ b/roles/edpm_nftables/tasks/cleanup.yml @@ -4,6 +4,9 @@ block: - name: Empty ruleset ansible.builtin.command: nft flush ruleset + register: nft_flush_ruleset + changed_when: nft_flush_ruleset.rc == 0 + failed_when: nft_flush_ruleset.rc != 0 - name: Remove generated files ansible.builtin.file: diff --git a/roles/edpm_nftables/tasks/configure.yml b/roles/edpm_nftables/tasks/configure.yml index ab4c7878f..a894577a1 100644 --- a/roles/edpm_nftables/tasks/configure.yml +++ b/roles/edpm_nftables/tasks/configure.yml @@ -23,12 +23,13 @@ state: directory owner: root group: root - mode: '0750' + mode: "0750" - name: Push default ruleset snipet ansible.builtin.copy: dest: "{{ edpm_nftables_src }}/edpm-nftables-base.yaml" src: 00-base-rules.yaml + mode: "0644" - name: IPtables compatibility layout become: true @@ -39,16 +40,21 @@ src: iptables.nft owner: root group: root - mode: '0600' + mode: "0600" - name: Load empty ruleset ansible.builtin.command: nft -f /etc/nftables/iptables.nft + register: nft_iptables + changed_when: nft_iptables.rc == 0 + failed_when: nft_iptables.rc != 0 # Get current nft rules in JSON format, with our iptables compat content. - name: Get current nftables content become: true ansible.builtin.command: nft -j list ruleset register: nft_current_rules + changed_when: nft_current_rules.rc == 0 + failed_when: nft_current_rules.rc != 0 - name: Load firewall snippets become: true @@ -56,15 +62,15 @@ edpm_nftables_from_files: src: "{{ edpm_nftables_src }}" -- name: nftables files generation +- name: Generate nftables files become: true when: - - not ansible_check_mode|bool + - not ansible_check_mode block: # Create a dedicated file for jumps - makes easier to manage afterward. # That one will be loaded upon boot only. - name: Generate chain jumps - ignore_errors: "{{ ansible_check_mode|bool }}" + ignore_errors: "{{ ansible_check_mode }}" vars: current_nft: "{{ nft_current_rules }}" nft_is_update: false @@ -75,14 +81,14 @@ src: jump-chain.j2 owner: root group: root - mode: '0600' + mode: "0600" # Create a special "update chain jumps" file, adding just the MISSING # jumps in the main, default chains. This will avoid useless duplication # upon update/day-2 operation, since we cannot really flush INPUT and other # default chains. - name: Generate chain jumps - ignore_errors: "{{ ansible_check_mode|bool }}" + ignore_errors: "{{ ansible_check_mode }}" vars: current_nft: "{{ nft_current_rules }}" nft_is_update: true @@ -93,7 +99,7 @@ src: jump-chain.j2 owner: root group: root - mode: '0600' + mode: "0600" # Note: we do NOT include this one for boot, since chains are # already empty! @@ -107,7 +113,7 @@ src: flush-chain.j2 owner: root group: root - mode: '0600' + mode: "0600" - name: Generate nft edpm chains register: nft_chains @@ -119,7 +125,7 @@ src: chains.j2 owner: root group: root - mode: '0600' + mode: "0600" - name: Generate nft ruleset in static file register: nft_ruleset @@ -131,7 +137,7 @@ src: ruleset.j2 owner: root group: root - mode: '0600' + mode: "0600" - name: Create a sentinel file when nft rules are changed ansible.builtin.file: @@ -139,7 +145,7 @@ state: touch owner: root group: root - mode: '0600' + mode: "0600" when: - nft_ruleset is defined - nft_ruleset is changed @@ -151,13 +157,17 @@ - name: Validate all of the generated content before loading become: true when: - - not ansible_check_mode|bool + - not ansible_check_mode ansible.builtin.shell: >- + set -o pipefail; cat /etc/nftables/edpm-chains.nft /etc/nftables/edpm-flushes.nft /etc/nftables/edpm-rules.nft /etc/nftables/edpm-update-jumps.nft /etc/nftables/edpm-jumps.nft | nft -c -f - + register: nftables_validate + changed_when: nftables_validate.rc == 0 + failed_when: nftables_validate.rc != 0 # Order is important here. # Please keep that in mind in case you want to add some new ruleset in their diff --git a/roles/edpm_nftables/tasks/run.yml b/roles/edpm_nftables/tasks/run.yml index e28332f1e..846e98ac1 100644 --- a/roles/edpm_nftables/tasks/run.yml +++ b/roles/edpm_nftables/tasks/run.yml @@ -17,6 +17,9 @@ - name: Inject our custom chains in nftables become: true ansible.builtin.command: nft -f /etc/nftables/edpm-chains.nft + register: nft_injectrules + changed_when: nft_injectrules.rc == 0 + failed_when: nft_injectrules.rc != 0 # Load all the ruleset in a single transaction. # This prevents accidental lock-outs. @@ -29,13 +32,16 @@ register: nft_ruleset_changed - name: Reload ruleset ansible.builtin.shell: >- + set -o pipefail; cat /etc/nftables/edpm-flushes.nft /etc/nftables/edpm-rules.nft /etc/nftables/edpm-update-jumps.nft | nft -f - when: nft_ruleset_changed.stat.exists + register: nft_reload_ruleset + changed_when: nft_reload_ruleset.rc == 0 + failed_when: nft_reload_ruleset.rc != 0 always: - name: Delete nft_ruleset_changed file ansible.builtin.file: path: /etc/nftables/edpm-rules.nft.changed state: absent - ignore_errors: true diff --git a/roles/edpm_nftables/tasks/service-bootstrap.yml b/roles/edpm_nftables/tasks/service-bootstrap.yml index a65920fcc..2397eed7f 100644 --- a/roles/edpm_nftables/tasks/service-bootstrap.yml +++ b/roles/edpm_nftables/tasks/service-bootstrap.yml @@ -14,23 +14,20 @@ # License for the specific language governing permissions and limitations # under the License. -# systemctl will return 0 if enabled, 3 if disabled -- name: Get nftables service state - ansible.builtin.command: systemctl status nftables - register: nftables_status - failed_when: nftables_status.rc not in [0, 3] +- name: Gather service facts + ansible.builtin.service_facts: - name: Switch firewall engine become: true when: - - nftables_status.rc == 3 + - ansible_facts.services["nftables.service"] is defined + - ansible_facts.services["nftables.service"].status == "disabled" block: - # systemctl will return 0 if success, 1 if unit not found - name: Ensure legacy iptables services are off - ansible.builtin.command: "systemctl disable --now {{ item }}" - register: ipt_service - failed_when: - - ipt_service.rc not in [0, 1] + ansible.builtin.systemd: + name: "{{ item }}" + enabled: false + state: stopped loop: - iptables.service - ip6tables.service @@ -43,3 +40,6 @@ - name: Empty nftables from anything that may lay around ansible.builtin.command: nft flush ruleset + register: nft_flush_ruleset + changed_when: nft_flush_ruleset.rc == 0 + failed_when: nft_flush_ruleset.rc != 0