Supports nftables instead of iptables

This patch introduces a new role (tripleo_nftables) as well as a new
tripleo_firewall_engine parameter, allowing to switch from iptables to
nftables.

All of tripleo rules are pushed in the "inet" family, in a dedicated
chains therein. It allows to avoid rule duplication between IPv6 and
IPv4, while ensuring we don't break the compatibility layer for
iptables-nft - that tool is checking only the "ip" family, while
ip6tables-nft is checking the "ip6" one.

This means some changes are needed in the doc, when it comes to listing
the existing rules.

Also, please note some tools such as neutron are still heavily using the
iptables family, as well as some part of podman apparently.

Change-Id: Ia43b58f304d8ef41b80820c3c98696650eb362e1
This commit is contained in:
Cédric Jeanneret 2022-05-11 14:04:42 +02:00
parent feb150954f
commit 656c1aba3d
31 changed files with 769 additions and 79 deletions

View File

@ -0,0 +1,6 @@
=======================
Role - tripleo_nftables
=======================
.. ansibleautoplugin::
:role: tripleo_ansible/roles/tripleo_nftables

View File

@ -29,6 +29,8 @@
# dport: 22
# extras:
# ensure: 'absent'
tripleo_firewall_engine: 'iptables'
tripleo_firewall_rules: {}
tripleo_firewall_frontend_enabled: false

View File

@ -0,0 +1,22 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Converge
hosts: all
roles:
- role: "tripleo_firewall"
tripleo_firewall_engine: 'nftables'

View File

@ -0,0 +1,27 @@
---
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
hosts:
instance:
ansible_host: localhost
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH}:${HOME}/zuul-jobs/roles"
scenario:
name: nftables
test_sequence:
- prepare
- converge
- check
verifier:
name: testinfra

View File

@ -0,0 +1,21 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Prepare
hosts: all
roles:
- role: test_deps

View File

@ -0,0 +1,98 @@
---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# "tripleo_firewall" will search for and load any operating system variable file
- name: Firewall add block
become: true
block:
- name: Ensure firewall is installed
package:
name: "{{ tripleo_firewall_packages }}"
state: present
- name: Create empty ruleset in /etc/sysconfig/iptables and /etc/sysconfig/ip6tables
become: true
ignore_errors: "{{ (((ansible_facts['os_family'] | lower) ~ '-' ~ ansible_facts['distribution_major_version']) == 'redhat-7') | bool }}"
copy:
dest: "{{ item }}"
content: "# empty ruleset created by deployed-server bootstrap"
loop:
- /etc/sysconfig/iptables
- /etc/sysconfig/ip6tables
- name: Ensure firewall is enabled/started
systemd:
name: iptables
state: started
enabled: true
- name: Manage firewall rules
tripleo_iptables:
tripleo_rules: "{{ firewall_rules_sorted }}"
- name: Firewall save block
become: true
block:
- name: Save firewall rules ipv4
command: /usr/libexec/iptables/iptables.init save
- name: Save firewall rules ipv6
command: /usr/libexec/iptables/ip6tables.init save
- name: Enable iptables service (and do a daemon-reload systemd)
systemd:
daemon_reload: true
enabled: true
name: "{{ item }}"
state: started
loop:
- iptables.service
- ip6tables.service
- name: Enable tripleo-iptables service (and do a daemon-reload systemd)
systemd:
daemon_reload: true
enabled: true
name: "{{ item }}"
state: started
loop:
- tripleo-iptables.service
- tripleo-ip6tables.service
failed_when: false
- name: Stop and disable firewalld
systemd:
enabled: false
name: "firewalld.service"
state: stopped
failed_when: false
- name: Find non-persistent rules
command: egrep -l 'comment.*(neutron-|ironic-inspector)' /etc/sysconfig/iptables* /etc/sysconfig/ip6tables*
failed_when: false
changed_when: false
register: neutron_rules
- name: Remove non-persistent line(s)
lineinfile:
path: "{{ item }}"
state: absent
regexp: '^((?!.*comment)(?=.*(ironic-inspector|neutron-)))'
when:
- not ansible_check_mode|bool
- item.find('v=' ~ '^/') == -1
loop: "{{ neutron_rules.stdout_lines }}"

View File

@ -87,83 +87,15 @@
list
}}"
- name: Firewall add block
become: true
block:
- name: Ensure firewall is installed
package:
name: "{{ tripleo_firewall_packages }}"
state: present
- name: Manage rules via iptables
when:
- tripleo_firewall_engine == 'iptables'
include_tasks: iptables.yaml
- name: Create empty ruleset in /etc/sysconfig/iptables and /etc/sysconfig/ip6tables
become: true
ignore_errors: "{{ (((ansible_facts['os_family'] | lower) ~ '-' ~ ansible_facts['distribution_major_version']) == 'redhat-7') | bool }}"
copy:
dest: "{{ item }}"
content: "# empty ruleset created by deployed-server bootstrap"
loop:
- /etc/sysconfig/iptables
- /etc/sysconfig/ip6tables
- name: Ensure firewall is enabled/started
systemd:
name: iptables
state: started
enabled: true
- name: Manage firewall rules
tripleo_iptables:
tripleo_rules: "{{ firewall_rules_sorted }}"
- name: Firewall save block
become: true
block:
- name: Save firewall rules ipv4
command: /usr/libexec/iptables/iptables.init save
- name: Save firewall rules ipv6
command: /usr/libexec/iptables/ip6tables.init save
- name: Enable iptables service (and do a daemon-reload systemd)
systemd:
daemon_reload: true
enabled: true
name: "{{ item }}"
state: started
loop:
- iptables.service
- ip6tables.service
- name: Enable tripleo-iptables service (and do a daemon-reload systemd)
systemd:
daemon_reload: true
enabled: true
name: "{{ item }}"
state: started
loop:
- tripleo-iptables.service
- tripleo-ip6tables.service
failed_when: false
- name: Stop and disable firewalld
systemd:
enabled: false
name: "firewalld.service"
state: stopped
failed_when: false
- name: Find non-persistent rules
command: egrep -l 'comment.*(neutron-|ironic-inspector)' /etc/sysconfig/iptables* /etc/sysconfig/ip6tables*
failed_when: false
changed_when: false
register: neutron_rules
- name: Remove non-persistent line(s)
lineinfile:
path: "{{ item }}"
state: absent
regexp: '^((?!.*comment)(?=.*(ironic-inspector|neutron-)))'
when:
- not ansible_check_mode|bool
- item.find('v=' ~ '^/') == -1
loop: "{{ neutron_rules.stdout_lines }}"
- name: Manage rules via nftables
when:
- tripleo_firewall_engine == 'nftables'
vars:
tripleo_nftables_rules: "{{ firewall_rules_sorted | sort(attribute='rule_name') |list }}"
include_role:
name: tripleo_nftables

View File

@ -0,0 +1,59 @@
---
# Copyright 2022 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# All variables intended for modification should be placed in this file.
# All variables within this role should have a prefix of "tripleo_nftables_"
# Example rule definition
tripleo_nftables_rules:
- rule:
proto: all
state:
- RELATED
- ESTABLISHED
rule_name: 000 accept related established rules
- rule:
ipversion: ipv4
proto: icmp
rule_name: 001 accept all icmp
- rule:
ipversion: ipv6
proto: ipv6-icmp
rule_name: 001 accept all ipv6-icmp
- rule:
interface: lo
proto: all
rule_name: 002 accept all to lo interface
- rule:
destination: fe80::/64
dport: 546
ipversion: ipv6
proto: udp
state:
- NEW
rule_name: 004 accept ipv6 dhcpv6
- rule:
jump: LOG
limit: 20/min
limit_burst: 15
proto: all
rule_name: 998 log all
- rule:
action: drop
proto: all
rule_name: 999 drop all

View File

@ -0,0 +1,83 @@
#!/usr/sbin/nft -f
#
# Managed by tripleo-ansible/tripleo_nftables
#
# Ensure we get the iptables layout to make the whole thing 100% compatible,
# even if some other tools are still relying on iptables-nft compatibility
# wrapper
# We will push our tripleo rules in the inet table - it avoids rule duplication
# and allows to keep good compatibility with the iptables-nft layer
table inet filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}
table inet raw {
chain PREROUTING {
type filter hook prerouting priority raw; policy accept;
}
chain OUTPUT {
type filter hook output priority raw; policy accept;
}
}
# Compatibility tables and chains for iptables-nft
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}
table ip raw {
chain PREROUTING {
type filter hook prerouting priority raw; policy accept;
}
chain OUTPUT {
type filter hook output priority raw; policy accept;
}
}
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
}
}
table ip6 raw {
chain PREROUTING {
type filter hook prerouting priority raw; policy accept;
}
chain OUTPUT {
type filter hook output priority raw; policy accept;
}
}
table ip6 filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}
chain FORWARD {
type filter hook forward priority filter; policy accept;
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}

View File

@ -0,0 +1,43 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
galaxy_info:
author: OpenStack
description: TripleO OpenStack Role -- tripleo_nftables
company: Red Hat
license: Apache-2.0
min_ansible_version: 2.7
namespace: openstack
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: CentOS
versions:
- 8
- 9
galaxy_tags:
- tripleo
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
dependencies: []

View File

@ -0,0 +1,21 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Converge
hosts: all
roles:
- role: "tripleo_nftables"

View File

@ -0,0 +1,28 @@
---
log: true
provisioner:
name: ansible
config_options:
defaults:
fact_caching: jsonfile
fact_caching_connection: /tmp/molecule/facts
inventory:
hosts:
all:
hosts:
instance:
ansible_host: localhost
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_ROLES_PATH: "${ANSIBLE_ROLES_PATH}:${HOME}/zuul-jobs/roles"
scenario:
test_sequence:
- prepare
- converge
- check
verifier:
name: testinfra

View File

@ -0,0 +1,27 @@
---
# Copyright 2020 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
- name: Prepare
hosts: all
tasks:
- name: test_deps
include_role:
name: test_deps
- name: Install nftables
become: true
package:
name: nftables

View File

@ -0,0 +1,137 @@
---
# Copyright 2022 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# 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: Swith firewall management to nftables if needed
when:
- nftables_status.rc == 3
include_tasks: service.yaml
- name: IPtables compatibility layout
become: true
block:
- name: Push initial, empty ruleset
register: init_nftables
copy:
dest: /etc/nftables/iptables.nft
src: iptables.nft
- name: Load empty ruleset if needed
when:
- init_nftables is changed
ansible.builtin.command: nft -f /etc/nftables/iptables.nft
# 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
- name: nftables files generation
become: true
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 }}"
vars:
current_nft: "{{ nft_current_rules }}"
nft_is_update: false
template:
dest: /etc/nftables/tripleo-jumps.nft
src: jump-chain.j2
# 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 }}"
vars:
current_nft: "{{ nft_current_rules }}"
nft_is_update: true
template:
dest: /etc/nftables/tripleo-update-jumps.nft
src: jump-chain.j2
# Note: we do NOT include this one for boot, since chains are
# already empty!
- name: Generate nft flushes
register: nft_flushes
template:
dest: /etc/nftables/tripleo-flushes.nft
src: flush-chain.j2
- name: Generate nft tripleo chains
register: nft_chains
template:
dest: /etc/nftables/tripleo-chains.nft
src: chains.j2
- name: Generate nft ruleset in static file
register: nft_ruleset
template:
dest: /etc/nftables/tripleo-rules.nft
src: ruleset.j2
# We cannot use the "validate" parameter from the "template" module, since
# we don't load the chains before. So let's validate now, with all the things.
# Remember, the "iptables" compat layout is already loaded at this point.
- name: Validate all of the generated content before loading
ansible.builtin.shell: >-
cat /etc/nftables/tripleo-chains.nft
/etc/nftables/tripleo-flushes.nft
/etc/nftables/tripleo-rules.nft
/etc/nftables/tripleo-update-jumps.nft
/etc/nftables/tripleo-jumps.nft | nft -c -f -
# Order is important here.
# Please keep that in mind in case you want to add some new ruleset in their
# dedicated file!
- name: Ensure we load our different nft rulesets on boot
become: true
ansible.builtin.blockinfile:
path: /etc/sysconfig/nftables.conf
backup: false
validate: nft -c -f %s
block: |
include "/etc/nftables/iptables.nft"
include "/etc/nftables/tripleo-chains.nft"
include "/etc/nftables/tripleo-rules.nft"
include "/etc/nftables/tripleo-jumps.nft"
- name: Create our custom chains
become: true
ansible.builtin.command: nft -f /etc/nftables/tripleo-chains.nft
# Here, we make different call in order to avoid jumps duplication.
# In both cases, we flush the custom chains. Doing things like that ensures
# we run all, from the flush to the rule creation, in a single transaction.
# This prevents accidental lock-outs.
- name: Reload custom nftables ruleset WITH jumps
become: true
ansible.builtin.shell: >-
cat /etc/nftables/tripleo-flushes.nft
/etc/nftables/tripleo-rules.nft
/etc/nftables/tripleo-update-jumps.nft | nft -f -
when:
- nft_ruleset is changed

View File

@ -0,0 +1,33 @@
---
# Copyright 2022 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# systemctl will return 0 if success, 1 if unit not found
- name: Ensure legacy iptables services are off
become: true
ansible.builtin.command: "systemctl disable --now {{ item }}"
register: ipt_service
failed_when:
- ipt_service.rc not in [0, 1]
loop:
- iptables.service
- ip6tables.service
- name: Ensure nftables service is enabled and running
become: true
ansible.builtin.systemd:
name: nftables
state: started
enabled: true

View File

@ -0,0 +1,8 @@
# Create chain if needed
{%- for ruleset in tripleo_nftables_rules %}
{% set rule=ruleset['rule'] %}
{%- if 'extras' not in rule or rule['extras'].get('ensure', 'present') in ['enabled', 'present'] %}
# Create chain TRIPLEO_{{ rule.get('chain', 'INPUT') }} in {{rule.get('table', 'filter') }} table
add chain inet {{ rule.get('table', 'filter') }} TRIPLEO_{{ rule.get('chain', 'INPUT') }}
{% endif %}
{% endfor %}

View File

@ -0,0 +1,6 @@
{%- if 'destination' in rule %}
{%- if 'ipversion' in rule and rule['ipversion'] == 'ipv6' %}
ip6
{%- endif %}
daddr {{ rule['destination'] }}
{%- endif %}

View File

@ -0,0 +1,15 @@
{%- if 'dport' in rule %}
{%- if rule['dport'] is iterable %}
{{ rule.get('proto', false)|ternary('', 'tcp ') }}dport { {{ rule['dport'] |join(',') }} }
{%- else %}
{{ rule.get('proto', false)|ternary('', 'tcp ') }}dport {{ rule['dport'] }}
{%- endif %}
{%- endif %}
{#- This is for legacy things - Really, use dport... #}
{%- if 'port' in rule %}
{%- if rule['port'] is iterable %}
{{ rule.get('proto', false)|ternary('', 'tcp ') }}dport { {{ rule['port'] |join(',') }} }
{%- else %}
{{ rule.get('proto', false)|ternary('', 'tcp ') }}dport {{ rule['port'] }}
{%- endif %}
{%- endif %}

View File

@ -0,0 +1,7 @@
# Managed by tripleo-ansible/tripleo_nftables
{%- for ruleset in tripleo_nftables_rules %}
{% set rule=ruleset['rule'] %}
{% if 'extras' not in rule or rule['extras'].get('ensure', 'present') in ['enabled', 'present'] %}
flush chain inet {{ rule.get('table', 'filter') }} TRIPLEO_{{ rule.get('chain', 'INPUT') }}
{% endif %}
{% endfor %}

View File

@ -0,0 +1,3 @@
{%- if 'interface' in rule %}
iifname {{ rule['interface'] }}
{%- endif %}

View File

@ -0,0 +1,4 @@
{# We force everything into the "inet" family so that we cover both
ip and ip6. This also ensures proper compat with iptables-nft.
#}
inet

View File

@ -0,0 +1,31 @@
# Managed by tripleo-ansible/tripleo_nftables
{% set chains = namespace(chains=[]) %}
{% if nft_is_update|default(false)|bool %}
{# Add missing jumps only (usually during day-2 operations) #}
{% set existing = (current_nft['stdout']|from_json)['nftables']|map(attribute='rule', default={})|list %}
{% for ruleset in tripleo_nftables_rules %}
{% set rule=ruleset['rule'] %}
{% set query="[? table==`"~rule.get('table', 'filter')~"` && family==`inet` && chain==`"~rule.get('chain', 'INPUT')~"`].expr[*].jump.target" %}
{% set chain_key = rule.get('chain', 'INPUT') ~ rule.get('table', 'filter') %}
{% if chain_key not in chains.chains %}
{% if 'TRIPLEO_'~rule.get('chain', 'INPUT') not in (existing|json_query(query)|flatten) %}
insert rule inet {{ rule.get('table', 'filter') }} {{ rule.get('chain', 'INPUT') }} position 0 jump TRIPLEO_{{ rule.get('chain', 'INPUT') }}
{% endif %}
{% set _ = chains.chains.append(chain_key) %}
{% endif %}
{% endfor %}
{% else %}
{# Insert all jumps to custom chains (usually during boot) #}
{% for ruleset in tripleo_nftables_rules %}
{% set rule=ruleset['rule'] %}
{% if 'extras' not in rule or rule['extras'].get('ensure', 'present') in ['enabled', 'present'] %}
{% set chain_key = rule.get('chain', 'INPUT') ~ rule.get('table', 'filter') %}
{% if chain_key not in chains.chains %}
insert rule inet {{ rule.get('table', 'filter') }} {{ rule.get('chain', 'INPUT') }} position 0 jump TRIPLEO_{{ rule.get('chain', 'INPUT') }}
{% set _ = chains.chains.append(chain_key) %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}

View File

@ -0,0 +1,9 @@
{%- if 'jump' in rule %}
{% if (rule['jump']|lower) not in ['accept', 'drop', 'log', 'masquerade', 'notrack', 'return'] %}
jump {{ rule['jump'] }}
{%- else %}
{{ rule['jump']|lower }}
{%- endif %}
{%- else %}
accept
{%- endif %}

View File

@ -0,0 +1,3 @@
{%- if 'limit' in rule %}
limit rate {{ rule['limit']|regex_replace('([0-9]+)/min', '\\1/minute') }}
{%- endif %}

View File

@ -0,0 +1,3 @@
{%- if 'limit_burst' in rule %}
burst {{ rule['limit_burst'] }} packets
{%- endif %}

View File

@ -0,0 +1,6 @@
{%- if 'proto' in rule and (rule['proto']|lower) != 'all' %}
{%- if (rule['proto']|lower) not in ['tcp', 'udp'] %}
meta l4proto
{%- endif %}
{{ rule['proto']|lower }}
{%- endif %}

View File

@ -0,0 +1,30 @@
#!/usr/sbin/nft -f
# Managed by tripleo-ansible/tripleo_nftables
# Valid starting nft-0.9.8
{%- for ruleset in tripleo_nftables_rules %}
{% set rule=ruleset['rule'] %}
{% set name=ruleset['rule_name'] %}
{%- if 'extras' not in rule or rule['extras'].get('ensure', 'present') in ['enabled', 'present'] %}
# {{ rule.get('rule_name', name) }} {{ rule }}
add rule
{%- include 'templates/ipversion.j2' %}
{{ rule.get('table', 'filter') }} TRIPLEO_{{ rule.get('chain', 'INPUT') }}
{%- include 'templates/interface.j2' %}
{%- include 'templates/source.j2' %}
{%- include 'templates/sport.j2' %}
{%- include 'templates/destination.j2' %}
{%- include 'templates/protocol.j2' %}
{%- include 'templates/dport.j2' %}
{%- include 'templates/state.j2' %}
{%- include 'templates/limit.j2' %}
{%- include 'templates/limit_burst.j2' %}
counter
{%- include 'templates/jump.j2' %}
comment "{{rule.get('rule_name', name) }}"
{% endif %}
{% endfor %}
# Lock down INPUT chains
add chain inet filter INPUT { policy drop; }

View File

@ -0,0 +1,6 @@
{%- if 'source' in rule %}
{%- if 'ipversion' not in rule %}
ip
{%- endif %}
saddr {{ rule['source'] }}
{%- endif %}

View File

@ -0,0 +1,3 @@
{%- if 'sport' in rule %}
{{ rule.get('proto', false)|ternary('', 'tcp ') }}sport {{ rule['sport'] }}
{%- endif %}

View File

@ -0,0 +1,7 @@
{%- if 'state' in rule %}
{%- if rule['state']|length > 0 %}
ct state {{ rule['state'] |join(',')|lower }}
{%- endif %}
{%- else %}
ct state new
{%- endif %}

View File

@ -44,6 +44,7 @@
- tripleo-ansible-centos-stream-molecule-tripleo_multipathd
- tripleo-ansible-centos-stream-molecule-tripleo_mysql_client
- tripleo-ansible-centos-stream-molecule-tripleo_network_config
- tripleo-ansible-centos-stream-molecule-tripleo_nftables
- tripleo-ansible-centos-stream-molecule-tripleo_nodes_validation
- tripleo-ansible-centos-stream-molecule-tripleo_nova_image_cache
- tripleo-ansible-centos-stream-molecule-tripleo_nvdimm
@ -111,6 +112,7 @@
- tripleo-ansible-centos-stream-molecule-tripleo_multipathd
- tripleo-ansible-centos-stream-molecule-tripleo_mysql_client
- tripleo-ansible-centos-stream-molecule-tripleo_network_config
- tripleo-ansible-centos-stream-molecule-tripleo_nftables
- tripleo-ansible-centos-stream-molecule-tripleo_nodes_validation
- tripleo-ansible-centos-stream-molecule-tripleo_nova_image_cache
- tripleo-ansible-centos-stream-molecule-tripleo_nvdimm
@ -176,6 +178,7 @@
- tripleo-ansible-centos-stream-molecule-tripleo_multipathd
- tripleo-ansible-centos-stream-molecule-tripleo_mysql_client
- tripleo-ansible-centos-stream-molecule-tripleo_network_config
- tripleo-ansible-centos-stream-molecule-tripleo_nftables
- tripleo-ansible-centos-stream-molecule-tripleo_nodes_validation
- tripleo-ansible-centos-stream-molecule-tripleo_nova_image_cache
- tripleo-ansible-centos-stream-molecule-tripleo_nvdimm
@ -507,6 +510,13 @@
parent: tripleo-ansible-centos-stream-base
vars:
tripleo_role_name: tripleo_network_config
- job:
files:
- ^tripleo_ansible/roles/tripleo_nftables/(?!meta).*
name: tripleo-ansible-centos-stream-molecule-tripleo_nftables
parent: tripleo-ansible-centos-stream-base
vars:
tripleo_role_name: tripleo_nftables
- job:
files:
- ^tripleo_ansible/roles/tripleo_nodes_validation/(?!meta).*