From 1f1228f3e851ac0aafbf05d5358d4014c0e6f0d7 Mon Sep 17 00:00:00 2001 From: Ionut Ciocoiu Date: Wed, 11 Mar 2026 19:09:14 +0200 Subject: [PATCH] Add nftables configuration for K3s on Arch Linux (#511) * Do not enable nftables by default * If nftables is enables, configure exceptions for k3s service Signed-off-by: Ionut Ciocoiu Co-authored-by: Derek Nola --- roles/prereq/tasks/main.yml | 39 +++++++++++++++++++++++++------ roles/prereq/templates/k3s.nft.j2 | 31 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 roles/prereq/templates/k3s.nft.j2 diff --git a/roles/prereq/tasks/main.yml b/roles/prereq/tasks/main.yml index cf16717..57c9e8e 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 0000000..45794bb --- /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