diff --git a/VERSION b/VERSION
index 6e8bf73..0ea3a94 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.0
+0.2.0
diff --git a/firewalld/defaults.yaml b/firewalld/defaults.yaml
index ac2f830..84b32a6 100644
--- a/firewalld/defaults.yaml
+++ b/firewalld/defaults.yaml
@@ -2,5 +2,6 @@
# vim: ft=yaml
firewalld:
package: firewalld
+ ipsetpackage: ipset
service: firewalld
config: /etc/firewalld.conf
diff --git a/firewalld/files/ipset.xml b/firewalld/files/ipset.xml
new file mode 100644
index 0000000..204cce7
--- /dev/null
+++ b/firewalld/files/ipset.xml
@@ -0,0 +1,31 @@
+
+
+{%- if 'short' in ipset %}
+ {{ ipset.short }}
+{%- endif %}
+{%- if 'description' in ipset %}
+ {{ ipset.description }}
+{%- endif %}
+{%- if 'options' in ipset %}
+{%- if 'maxelem' in ipset.options %}
+{%- for v in ipset.options.maxelem %}
+
+ {%- endfor %}
+{%- endif %}
+{%- if 'timeout' in ipset.options %}
+{%- for v in ipset.options.timeout %}
+
+{%- endfor %}
+{%- endif %}
+{%- if 'hashsize' in ipset.options %}
+{%- for v in ipset.options.hashsize %}
+
+{%- endfor %}
+{%- endif %}
+{%- endif %}
+{%- if 'entries' in ipset %}
+{%- for v in ipset.entries %}
+ {{ v }}
+{%- endfor %}
+{%- endif %}
+
diff --git a/firewalld/files/zone.xml b/firewalld/files/zone.xml
index 1e7c33d..75c40e8 100644
--- a/firewalld/files/zone.xml
+++ b/firewalld/files/zone.xml
@@ -52,6 +52,9 @@
{%- else %}
{%- endif %}
+ {%- if 'ipset' in rule %}
+
+ {%- endif %}
{%- if 'source' in rule %}
{%- endif %}
diff --git a/firewalld/init.sls b/firewalld/init.sls
index 6fbc02c..ea8b0cb 100644
--- a/firewalld/init.sls
+++ b/firewalld/init.sls
@@ -8,6 +8,7 @@
{% if salt['pillar.get']('firewalld:enabled') %}
include:
- firewalld.config
+ - firewalld.ipsets
- firewalld.services
- firewalld.zones
diff --git a/firewalld/ipsets.sls b/firewalld/ipsets.sls
new file mode 100644
index 0000000..83995bb
--- /dev/null
+++ b/firewalld/ipsets.sls
@@ -0,0 +1,48 @@
+# == State: firewalld.ipsets
+#
+# This state ensures that /etc/firewalld/ipsets/ exists.
+#
+{% from "firewalld/map.jinja" import firewalld with context %}
+
+{%- if salt['pillar.get']('firewalld:ipset') %}
+package_ipset:
+ pkg.installed:
+ - name: {{ firewalld.ipsetpackage }}
+
+directory_firewalld_ipsets:
+ file.directory: # make sure this is a directory
+ - name: /etc/firewalld/ipsets
+ - user: root
+ - group: root
+ - mode: 750
+ - require:
+ - pkg: package_firewalld # make sure package is installed
+ - listen_in:
+ - module: service_firewalld # restart service
+
+# == Define: firewalld.ipsets
+#
+# This defines a ipset configuration, see firewalld.ipset (5) man page.
+#
+{% for k, v in salt['pillar.get']('firewalld:ipsets', {}).items() %}
+{% set z_name = v.name|default(k) %}
+
+/etc/firewalld/ipsets/{{ z_name }}.xml:
+ file.managed:
+ - name: /etc/firewalld/ipsets/{{ z_name }}.xml
+ - user: root
+ - group: root
+ - mode: 644
+ - source: salt://firewalld/files/ipset.xml
+ - template: jinja
+ - require:
+ - pkg: package_firewalld # make sure package is installed
+ - file: directory_firewalld_ipsets
+ - listen_in:
+ - module: service_firewalld # restart service
+ - context:
+ name: {{ z_name }}
+ ipset: {{ v }}
+
+{% endfor %}
+{%- endif %}
diff --git a/pillar.example.sls b/pillar.example.sls
index 9d649d9..6b74136 100644
--- a/pillar.example.sls
+++ b/pillar.example.sls
@@ -1,31 +1,91 @@
-# CentOS7 FirewallD firewall
+# FirewallD pillar examples:
firewalld:
enabled: True
+ ipset: True
default_zone: public
+
services:
sshcustom:
short: sshcustom
description: SSH on port 3232 and 5252. Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.
ports:
- tcp:
+ tcp:
- 3232
- 5252
- modules:
+ modules:
- some_module_to_load
destinations:
- ipv4:
+ ipv4:
- 224.0.0.251
- 224.0.0.252
- ipv6:
+ ipv6:
- ff02::fb
- ff02::fc
+
+ zabbixcustom:
+ short: Zabbixcustom
+ description: "zabbix custom rule"
+ ports:
+ tcp:
+ - "10051"
+ salt-minion:
+ short: salt-minion
+ description: "salt-minion"
+ ports:
+ tcp:
+ - "8000"
+
+ ipsets:
+ fail2ban-ssh:
+ short: fail2ban-ssh
+ description: fail2ban-ssh ipset
+ type: 'hash:ip'
+ options:
+ maxelem:
+ - 65536
+ timeout:
+ - 300
+ hashsize:
+ - 1024
+ entries:
+ - 10.0.0.1
+
+
zones:
public:
short: Public
description: "For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted."
services:
- http
+ - zabbixcustom
- https
- ssh
- - dhcpv6-client
-
+ - salt-minion
+ rich_rules:
+ - family: ipv4
+ source:
+ address: 8.8.8.8/24
+ accept: true
+ - family: ipv4
+ ipset:
+ name: fail2ban-ssh
+ reject:
+ type: icmp-port-unreachable
+ ports:
+{% if grains['id'] == 'salt.example.com' %}
+ - comment: salt-master
+ port: 4505
+ protocol: tcp
+ - comment: salt-python
+ port: 4506
+ protocol: tcp
+{% endif %}
+ - comment: zabbix-agent
+ port: 10050
+ protocol: tcp
+ - comment: bacula-client
+ port: 9102
+ protocol: tcp
+ - comment: vsftpd
+ port: 21
+ protocol: tcp