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_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_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 | ||||
| 
 | ||||
|  | @ -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_*_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`. | ||||
|     * 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`. | ||||
| 
 | ||||
| `defaults/main.yml`: | ||||
|  | @ -94,6 +98,8 @@ nft_global_default_rules: | |||
|     - ct state established,related accept | ||||
|     - ct state invalid drop | ||||
| nft_global_rules: {} | ||||
| nft_merged_groups: false | ||||
| nft_merged_groups_dir: vars/ | ||||
| nft_global_group_rules: {} | ||||
| nft_global_host_rules: {} | ||||
| 
 | ||||
|  | @ -283,6 +289,39 @@ nft_input_group_rules: | |||
|     - 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 | ||||
| 
 | ||||
| * 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. | ||||
| 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 [[[ | ||||
| # | ||||
| # 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. | ||||
| 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 | ||||
| 
 | ||||
| - 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 | ||||
|   include_vars: "{{ item }}" | ||||
|   include_vars: "{{ osname }}" | ||||
|   with_first_found: | ||||
|     - "{{ ansible_distribution|lower }}-{{ ansible_distribution_version }}.yml" | ||||
|     - "{{ ansible_distribution|lower }}.yml" | ||||
|     - "{{ ansible_os_family|lower }}.yml" | ||||
|   loop_control: | ||||
|     loop_var: osname | ||||
| 
 | ||||
| # Manage packages [[[1 | ||||
| - name: Ensure Nftables packages are in there desired state | ||||
| - name: Ensure Nftables packages are in their desired state | ||||
|   package: | ||||
|     name: '{{ nft_pkg_list | list }}' | ||||
|     state: '{{ nft_pkg_state }}' | ||||
|  | @ -19,8 +54,8 @@ | |||
|   until: pkg_install_result is success | ||||
|   when: nft_enabled|bool | ||||
| 
 | ||||
| - name: Ensure old Iptables packages are in there desired state | ||||
|   apt: | ||||
| - name: Ensure old Iptables packages are in their desired state | ||||
|   package: | ||||
|     name: '{{ nft_old_pkg_list | list }}' | ||||
|     state: '{{ nft_old_pkg_state }}' | ||||
|   register: pkg_remove_result | ||||
|  |  | |||
|  | @ -1,8 +1,12 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| #!/usr/sbin/nft -f | ||||
| # {{ ansible_managed }} | ||||
| {% set globalmerged = nft_global_default_rules.copy() %} | ||||
| {% set _ = globalmerged.update(nft_global_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) %} | ||||
| 
 | ||||
| # clean | ||||
|  | @ -14,12 +18,12 @@ table inet filter { | |||
| 	chain global { | ||||
| {% for group, rules in globalmerged|dictsort  %} | ||||
| 		# {{ group }} | ||||
| {% if not rules %} | ||||
|   {% if not rules %} | ||||
| 		# (none) | ||||
| {% endif %} | ||||
| {% for rule in rules %} | ||||
|   {% endif %} | ||||
|   {% for rule in rules %} | ||||
| 		{{ rule }} | ||||
| {% endfor %} | ||||
|   {% endfor %} | ||||
| {% endfor %} | ||||
| 	} | ||||
| 	include "{{ nft_set_conf_path }}" | ||||
|  |  | |||
|  | @ -1,16 +1,19 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set definemerged = nft_define_default.copy() %} | ||||
| {% set _ = definemerged.update(nft_define) %} | ||||
| {% 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) %} | ||||
| 
 | ||||
| 
 | ||||
| {% for definition in definemerged.values() %} | ||||
| {% if definition.desc is defined %} | ||||
|   {% if definition.desc is defined %} | ||||
| # {{ definition.desc }} | ||||
| {% else %} | ||||
|   {% else %} | ||||
| # {{ definition.name }} | ||||
| {% endif %} | ||||
|   {% endif %} | ||||
| define {{ definition.name }} = {{ definition.value }} | ||||
| 
 | ||||
| {% endfor %} | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set inputmerged = nft_input_default_rules.copy() %} | ||||
| {% set _ = inputmerged.update(nft_input_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) %} | ||||
| 
 | ||||
| chain input { | ||||
| {% for group, rules in inputmerged|dictsort  %} | ||||
| 	# {{ group }} | ||||
| {% if not rules %} | ||||
|   {% if not rules %} | ||||
| 	# (none) | ||||
| {% endif %} | ||||
| {% for rule in rules %} | ||||
|   {% endif %} | ||||
|   {% for rule in rules %} | ||||
| 	{{ rule }} | ||||
| {% endfor %} | ||||
|   {% endfor %} | ||||
| {% endfor %} | ||||
| } | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set outputmerged = nft_output_default_rules.copy() %} | ||||
| {% set _ = outputmerged.update(nft_output_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) %} | ||||
| 
 | ||||
| chain output { | ||||
| {% for group, rules in outputmerged|dictsort  %} | ||||
| 	# {{ group }} | ||||
| {% if not rules %} | ||||
|   {% if not rules %} | ||||
| 	# (none) | ||||
| {% endif %} | ||||
| {% for rule in rules %} | ||||
|   {% endif %} | ||||
|   {% for rule in rules %} | ||||
| 	{{ rule }} | ||||
| {% endfor %} | ||||
|   {% endfor %} | ||||
| {% endfor %} | ||||
| } | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set postroutingmerged = nft__nat_default_postrouting_rules.copy() %} | ||||
| {% set _ = postroutingmerged.update(nft__nat_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) %} | ||||
| 
 | ||||
| chain postrouting { | ||||
| {% for group, rules in postroutingmerged|dictsort  %} | ||||
| 	# {{ group }} | ||||
| {% if not rules %} | ||||
|   {% if not rules %} | ||||
| 	# (none) | ||||
| {% endif %} | ||||
| {% for rule in rules %} | ||||
|   {% endif %} | ||||
|   {% for rule in rules %} | ||||
| 	{{ rule }} | ||||
| {% endfor %} | ||||
|   {% endfor %} | ||||
| {% endfor %} | ||||
| } | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set preroutingmerged = nft__nat_default_prerouting_rules.copy() %} | ||||
| {% set _ = preroutingmerged.update(nft__nat_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) %} | ||||
| 
 | ||||
| chain prerouting { | ||||
| {% for group, rules in preroutingmerged|dictsort  %} | ||||
| 	# {{ group }} | ||||
| {% if not rules %} | ||||
|   {% if not rules %} | ||||
| 	# (none) | ||||
| {% endif %} | ||||
| {% for rule in rules %} | ||||
|   {% endif %} | ||||
|   {% for rule in rules %} | ||||
| 	{{ rule }} | ||||
| {% endfor %} | ||||
|   {% endfor %} | ||||
| {% endfor %} | ||||
| } | ||||
|  |  | |||
|  | @ -1,16 +1,20 @@ | |||
| #jinja2: lstrip_blocks: "True", trim_blocks: "True" | ||||
| # {{ ansible_managed }} | ||||
| {% set setmerged = nft_set_default.copy() %} | ||||
| {% set _ = setmerged.update(nft_set) %} | ||||
| {% 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) %} | ||||
| 
 | ||||
| {% for set, rules in setmerged|dictsort  %} | ||||
| {% if rules %} | ||||
|   {% if rules %} | ||||
| set {{ set }} { | ||||
| {% for rule in rules %} | ||||
|     {% for rule in rules %} | ||||
| 	{{ rule }} | ||||
| {% endfor %} | ||||
|     {% endfor %} | ||||
| } | ||||
| {% endif %} | ||||
|   {% endif %} | ||||
| 
 | ||||
| {% endfor %} | ||||
|  |  | |||
|  | @ -0,0 +1,4 @@ | |||
| --- | ||||
| # vars file for Centos-based distros | ||||
| nft_pkg_list: | ||||
|   - nftables | ||||
		Loading…
	
		Reference in New Issue