diff --git a/roles/prereq/tasks/main.yml b/roles/prereq/tasks/main.yml index cf167172..57c9e8e9 100644 --- a/roles/prereq/tasks/main.yml +++ b/roles/prereq/tasks/main.yml @@ -32,7 +32,7 @@ reload: true when: ansible_facts['all_ipv6_addresses'] | length > 0 -- name: Handle modern nftables/iptables-nft stack (Arch Linux ARM 6.18+) +- name: Handle modern nftables/iptables-nft stack (Arch Linux 6.18+) when: - ansible_facts['distribution'] == 'Archlinux' - ansible_facts['kernel'] is version('6.18', '>=') @@ -48,7 +48,6 @@ force: true when: - "'iptables' in ansible_facts.packages" - - "'iptables-nft' not in ansible_facts.packages" - name: Install iptables-nft and nftables community.general.pacman: @@ -57,11 +56,37 @@ - nftables state: present - - name: Ensure nftables is enabled and started - ansible.builtin.systemd: - name: nftables - state: started - enabled: true + - name: Check nftables service + ansible.builtin.service_facts: + + - name: Configure nftables include and K3s rules fragment + when: + - ansible_facts.services['nftables.service'] is defined + - ansible_facts.services['nftables.service'].status == 'enabled' + block: + - name: Ensure nftables include directory exists + ansible.builtin.file: + path: /etc/nftables.d + state: directory + mode: "0755" + + - name: Ensure nftables loads /etc/nftables.d rules + ansible.builtin.lineinfile: + path: /etc/nftables.conf + regexp: '^include "/etc/nftables\\.d/\\*\\.nft"$' + line: 'include "/etc/nftables.d/*.nft"' + insertafter: EOF + + - name: Install K3s nftables rules fragment + ansible.builtin.template: + src: k3s.nft.j2 + dest: /etc/nftables.d/k3s.nft + mode: "0644" + + - name: Reload nftables + ansible.builtin.service: + name: nftables + state: reloaded - name: Populate service facts ansible.builtin.service_facts: diff --git a/roles/prereq/templates/k3s.nft.j2 b/roles/prereq/templates/k3s.nft.j2 new file mode 100644 index 00000000..45794bb2 --- /dev/null +++ b/roles/prereq/templates/k3s.nft.j2 @@ -0,0 +1,31 @@ +# K3s rules managed by ansible-k3s; loaded via /etc/nftables.conf include + +# Allow inter-node communication (server + agent nodes) +{% for host in (groups[server_group] | default([]) + groups[agent_group] | default([])) | unique %} +{% if hostvars[host].ansible_default_ipv4 is defined %} +insert rule inet filter input ip saddr {{ hostvars[host].ansible_default_ipv4.address }} accept +{% endif %} +{% endfor %} + +# K3s core ports +insert rule inet filter input tcp dport {{ api_port | default(6443) }} accept +{% if groups[server_group] | length > 1 %} +insert rule inet filter input tcp dport 2379-2381 accept +{% endif %} + +# Inter-node overlay ports +insert rule inet filter input tcp dport { 5001, 10250 } accept +insert rule inet filter input udp dport { 8472, 51820, 51821 } accept + +# Cluster and service CIDRs +{% for cidr in (cluster_cidr + ',' + service_cidr) | split(',') %} +insert rule inet filter input ip saddr {{ cidr }} accept +{% endfor %} + +# NodePort range +insert rule inet filter input tcp dport 30000-32767 accept +insert rule inet filter input udp dport 30000-32767 accept + +# Keep forward traffic open for CNI/pod networking +insert rule inet filter forward ct state established,related accept +insert rule inet filter forward accept \ No newline at end of file