Support merged firewall rules for multiple groups per host.
- Multiple groups for a single server will now lead to all firewall
    rules being merged instead of overwritten.
			
			
This commit is contained in:
		
							parent
							
								
									6e1c48ee99
								
							
						
					
					
						commit
						290a86e906
					
				|  | @ -74,6 +74,17 @@ nft_global_default_rules: | |||
| # in the Ansible inventory. | ||||
| nft_global_rules: {} | ||||
|                                                                    # ]]] | ||||
| # .. envvar:: merged_groups [[[ | ||||
| # | ||||
| # Enable or disable the ability to merge multiple firewall group variables | ||||
| merged_groups: false | ||||
|                                                                    # ]]] | ||||
| # .. envvar:: merged_groups_dir [[[ | ||||
| # | ||||
| # The directory to read the group firewall rules from. | ||||
| # Relative to the playbook directory. | ||||
| merged_groups_dir: vars/ | ||||
|                                                                    # ]]] | ||||
| # .. envvar:: nft_global_group_rules [[[ | ||||
| # | ||||
| # List of global rules (applied on all tables) to configure for hosts in | ||||
|  |  | |||
|  | @ -2,16 +2,33 @@ | |||
| # .. vim: foldmarker=[[[,]]]:foldmethod=marker | ||||
| # | ||||
| # tasks file for nftables | ||||
| - name: Import nftables-variables if merged_groups is set | ||||
|   when: merged_groups | ||||
|   set_fact: | ||||
|     "{{ groupname }}": "{{ lookup('file',merged_groups_dir ~ groupname) | from_yaml }}" | ||||
|   loop: "{{ group_names }}" | ||||
|   loop_control: | ||||
|     loop_var: groupname | ||||
| 
 | ||||
| - name: Combine Rules when merged_groups is set | ||||
|   when: merged_groups | ||||
|   set_fact: | ||||
|     nft_combined_rules: "{{ nft_combined_rules | default({}) | combine ( hostvars[inventory_hostname][groupname], recursive=True ) }}" | ||||
|   loop: "{{ group_names }}" | ||||
|   loop_control: | ||||
|     loop_var: groupname | ||||
| 
 | ||||
| - 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,7 +36,7 @@ | |||
|   until: pkg_install_result is success | ||||
|   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: | ||||
|     name: '{{ nft_old_pkg_list | list }}' | ||||
|     state: '{{ nft_old_pkg_state }}' | ||||
|  |  | |||
|  | @ -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 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 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 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 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 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 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 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 %} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue