From 043bc55dcbd4c622eaae0c797420adb7db3f1013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gardais=20J=C3=A9r=C3=A9my?= Date: Tue, 8 Aug 2017 14:32:59 +0200 Subject: [PATCH] Manage sets and maps definitions in a specific file. --- README.md | 38 ++++++++++++++++++----- defaults/main.yml | 10 +++++- tasks/main.yml | 10 ++++++ templates/etc/nftables.conf.j2 | 1 + templates/etc/nftables.d/inet-sets.nft.j2 | 15 +++++++++ 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 templates/etc/nftables.d/inet-sets.nft.j2 diff --git a/README.md b/README.md index 5029130..8660157 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ Highly inspired by [Mike Gleason firewall role][mikegleasonjr firewall github] ( * **nft_main_conf_content** : Template used to generate the previous main configuration file [default : `etc/nftables.conf.j2`]. * **nft_input_conf_path** : Input configuration file include in main configuration file [default : `/etc/nftables.d/inet-input.nft`]. * **nft_input_conf_content** : Template used to generate the previous input configuration file [default : `etc/nftables.d/inet-input.nft.j2`]. +* **nft_define_conf_path** : Vars definition file include in main configuration file [default : `/etc/nftables.d/defines.nft`]. +* **nft_define_conf_content** : Template used to generate the previous vars definition file [default : `etc/nftables.d/defines.nft.j2`]. +* **nft_sets_conf_path** : Sets and maps definition file include in main configuration file [default : `/etc/nftables.d/inet-sets.nft`]. +* **nft_sets_conf_content** : Template used to generate the previous sets and maps definition file [default : `etc/nftables.d/inet-sets.nft.j2`]. * **nft_global_default_rules** : Set default rules for `global` chain. Other chains will jump to `global` before apply their specific rules. * **nft_global_group_rules** : You can add `global` rules or override those defined by **nft_global_default_rules** for a group. * **nft_global_host_rules:** : Hosts can also add or override `global` rules. @@ -63,10 +67,25 @@ nft_global_host_rules: {} nft_input_default_rules: 000 policy: - type filter hook input priority 0; policy drop; - 001 global: + 005 global: - jump global nft_input_group_rules: {} nft_input_host_rules: {} + +# define nft vars +nft_define_default: + broadcast and multicast: + desc: 'broadcast and multicast' + name: badcast_addr + value: '{ 255.255.255.255, 224.0.0.1, 224.0.0.251 }' +nft_define_group: {} +nft_define_host: {} +nft_set_default: + blackhole: + - type ipv4_addr; + - elements = $badcast_addr +nft_set_group: {} +nft_set_host: {} ``` Those default will generate the following configuration : @@ -74,20 +93,19 @@ Those default will generate the following configuration : #!/usr/sbin/nft -f # Ansible managed - # clean flush ruleset +include "/etc/nftables.d/defines.nft" + table inet firewall { chain global { # 000 state management ct state established,related accept ct state invalid drop } - chain input { - type filter hook input priority 0; policy drop; - jump global - } + include "/etc/nftables.d/inet-sets.nft" + include "/etc/nftables.d/inet-input.nft" chain output { type filter hook output priority 0; jump global @@ -99,6 +117,11 @@ And you get the same result by displaying the ruleset on the host : `$ nft lis ``` table inet firewall { + set blackhole { + type ipv4_addr + elements = { 255.255.255.255, 224.0.0.1, 224.0.0.251 } + } + chain global { ct state established,related accept ct state invalid drop @@ -148,8 +171,9 @@ nft_input_group_rules: This role will : * Install `nftables` on the system. -* Generate a default configuration file loaded by systemd unit. +* Generate a default configuration file which include all following files and loaded by systemd unit. * Generate input rules file include called by the main configuration file. +* Generate vars in a file and sets and maps in another file. * Restart `nftables` service. ## Development diff --git a/defaults/main.yml b/defaults/main.yml index 1a2fa2e..103332f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -12,6 +12,8 @@ nft_input_conf_path: '/etc/nftables.d/inet-input.nft' nft_input_conf_content: 'etc/nftables.d/inet-input.nft.j2' nft_define_conf_path: '/etc/nftables.d/defines.nft' nft_define_conf_content: 'etc/nftables.d/defines.nft.j2' +nft_set_conf_path: '/etc/nftables.d/inet-sets.nft' +nft_set_conf_content: 'etc/nftables.d/inet-sets.nft.j2' # rules nft_global_default_rules: @@ -23,7 +25,7 @@ nft_global_host_rules: {} nft_input_default_rules: 000 policy: - type filter hook input priority 0; policy drop; - 001 global: + 005 global: - jump global nft_input_group_rules: {} nft_input_host_rules: {} @@ -36,6 +38,12 @@ nft_define_default: value: '{ 255.255.255.255, 224.0.0.1, 224.0.0.251 }' nft_define_group: {} nft_define_host: {} +nft_set_default: + blackhole: + - type ipv4_addr; + - elements = $badcast_addr +nft_set_group: {} +nft_set_host: {} # service nft_service_manage: true diff --git a/tasks/main.yml b/tasks/main.yml index 3148881..86c6a90 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -49,4 +49,14 @@ mode: 0755 backup: yes notify: restart nftables service + +- name: generate sets and maps file + template: + src: "{{ nft_set_conf_content }}" + dest: "{{ nft_set_conf_path }}" + owner: root + group: root + mode: 0755 + backup: yes + notify: restart nftables service # }}} diff --git a/templates/etc/nftables.conf.j2 b/templates/etc/nftables.conf.j2 index 92735c7..b8bb683 100755 --- a/templates/etc/nftables.conf.j2 +++ b/templates/etc/nftables.conf.j2 @@ -21,6 +21,7 @@ table inet firewall { {% endfor %} {% endfor %} } + include "{{ nft_set_conf_path }}" include "{{ nft_input_conf_path }}" chain output { type filter hook output priority 0; diff --git a/templates/etc/nftables.d/inet-sets.nft.j2 b/templates/etc/nftables.d/inet-sets.nft.j2 new file mode 100644 index 0000000..0b2a8a9 --- /dev/null +++ b/templates/etc/nftables.d/inet-sets.nft.j2 @@ -0,0 +1,15 @@ +# {{ ansible_managed }} +{% set setmerged = nft_set_default.copy() %} +{% set _ = setmerged.update(nft_set_group) %} +{% set _ = setmerged.update(nft_set_host) %} + +{% for set, rules in setmerged|dictsort %} +{% if rules %} +set {{ set }} { +{% for rule in rules %} + {{ rule }} +{% endfor %} +} +{% endif %} + +{% endfor %}