From b006196cc5b63fcbc98d36d71bf66822ce23d575 Mon Sep 17 00:00:00 2001 From: sjat Date: Sat, 6 Jun 2026 19:06:39 +0200 Subject: [PATCH] fix(base): confirm firewall apply over a FRESH connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit established/related keeps the in-flight session alive across the swap, so the prior 'next task runs' confirm always passed even if new connections were bricked — the rollback was theater. reset_connection + wait_for_connection now force a fresh handshake through the new ruleset; failure aborts the play and the armed timer reverts. (meta: reset_connection ignores 'when' — benign extra reconnect on no-op runs; verified idempotent in molecule.) --- roles/base/defaults/main.yml | 1 + roles/base/tasks/firewall.yml | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/roles/base/defaults/main.yml b/roles/base/defaults/main.yml index 0fdb354..9cebece 100644 --- a/roles/base/defaults/main.yml +++ b/roles/base/defaults/main.yml @@ -4,5 +4,6 @@ base__firewall_mgmt_interface: wt0 # SSH accepted only on this iface (NetBird, ADR-016) base__firewall_ssh_port: 22 base__firewall_rollback_timeout: 45 # seconds before the auto-revert fires on a bad apply +base__firewall_confirm_timeout: 20 # seconds to re-establish a fresh connection post-apply base__firewall_dropin_dir: /etc/nftables.d base__firewall_apply: true # set false to render+validate without applying (CI/Molecule) diff --git a/roles/base/tasks/firewall.yml b/roles/base/tasks/firewall.yml index dc8b2d0..0045e61 100644 --- a/roles/base/tasks/firewall.yml +++ b/roles/base/tasks/firewall.yml @@ -68,6 +68,13 @@ ansible.builtin.command: nft -f /etc/nftables.conf changed_when: true + - name: Drop the persistent connection so the confirm uses a fresh one + ansible.builtin.meta: reset_connection + + - name: Confirm a NEW connection survives the applied ruleset + ansible.builtin.wait_for_connection: + timeout: "{{ base__firewall_confirm_timeout }}" + - name: Stop the rollback timer after connectivity confirmed ansible.builtin.systemd: name: "{{ item }}"