Merge branch 'p-rintz-master'
This commit is contained in:
commit
0df963cd86
39
README.md
39
README.md
|
@ -70,6 +70,9 @@ Highly inspired by [Mike Gleason firewall role][mikegleasonjr firewall github] (
|
||||||
* **nft_service_enabled** : Set `nftables` service available at startup [default : `true`].
|
* **nft_service_enabled** : Set `nftables` service available at startup [default : `true`].
|
||||||
* **nft__service_protect** : If systemd unit should protect system and home [default : `true`].
|
* **nft__service_protect** : If systemd unit should protect system and home [default : `true`].
|
||||||
* **nft__fail2ban_service** : If the Nftables service should also restart the Fail2ban service [default : `False`].
|
* **nft__fail2ban_service** : If the Nftables service should also restart the Fail2ban service [default : `False`].
|
||||||
|
* **nft_merged_groups** : If variables from the hosts Ansible groups should be merged [default : `false`].
|
||||||
|
* **nft_merged_groups_dir** : The dictionary where the nftables group rules, named like the Ansible groups, are located in [default : `vars/`].
|
||||||
|
* **nft_debug** : Toggle more verbose output on/off. [default: 'false'].
|
||||||
|
|
||||||
### OS Specific Variables
|
### OS Specific Variables
|
||||||
|
|
||||||
|
@ -83,6 +86,7 @@ Each type of rules dictionaries will be merged and rules will be applied in the
|
||||||
* **nft_*_default_rules** : Define default rules for all nodes. You can define it in `group_vars/all`.
|
* **nft_*_default_rules** : Define default rules for all nodes. You can define it in `group_vars/all`.
|
||||||
* **nft_*_rules** : Can add rules and override those defined by **nft_*_default_rules**. You can define it in `group_vars/all`.
|
* **nft_*_rules** : Can add rules and override those defined by **nft_*_default_rules**. You can define it in `group_vars/all`.
|
||||||
* **nft_*_group_rules** : Can add rules and override those defined by **nft_*_default_rules** and **nft_*_rules**. You can define it in `group_vars/webservers`.
|
* **nft_*_group_rules** : Can add rules and override those defined by **nft_*_default_rules** and **nft_*_rules**. You can define it in `group_vars/webservers`.
|
||||||
|
* If 'nft_merged_groups' is set to true, multiple group rules from the ansible groups will also be merged together.
|
||||||
* **nft_*_host_rules** : Can add rules and override those define by **nft_*_default_rules**, **nft_*_group_rules** and **nft_*_rules**. You can define it in `host_vars/www.local.domain`.
|
* **nft_*_host_rules** : Can add rules and override those define by **nft_*_default_rules**, **nft_*_group_rules** and **nft_*_rules**. You can define it in `host_vars/www.local.domain`.
|
||||||
|
|
||||||
`defaults/main.yml`:
|
`defaults/main.yml`:
|
||||||
|
@ -94,6 +98,8 @@ nft_global_default_rules:
|
||||||
- ct state established,related accept
|
- ct state established,related accept
|
||||||
- ct state invalid drop
|
- ct state invalid drop
|
||||||
nft_global_rules: {}
|
nft_global_rules: {}
|
||||||
|
nft_merged_groups: false
|
||||||
|
nft_merged_groups_dir: vars/
|
||||||
nft_global_group_rules: {}
|
nft_global_group_rules: {}
|
||||||
nft_global_host_rules: {}
|
nft_global_host_rules: {}
|
||||||
|
|
||||||
|
@ -283,6 +289,39 @@ nft_input_group_rules:
|
||||||
- counter
|
- counter
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Use merged group rules from multiple ansible groups:
|
||||||
|
|
||||||
|
``` yml
|
||||||
|
- hosts: serverXYZ
|
||||||
|
vars:
|
||||||
|
nft_merged_groups: true
|
||||||
|
nft_merged_groups_dir: vars/
|
||||||
|
roles:
|
||||||
|
- role: ipr-cnrs.nftables
|
||||||
|
```
|
||||||
|
|
||||||
|
And put the rules inside the "vars" folder named after your ansible groups of the server:
|
||||||
|
|
||||||
|
`vars/first_group` :
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
nft_input_group_rules:
|
||||||
|
020 icmp:
|
||||||
|
- ip protocol icmp icmp type echo-request ip length <= 84 counter limit rate 1/minute accept
|
||||||
|
999 count policy packet:
|
||||||
|
- counter
|
||||||
|
```
|
||||||
|
|
||||||
|
`vars/second_group` :
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
nft_input_group_rules:
|
||||||
|
021 LAN:
|
||||||
|
- iif eth0 accept
|
||||||
|
```
|
||||||
|
|
||||||
|
These rulesets from the two groups will be merged if the host has the two groups as ansible roles.
|
||||||
|
|
||||||
## Known Issue
|
## Known Issue
|
||||||
|
|
||||||
* The 10 minutes delay at the first run is finally fixed by allowing the host to reset SSH connection (flags `rst, psh | ack`) (see #1).
|
* The 10 minutes delay at the first run is finally fixed by allowing the host to reset SSH connection (flags `rst, psh | ack`) (see #1).
|
||||||
|
|
|
@ -74,6 +74,17 @@ nft_global_default_rules:
|
||||||
# in the Ansible inventory.
|
# in the Ansible inventory.
|
||||||
nft_global_rules: {}
|
nft_global_rules: {}
|
||||||
# ]]]
|
# ]]]
|
||||||
|
# .. envvar:: nft_merged_groups [[[
|
||||||
|
#
|
||||||
|
# Enable or disable the ability to merge multiple firewall group variables
|
||||||
|
nft_merged_groups: false
|
||||||
|
# ]]]
|
||||||
|
# .. envvar:: nft_merged_groups_dir [[[
|
||||||
|
#
|
||||||
|
# The directory to read the group firewall rules from.
|
||||||
|
# Relative to the playbook directory.
|
||||||
|
nft_merged_groups_dir: vars/
|
||||||
|
# ]]]
|
||||||
# .. envvar:: nft_global_group_rules [[[
|
# .. envvar:: nft_global_group_rules [[[
|
||||||
#
|
#
|
||||||
# List of global rules (applied on all tables) to configure for hosts in
|
# List of global rules (applied on all tables) to configure for hosts in
|
||||||
|
@ -514,5 +525,17 @@ nft__service_protect: true
|
||||||
# Any Nftables service (re)start will also restart Fail2ban service.
|
# Any Nftables service (re)start will also restart Fail2ban service.
|
||||||
nft__fail2ban_service: False
|
nft__fail2ban_service: False
|
||||||
# ]]]
|
# ]]]
|
||||||
|
# .. envvar:: nft_debug [
|
||||||
|
#
|
||||||
|
# Toggle on/off more verbose output. Possible options are:
|
||||||
|
#
|
||||||
|
# ''Flase''
|
||||||
|
# Default. No additional output will be given.
|
||||||
|
#
|
||||||
|
# ''True''
|
||||||
|
# More verbose output.
|
||||||
|
nft_debug: False
|
||||||
|
|
||||||
|
# ]]]
|
||||||
# ]]]
|
# ]]]
|
||||||
# ]]]
|
# ]]]
|
||||||
|
|
|
@ -3,15 +3,50 @@
|
||||||
#
|
#
|
||||||
# tasks file for nftables
|
# tasks file for nftables
|
||||||
|
|
||||||
|
- name: Check for group files
|
||||||
|
become: no
|
||||||
|
delegate_to: localhost
|
||||||
|
stat:
|
||||||
|
path: "{{ nft_merged_groups_dir ~ groupname }}"
|
||||||
|
register: nftables_group_rules
|
||||||
|
loop: "{{ group_names }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: groupname
|
||||||
|
|
||||||
|
- debug: var=nftables_group_rules
|
||||||
|
when: nft_debug
|
||||||
|
|
||||||
|
- name: Import nftables-variables if nft_merged_groups is set
|
||||||
|
when: nft_merged_groups and varfile.stat.exists
|
||||||
|
include_vars:
|
||||||
|
file: "{{ nft_merged_groups_dir ~ varfile.groupname }}"
|
||||||
|
name: "{{ varfile.groupname }}"
|
||||||
|
loop: "{{ nftables_group_rules.results }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: varfile
|
||||||
|
|
||||||
|
- name: Combine Rules when nft_merged_groups is set
|
||||||
|
when: nft_merged_groups and (hostvars[inventory_hostname][varfile.groupname] is defined and hostvars[inventory_hostname][varfile.groupname]|length > 0) and varfile.stat.exists
|
||||||
|
set_fact:
|
||||||
|
nft_combined_rules: "{{ nft_combined_rules | default({}) | combine ( hostvars[inventory_hostname][varfile.groupname], recursive=True ) }}"
|
||||||
|
loop: "{{ nftables_group_rules.results }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: varfile
|
||||||
|
|
||||||
|
- debug: var=nft_combined_rules
|
||||||
|
when: nft_debug
|
||||||
|
|
||||||
- name: Load specific OS vars for nftables
|
- name: Load specific OS vars for nftables
|
||||||
include_vars: "{{ item }}"
|
include_vars: "{{ osname }}"
|
||||||
with_first_found:
|
with_first_found:
|
||||||
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_version }}.yml"
|
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_version }}.yml"
|
||||||
- "{{ ansible_distribution|lower }}.yml"
|
- "{{ ansible_distribution|lower }}.yml"
|
||||||
- "{{ ansible_os_family|lower }}.yml"
|
- "{{ ansible_os_family|lower }}.yml"
|
||||||
|
loop_control:
|
||||||
|
loop_var: osname
|
||||||
|
|
||||||
# Manage packages [[[1
|
# Manage packages [[[1
|
||||||
- name: Ensure Nftables packages are in there desired state
|
- name: Ensure Nftables packages are in their desired state
|
||||||
package:
|
package:
|
||||||
name: '{{ nft_pkg_list | list }}'
|
name: '{{ nft_pkg_list | list }}'
|
||||||
state: '{{ nft_pkg_state }}'
|
state: '{{ nft_pkg_state }}'
|
||||||
|
@ -19,8 +54,8 @@
|
||||||
until: pkg_install_result is success
|
until: pkg_install_result is success
|
||||||
when: nft_enabled|bool
|
when: nft_enabled|bool
|
||||||
|
|
||||||
- name: Ensure old Iptables packages are in there desired state
|
- name: Ensure old Iptables packages are in their desired state
|
||||||
apt:
|
package:
|
||||||
name: '{{ nft_old_pkg_list | list }}'
|
name: '{{ nft_old_pkg_list | list }}'
|
||||||
state: '{{ nft_old_pkg_state }}'
|
state: '{{ nft_old_pkg_state }}'
|
||||||
register: pkg_remove_result
|
register: pkg_remove_result
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
#!/usr/sbin/nft -f
|
#!/usr/sbin/nft -f
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set globalmerged = nft_global_default_rules.copy() %}
|
{% set globalmerged = nft_global_default_rules.copy() %}
|
||||||
{% set _ = globalmerged.update(nft_global_rules) %}
|
{% set _ = globalmerged.update(nft_global_rules) %}
|
||||||
{% set _ = globalmerged.update(nft_global_group_rules) %}
|
{% set _ = globalmerged.update(nft_global_group_rules) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft_global_group_rules is defined%}
|
||||||
|
{% set _ = globalmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft_global_group_rules) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = globalmerged.update(nft_global_host_rules) %}
|
{% set _ = globalmerged.update(nft_global_host_rules) %}
|
||||||
|
|
||||||
# clean
|
# clean
|
||||||
|
@ -14,12 +18,12 @@ table inet filter {
|
||||||
chain global {
|
chain global {
|
||||||
{% for group, rules in globalmerged|dictsort %}
|
{% for group, rules in globalmerged|dictsort %}
|
||||||
# {{ group }}
|
# {{ group }}
|
||||||
{% if not rules %}
|
{% if not rules %}
|
||||||
# (none)
|
# (none)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
include "{{ nft_set_conf_path }}"
|
include "{{ nft_set_conf_path }}"
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set definemerged = nft_define_default.copy() %}
|
{% set definemerged = nft_define_default.copy() %}
|
||||||
{% set _ = definemerged.update(nft_define) %}
|
{% set _ = definemerged.update(nft_define) %}
|
||||||
{% set _ = definemerged.update(nft_define_group) %}
|
{% set _ = definemerged.update(nft_define_group) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft_define_group is defined%}
|
||||||
|
{% set _ = definemerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft_define_group) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = definemerged.update(nft_define_host) %}
|
{% set _ = definemerged.update(nft_define_host) %}
|
||||||
|
|
||||||
|
|
||||||
{% for definition in definemerged.values() %}
|
{% for definition in definemerged.values() %}
|
||||||
{% if definition.desc is defined %}
|
{% if definition.desc is defined %}
|
||||||
# {{ definition.desc }}
|
# {{ definition.desc }}
|
||||||
{% else %}
|
{% else %}
|
||||||
# {{ definition.name }}
|
# {{ definition.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
define {{ definition.name }} = {{ definition.value }}
|
define {{ definition.name }} = {{ definition.value }}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set inputmerged = nft_input_default_rules.copy() %}
|
{% set inputmerged = nft_input_default_rules.copy() %}
|
||||||
{% set _ = inputmerged.update(nft_input_rules) %}
|
{% set _ = inputmerged.update(nft_input_rules) %}
|
||||||
{% set _ = inputmerged.update(nft_input_group_rules) %}
|
{% set _ = inputmerged.update(nft_input_group_rules) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft_input_group_rules is defined %}
|
||||||
|
{% set _ = inputmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft_input_group_rules) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = inputmerged.update(nft_input_host_rules) %}
|
{% set _ = inputmerged.update(nft_input_host_rules) %}
|
||||||
|
|
||||||
chain input {
|
chain input {
|
||||||
{% for group, rules in inputmerged|dictsort %}
|
{% for group, rules in inputmerged|dictsort %}
|
||||||
# {{ group }}
|
# {{ group }}
|
||||||
{% if not rules %}
|
{% if not rules %}
|
||||||
# (none)
|
# (none)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set outputmerged = nft_output_default_rules.copy() %}
|
{% set outputmerged = nft_output_default_rules.copy() %}
|
||||||
{% set _ = outputmerged.update(nft_output_rules) %}
|
{% set _ = outputmerged.update(nft_output_rules) %}
|
||||||
{% set _ = outputmerged.update(nft_output_group_rules) %}
|
{% set _ = outputmerged.update(nft_output_group_rules) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft_output_group_rules is defined %}
|
||||||
|
{% set _ = outputmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft_output_group_rules) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = outputmerged.update(nft_output_host_rules) %}
|
{% set _ = outputmerged.update(nft_output_host_rules) %}
|
||||||
|
|
||||||
chain output {
|
chain output {
|
||||||
{% for group, rules in outputmerged|dictsort %}
|
{% for group, rules in outputmerged|dictsort %}
|
||||||
# {{ group }}
|
# {{ group }}
|
||||||
{% if not rules %}
|
{% if not rules %}
|
||||||
# (none)
|
# (none)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set postroutingmerged = nft__nat_default_postrouting_rules.copy() %}
|
{% set postroutingmerged = nft__nat_default_postrouting_rules.copy() %}
|
||||||
{% set _ = postroutingmerged.update(nft__nat_postrouting_rules) %}
|
{% set _ = postroutingmerged.update(nft__nat_postrouting_rules) %}
|
||||||
{% set _ = postroutingmerged.update(nft__nat_group_postrouting_rules) %}
|
{% set _ = postroutingmerged.update(nft__nat_group_postrouting_rules) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft__nat_group_postrouting_rules is defined %}
|
||||||
|
{% set _ = postroutingmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft__nat_group_postrouting_rules) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = postroutingmerged.update(nft__nat_host_postrouting_rules) %}
|
{% set _ = postroutingmerged.update(nft__nat_host_postrouting_rules) %}
|
||||||
|
|
||||||
chain postrouting {
|
chain postrouting {
|
||||||
{% for group, rules in postroutingmerged|dictsort %}
|
{% for group, rules in postroutingmerged|dictsort %}
|
||||||
# {{ group }}
|
# {{ group }}
|
||||||
{% if not rules %}
|
{% if not rules %}
|
||||||
# (none)
|
# (none)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set preroutingmerged = nft__nat_default_prerouting_rules.copy() %}
|
{% set preroutingmerged = nft__nat_default_prerouting_rules.copy() %}
|
||||||
{% set _ = preroutingmerged.update(nft__nat_prerouting_rules) %}
|
{% set _ = preroutingmerged.update(nft__nat_prerouting_rules) %}
|
||||||
{% set _ = preroutingmerged.update(nft__nat_group_prerouting_rules) %}
|
{% set _ = preroutingmerged.update(nft__nat_group_prerouting_rules) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft__nat_group_prerouting_rules is defined %}
|
||||||
|
{% set _ = preroutingmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft__nat_group_prerouting_rules) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = preroutingmerged.update(nft__nat_host_prerouting_rules) %}
|
{% set _ = preroutingmerged.update(nft__nat_host_prerouting_rules) %}
|
||||||
|
|
||||||
chain prerouting {
|
chain prerouting {
|
||||||
{% for group, rules in preroutingmerged|dictsort %}
|
{% for group, rules in preroutingmerged|dictsort %}
|
||||||
# {{ group }}
|
# {{ group }}
|
||||||
{% if not rules %}
|
{% if not rules %}
|
||||||
# (none)
|
# (none)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
|
#jinja2: lstrip_blocks: "True", trim_blocks: "True"
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% set setmerged = nft_set_default.copy() %}
|
{% set setmerged = nft_set_default.copy() %}
|
||||||
{% set _ = setmerged.update(nft_set) %}
|
{% set _ = setmerged.update(nft_set) %}
|
||||||
{% set _ = setmerged.update(nft_set_group) %}
|
{% set _ = setmerged.update(nft_set_group) %}
|
||||||
|
{% if nft_merged_groups and hostvars[inventory_hostname]['nft_combined_rules'].nft_set_group is defined %}
|
||||||
|
{% set _ = setmerged.update(hostvars[inventory_hostname]['nft_combined_rules'].nft_set_group) %}
|
||||||
|
{% endif %}
|
||||||
{% set _ = setmerged.update(nft_set_host) %}
|
{% set _ = setmerged.update(nft_set_host) %}
|
||||||
|
|
||||||
{% for set, rules in setmerged|dictsort %}
|
{% for set, rules in setmerged|dictsort %}
|
||||||
{% if rules %}
|
{% if rules %}
|
||||||
set {{ set }} {
|
set {{ set }} {
|
||||||
{% for rule in rules %}
|
{% for rule in rules %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
# vars file for Centos-based distros
|
||||||
|
nft_pkg_list:
|
||||||
|
- nftables
|
Loading…
Reference in New Issue