From f6a205335568089b327c9aab07a4f5837cfff71f Mon Sep 17 00:00:00 2001 From: Robert Kaussow Date: Mon, 13 Jun 2022 22:18:21 +0200 Subject: [PATCH] fix configuration templates --- defaults/main.yml | 13 ++++ molecule/rocky8/tests/test_default.py | 11 ++++ tasks/setup.yml | 34 ++++++---- templates/etc/firewalld/firewalld.conf.j2 | 65 ------------------- templates/etc/firewalld/ipsets/ipset.xml.j2 | 16 +++++ .../etc/firewalld/services/service.xml.j2 | 21 ++++++ templates/etc/firewalld/zones/zone.xml.j2 | 16 ++--- 7 files changed, 90 insertions(+), 86 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 4f04a03..447e4a2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -2,7 +2,20 @@ firewalld_default_zone: public firewalld_allow_zone_drifting: False +# @var firewalld_ipsets:description: A firewalld ipset configuration provides the information of an ip set for firewalld. +# @var firewalld_ipsets:example: > +# firewalld_ipsets: +# - name: appserver +# type: "hash:net" +# short: "App Servers" +# description: "Allow http access from all appservers" +# option: {} +# entry: +# - 192.168.2.1 +# - 192.168.2.2 +# @end firewalld_ipsets: [] + firewalld_services: [] # @var firewalld_zones:example: > diff --git a/molecule/rocky8/tests/test_default.py b/molecule/rocky8/tests/test_default.py index 18236da..3bd1aa4 100644 --- a/molecule/rocky8/tests/test_default.py +++ b/molecule/rocky8/tests/test_default.py @@ -5,3 +5,14 @@ import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ["MOLECULE_INVENTORY_FILE"] ).get_hosts("all") + + +def test_firewalld_is_installed(host): + firewalld = host.package("firewalld") + assert firewalld.is_installed + + +def test_firewalld_running_and_enabled(host): + firewalld = host.service("firewalld") + assert firewalld.is_running + assert firewalld.is_enabled diff --git a/tasks/setup.yml b/tasks/setup.yml index 1cf72ab..98d4de6 100644 --- a/tasks/setup.yml +++ b/tasks/setup.yml @@ -7,10 +7,18 @@ - firewalld - python3-firewall + - name: Configure firewalld + template: + src: etc/firewalld/firewalld.conf.j2 + dest: /etc/firewalld/firewalld.conf + mode: 0644 + notify: __firewalld_reload + - name: Configure firewalld ipsets template: src: etc/firewalld/ipsets/ipset.xml.j2 dest: /etc/firewalld/ipsets/{{ item.name }}.xml + mode: 0640 loop: "{{ firewalld_ipsets }}" loop_control: label: "{{ item.name }}" @@ -22,21 +30,22 @@ file_type: file patterns: "*.xml" register: __firewalld_ipsets_active - changed_when: false - failed_when: false + changed_when: False + failed_when: False - name: Remove unmanaged ipsets file: - path: "/etc/firewalld/ipsets/{{ item }}" + path: "{{ item }}" state: absent loop: "{{ __firewalld_ipsets_active.files | map(attribute='path') | list }}" notify: __firewalld_reload - when: item | replace('.xml','') not in firewalld_ipsets | map(attribute='name') | list + when: (item | basename | splitext | first) not in (firewalld_ipsets | map(attribute='name') | list) - name: Configure firewalld services template: src: etc/firewalld/services/service.xml.j2 dest: /etc/firewalld/services/{{ item.name }}.xml + mode: 0640 loop: "{{ firewalld_services }}" loop_control: label: "{{ item.name }}" @@ -48,21 +57,22 @@ file_type: file patterns: "*.xml" register: __firewalld_services_active - changed_when: false - failed_when: false + changed_when: False + failed_when: False - name: Remove unmanaged services file: - path: "/etc/firewalld/services/{{ item }}" + path: "{{ item }}" state: absent loop: "{{ __firewalld_services_active.files | map(attribute='path') | list }}" notify: __firewalld_reload - when: item | replace('.xml','') not in firewalld_services | map(attribute='name') | list + when: (item | basename | splitext | first) not in (firewalld_services | map(attribute='name') | list) - name: Configure firewalld zones template: src: etc/firewalld/zones/zone.xml.j2 dest: /etc/firewalld/zones/{{ item.name }}.xml + mode: 0640 loop: "{{ firewalld_zones }}" loop_control: label: "{{ item.name }}" @@ -74,16 +84,16 @@ file_type: file patterns: "*.xml" register: __firewalld_zones_active - changed_when: false - failed_when: false + changed_when: False + failed_when: False - name: Remove unmanaged zones file: - path: "/etc/firewalld/zones/{{ item }}" + path: "{{ item }}" state: absent loop: "{{ __firewalld_zones_active.files | map(attribute='path') | list }}" notify: __firewalld_reload - when: item | replace('.xml','') not in firewalld_zones | map(attribute='name') | list + when: (item | basename | splitext | first) not in (firewalld_zones | map(attribute='name') | list) - name: Ensure service is up and running service: diff --git a/templates/etc/firewalld/firewalld.conf.j2 b/templates/etc/firewalld/firewalld.conf.j2 index 404be15..8c71afe 100644 --- a/templates/etc/firewalld/firewalld.conf.j2 +++ b/templates/etc/firewalld/firewalld.conf.j2 @@ -1,78 +1,13 @@ #jinja2: lstrip_blocks: True {{ ansible_managed | comment }} -# default zone -# The default zone used if an empty zone string is used. -# Default: public DefaultZone={{ firewalld_default_zone }} - -# Clean up on exit -# If set to no or false the firewall configuration will not get cleaned up -# on exit or stop of firewalld -# Default: yes CleanupOnExit=yes - -# Lockdown -# If set to enabled, firewall changes with the D-Bus interface will be limited -# to applications that are listed in the lockdown whitelist. -# The lockdown whitelist file is lockdown-whitelist.xml -# Default: no Lockdown=no - -# IPv6_rpfilter -# Performs a reverse path filter test on a packet for IPv6. If a reply to the -# packet would be sent via the same interface that the packet arrived on, the -# packet will match and be accepted, otherwise dropped. -# The rp_filter for IPv4 is controlled using sysctl. -# Note: This feature has a performance impact. See man page FIREWALLD.CONF(5) -# for details. -# Default: yes IPv6_rpfilter=yes - -# IndividualCalls -# Do not use combined -restore calls, but individual calls. This increases the -# time that is needed to apply changes and to start the daemon, but is good for -# debugging. -# Default: no IndividualCalls=no - -# LogDenied -# Add logging rules right before reject and drop rules in the INPUT, FORWARD -# and OUTPUT chains for the default rules and also final reject and drop rules -# in zones. Possible values are: all, unicast, broadcast, multicast and off. -# Default: off LogDenied=off - -# FirewallBackend -# Selects the firewall backend implementation. -# Choices are: -# - nftables (default) -# - iptables (iptables, ip6tables, ebtables and ipset) FirewallBackend=nftables - -# FlushAllOnReload -# Flush all runtime rules on a reload. In previous releases some runtime -# configuration was retained during a reload, namely; interface to zone -# assignment, and direct rules. This was confusing to users. To get the old -# behavior set this to "no". -# Default: yes FlushAllOnReload=yes - -# RFC3964_IPv4 -# As per RFC 3964, filter IPv6 traffic with 6to4 destination addresses that -# correspond to IPv4 addresses that should not be routed over the public -# internet. -# Defaults to "yes". RFC3964_IPv4=yes - -# AllowZoneDrifting -# Older versions of firewalld had undocumented behavior known as "zone -# drifting". This allowed packets to ingress multiple zones - this is a -# violation of zone based firewalls. However, some users rely on this behavior -# to have a "catch-all" zone, e.g. the default zone. You can enable this if you -# desire such behavior. It's disabled by default for security reasons. -# Note: If "yes" packets will only drift from source based zones to interface -# based zones (including the default zone). Packets never drift from interface -# based zones to other interfaces based zones (including the default zone). -# Possible values; "yes", "no". Defaults to "yes". AllowZoneDrifting={{ firewalld_allow_zone_drifting | bool | ternary("yes", "no", "no") }} diff --git a/templates/etc/firewalld/ipsets/ipset.xml.j2 b/templates/etc/firewalld/ipsets/ipset.xml.j2 index e69de29..86a3d52 100644 --- a/templates/etc/firewalld/ipsets/ipset.xml.j2 +++ b/templates/etc/firewalld/ipsets/ipset.xml.j2 @@ -0,0 +1,16 @@ +#jinja2: lstrip_blocks: True + + +{% if item.short is defined %} + {{ item.short }} +{% endif %} +{% if item.description is defined %} + {{ item.description }} +{% endif %} +{% for name, value in (item.option | default({})).items() %} + diff --git a/templates/etc/firewalld/services/service.xml.j2 b/templates/etc/firewalld/services/service.xml.j2 index e69de29..f1d6afb 100644 --- a/templates/etc/firewalld/services/service.xml.j2 +++ b/templates/etc/firewalld/services/service.xml.j2 @@ -0,0 +1,21 @@ +#jinja2: lstrip_blocks: True + + +{% if item.short is defined %} + {{ item.short }} +{% endif %} +{% if item.description is defined %} + {{ item.description }} +{% endif %} +{% for tag in item %} +{# Tags which can be used several times #} +{% if tag in ["port", "protocol", "source-port", "module"] %} +{% for subtag in item[tag] %} + <{{ tag }}{% for name, value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/> +{% endfor %} +{# Tags which can be used once #} +{% elif tag in ["destination"] %} + <{{ tag }}{% for name, value in tag.items() | default({}) %} {{ name }}="{{ value }}"{% endfor %}/> +{% endif %} +{% endfor %} + diff --git a/templates/etc/firewalld/zones/zone.xml.j2 b/templates/etc/firewalld/zones/zone.xml.j2 index 26f6b44..d172507 100644 --- a/templates/etc/firewalld/zones/zone.xml.j2 +++ b/templates/etc/firewalld/zones/zone.xml.j2 @@ -1,6 +1,4 @@ #jinja2: lstrip_blocks: True -{{ ansible_managed | comment("xml") }} - {{ item.short | default(item.name) | upper }} @@ -11,12 +9,12 @@ {% for tag in item %} {# Settings which can be used several times #} - {% if tag in ['interface','source','service','port','protocol','icmp-block','forward-port','source-port'] %} + {% if tag in ["interface", "source", "service", "port", "protocol", "icmp-block", "forward-port", "source-port"] %} {% for subtag in item[tag] %} - <{{ tag }}{% for name,value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/> + <{{ tag }}{% for name, value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/> {% endfor %} {# Settings which can be used once #} - {% elif tag in ['icmp-block-inversion','masquerade'] and item[tag] == True %} + {% elif tag in ["icmp-block-inversion", "masquerade"] and item[tag] == True %} <{{ tag }}/> {% endif %} {% endfor %} @@ -26,10 +24,10 @@ {% for rule in item.rule | default([]) %} {% for tag in rule %} - {% if tag in ['source','destination','service','port','icmp-block','icmp-type','masquerade','forward-port'] %} - <{{ tag }}{% for name,value in tag.items() | default({}) %} {{ name }}="{{ value }}"{% endfor %}/> - {% elif tag in ['log','audit','accept','drop','mark','reject'] %} - <{{ tag }}{% for name,value in tag.items() %} {{ name }}="{{ value }}"{% endfor %}> + {% if tag in ["source", "destination", "service", "port", "icmp-block", "icmp-type", "masquerade", "forward-port"] %} + <{{ tag }}{% for name, value in tag.items() | default({}) %} {{ name }}="{{ value }}"{% endfor %}/> + {% elif tag in ["log", "audit", "accept", "drop", "mark", "reject"] %} + <{{ tag }}{% for name, value in tag.items() %} {{ name }}="{{ value }}"{% endfor %}> {% endif %} {% if tag.limit is defined %}