From d542d63c40227cca12c2f953149cf5461be4d71e Mon Sep 17 00:00:00 2001 From: kartnico Date: Sun, 12 Mar 2023 14:27:34 +0100 Subject: [PATCH] feat(policies): add policies management --- firewalld/files/policy.xml | 179 +++++++++++++++++++++++++++++++++++++ firewalld/init.sls | 1 + firewalld/policies.sls | 46 ++++++++++ pillar.example | 30 +++++++ 4 files changed, 256 insertions(+) create mode 100644 firewalld/files/policy.xml create mode 100644 firewalld/policies.sls diff --git a/firewalld/files/policy.xml b/firewalld/files/policy.xml new file mode 100644 index 0000000..0ae4bab --- /dev/null +++ b/firewalld/files/policy.xml @@ -0,0 +1,179 @@ + + +{%- macro rich_rule(rule) %} + + {%- if 'ipset' in rule %} + + {%- endif %} + {%- if 'source' in rule %} + + {%- endif %} + {%- if 'destination' in rule %} + + {%- endif %} + {%- if 'service' in rule %} + + {%- endif %} + {%- if 'port' in rule %} + + {%- endif %} + {%- if 'protocol' in rule %} + + {%- endif %} + {%- if 'icmp_block' in rule %} + + {%- endif %} + {%- if 'icmp_type' in rule %} + + {%- endif %} + {%- if 'masquerade' in rule %} + {%- if rule.masquerade %}{%- endif %} + {%- endif %} + {%- if 'forward_port' in rule %} + {%- if 'comment' in rule.forward_port %} + + {%- endif %} + + {%- endif %} + {%- if 'source_port' in rule %} + {%- if 'comment' in rule.source_port %} + + {%- endif %} + + {%- endif %} + {%- if 'log' in rule %} + + {%- if 'limit' in rule.log %} + + {%- endif %} + + {%- endif %} + {%- if 'audit' in rule %} + {%- if 'limit' in rule.audit %} {%- endif %} + {%- endif %} + {%- if 'accept' in rule %} + {%- if rule.accept is mapping and 'limit' in rule.accept %} {%- endif %} + {%- endif %} + {%- if 'reject' in rule %} + + {%- endif %} + {%- if 'drop' in rule %} + + {%- endif %} + +{%- endmacro %} + + {% if 'short' in policy %}{{ policy.short }}{% else %}{{ name }}{% endif %} + {% if 'description' in policy %}{{ policy.description }}{% endif %} + {% if 'ingress_zone' in policy %}{% endif %} + {% if 'egress_zone' in policy %}{% endif %} + +{%- if 'sources' in policy %} + {%- for v in policy.sources %} + {%- if 'comment' in v %} + + + {%- else %} + + {%- endif %} + {%- endfor %} +{%- endif %} +{%- if 'ipsets' in policy %} + {%- for v in policy.ipsets %} + {%- if 'comment' in v %} + + + {%- else %} + + {%- endif %} + {%- endfor %} +{%- endif %} +{%- for k,val in policy.items() %} + {%- if k.endswith("services") %} + {%- for v in val %} + + {%- endfor %} + {%- endif %} +{%- endfor %} +{%- if 'ports' in policy %} + {%- for v in policy.ports %} + {%- if 'comment' in v %} + + {%- endif %} + + {%- endfor %} +{%- endif %} +{%- if 'protocols' in policy %} + {%- for v in policy.protocols %} + + {%- endfor %} +{%- endif %} +{%- if 'icmp_blocks' in policy %} + {%- for v in policy.icmp_blocks %} + + {%- endfor %} +{%- endif %} +{%- if 'icmp_block_inversion' in policy and policy.icmp_block_inversion %} + +{%- endif %} +{%- if 'masquerade' in policy %} + {%- if policy.masquerade %} + + {%- endif %} +{%- endif %} +{%- if 'forward_ports' in policy %} + {%- for v in policy.forward_ports %} + {%- if 'comment' in v %} + + {%- endif %} + + {%- endfor %} +{%- endif %} +{%- if 'source_ports' in policy %} + {%- for v in policy.source_ports %} + {%- if 'comment' in v %} + + {%- endif %} + + {%- endfor %} +{%- endif %} +{%- if 'rich_rules' in policy %} + {%- if policy.rich_rules is list %} + {%- set rich_rules = policy.rich_rules %} + {%- else %} + {%- set expanded_ipset_rules = [] %} + {%- for name,rule in policy.rich_rules|dictsort %} + {%- if 'ipsets' in rule %} + {%- for ipset in rule.ipsets %} + {%- set tmp_rule = {} %} + {%- set _dummy = tmp_rule.update(rule) %} + {%- set _dummy = tmp_rule.update({'ipset':{'name':ipset}}) %} + {%- set _dummy = expanded_ipset_rules.append(tmp_rule) %} + {%- endfor %} + {%- else %} + {%- set _dummy = expanded_ipset_rules.append(rule) %} + {%- endif %} + {%- endfor %} + {%- set rich_rules = [] %} + {%- for rule in expanded_ipset_rules %} + {%- if 'services' in rule %} + {%- for service in rule.services %} + {%- set tmp_rule = {} %} + {%- set _dummy = tmp_rule.update(rule) %} + {%- set _dummy = tmp_rule.update({'service':service}) %} + {%- set _dummy = rich_rules.append(tmp_rule) %} + {%- endfor %} + {%- else %} + {%- set _dummy = rich_rules.append(rule) %} + {%- endif %} + {%- endfor %} + {%- endif %} + {%- for rule in rich_rules %} +{{- rich_rule(rule) }} + {%- endfor %} +{%- endif %} + diff --git a/firewalld/init.sls b/firewalld/init.sls index 8e4aec8..c1bec7c 100644 --- a/firewalld/init.sls +++ b/firewalld/init.sls @@ -24,6 +24,7 @@ include: - firewalld.backend - firewalld.services - firewalld.zones + - firewalld.policies - firewalld.direct # iptables service that comes with rhel/centos diff --git a/firewalld/policies.sls b/firewalld/policies.sls new file mode 100644 index 0000000..b03ed5b --- /dev/null +++ b/firewalld/policies.sls @@ -0,0 +1,46 @@ +# == State: firewalld.policies +# +# This state ensures that /etc/firewalld/policies/ exists. +# +{% from "firewalld/map.jinja" import firewalld with context %} + +directory_firewalld_policies: + file.directory: # make sure this is a directory + - name: /etc/firewalld/policies + - user: root + - group: root + - mode: 750 + - require: + - pkg: package_firewalld # make sure package is installed + - require_in: + - service: service_firewalld + - watch_in: + - cmd: reload_firewalld # reload firewalld config + +# == Define: firewalld.policies +# +# This defines a policy configuration, see firewalld.policy (5) man page. +# +{% for k, v in salt['pillar.get']('firewalld:policies', {}).items() %} +{% set z_name = v.name|default(k) %} + +/etc/firewalld/policies/{{ z_name }}.xml: + file.managed: + - name: /etc/firewalld/policies/{{ z_name }}.xml + - user: root + - group: root + - mode: 644 + - source: salt://firewalld/files/policy.xml + - template: jinja + - require: + - pkg: package_firewalld # make sure package is installed + - file: directory_firewalld_policies + - require_in: + - service: service_firewalld + - watch_in: + - cmd: reload_firewalld # reload firewalld config + - context: + name: {{ z_name }} + policy: {{ v|json }} + +{% endfor %} diff --git a/pillar.example b/pillar.example index 87d4690..2ee0aab 100644 --- a/pillar.example +++ b/pillar.example @@ -182,6 +182,36 @@ firewalld: services: - ssh + policies: + myOutputPolicy: + short: myOutputPolicy + target: DROP + ingress-zones: ANY + egress-zones: HOST + description: >- + This example, creates a policy that applies to traffic originating from the host + running firewalld and is destined to any zone. Or said differently traffic + in the OUTPUT chain. + services: + - http + - https + - ssh + rich_rules: + - family: ipv4 + destination: + address: 8.8.8.8 + port: + portid: 53 + protocol: udp + accept: true + ports: + - comment: salt-master + port: 4505 + protocol: tcp + - comment: salt-master + port: 4506 + protocol: tcp + direct: chain: MYCHAIN: