There is a way to manage tables in rules, but there is no way to manage tables for chains when setting policy. Looks like pillar structure is bad from the beginning and to not break backward compatibility, as same chain names may occur in different tables, so it is proposed to check if 'chain.policy' is map. And if it is, specific policies would be ensured for specific tables, otherwise table 'filter' would be used as a fallback. To ensure chains in specific tables we iterate over all rules in each chain. This hash is valid: parameters: iptables: service: enabled: true chain: OUTPUT: policy: ACCEPT FORWARD: policy: - table: mangle policy: DROP INPUT: policy: - table: nat policy: ACCEPT rules: - jump: ACCEPT protocol: icmp POSTROUTING: rules: - jump: MASQUERADE protocol: icmp out_interface: ens3 table: nat Prod-Related: CEEMCP-12 Prod-Related: EME-313 Change-Id: Ib5ba97dad165d3ef2dec7e053b391ea36a996103pull/19/head
source_network: 2001:DB8::/32 | source_network: 2001:DB8::/32 | ||||
jump: ACCEPT | jump: ACCEPT | ||||
You may set policy for chain in specific table | |||||
If 'table' key is omitted, 'filter' table is assumed | |||||
.. code-block:: yaml | |||||
parameters: | |||||
iptables: | |||||
service: | |||||
enabled: true | |||||
chain: | |||||
OUTPUT: | |||||
policy: ACCEPT | |||||
Specify policy directly | |||||
.. code-block:: yaml | |||||
parameters: | |||||
iptables: | |||||
service: | |||||
enabled: true | |||||
chain: | |||||
FORWARD: | |||||
policy: | |||||
- table: mangle | |||||
policy: DROP | |||||
Read more | Read more | ||||
========= | ========= | ||||
iptables_{{ chain_name }}_{{ rule_name }}: | |||||
{%- set table = rule.get('table', 'filter') %} | |||||
iptables_{{ table }}_{{ chain_name }}_{{ rule_name }}: | |||||
{%- if rule.position is defined %} | {%- if rule.position is defined %} | ||||
iptables.insert: | iptables.insert: | ||||
- position: {{ rule.position }} | - position: {{ rule.position }} | ||||
{%- else %} | {%- else %} | ||||
iptables.append: | iptables.append: | ||||
- require: | - require: | ||||
{%- if loop.index != 1 %} | |||||
- iptables: iptables_{{ chain_name }}_{% if service_name is defined %}{{ service_name }}_{% endif %}{{ loop.index - 1 }} | |||||
{%- else %} | |||||
{%- for chain in chains %} | |||||
- iptables: iptables_{{ chain }} | |||||
{%- endfor %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
- table: {{ rule.get('table', 'filter') }} | |||||
{%- if loop.index != 1 %} | |||||
- iptables: iptables_{{ table }}_{{ chain_name }}_{% if service_name is defined %}{{ service_name }}_{% endif %}{{ loop.index - 1 }} | |||||
{%- else %} | |||||
{%- for chain in chains %} | |||||
- iptables: iptables_{{ table }}_{{ chain }} | |||||
{%- endfor %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
- table: {{ table }} | |||||
- chain: {{ chain_name }} | - chain: {{ chain_name }} | ||||
{%- if rule.family is defined %} | {%- if rule.family is defined %} | ||||
- family: {{ rule.family }} | - family: {{ rule.family }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.destination_ports is defined %} | {%- if rule.destination_ports is defined %} | ||||
- dports: | - dports: | ||||
{%- for port in rule.destination_ports %} | |||||
{%- for port in rule.destination_ports %} | |||||
- {{ port }} | - {{ port }} | ||||
{% endfor %} | |||||
{% endfor %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.source_port is defined %} | {%- if rule.source_port is defined %} | ||||
- sport: {{ rule.source_port }} | - sport: {{ rule.source_port }} | ||||
{%- if rule.to_source is defined %} | {%- if rule.to_source is defined %} | ||||
- to-source: {{ rule.to_source }} | - to-source: {{ rule.to_source }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.source_network is defined %} | |||||
{%- if rule.source_network is defined %} | |||||
- source: {{ rule.source_network }} | - source: {{ rule.source_network }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.destination_network is defined %} | |||||
{%- if rule.destination_network is defined %} | |||||
- destination: {{ rule.destination_network }} | - destination: {{ rule.destination_network }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.log_prefix is defined %} | |||||
{%- if rule.log_prefix is defined %} | |||||
- log-prefix: '{{ rule.log_prefix }}' | - log-prefix: '{{ rule.log_prefix }}' | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.log_level is defined %} | |||||
{%- if rule.log_level is defined %} | |||||
- log-level: {{ rule.log_level }} | - log-level: {{ rule.log_level }} | ||||
{%- endif %} | {%- endif %} | ||||
{%- if rule.limit is defined %} | |||||
{%- if rule.limit is defined %} | |||||
- limit: '{{ rule.limit }}' | - limit: '{{ rule.limit }}' | ||||
{%- endif %} | {%- endif %} | ||||
{%- if chain.policy is defined %} | {%- if chain.policy is defined %} | ||||
{%- if chain.policy is string %} | |||||
- require_in: | |||||
- iptables: iptables_filter_{{ chain_name }}_policy | |||||
{%- else %} | |||||
{%- if table in chain.policy %} | |||||
- require_in: | - require_in: | ||||
- iptables: iptables_{{ chain_name }}_policy | |||||
- iptables: iptables_{{ table }}_{{ chain_name }}_policy | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %} | {%- if grains.get('virtual_subtype', None) not in ['Docker', 'LXC'] %} | ||||
- require: | - require: | ||||
- iptables: iptables_{{ chain_name }}{% if rule.family is defined %}_{{ rule.family }}{% endif %} | |||||
- iptables: iptables_{{ table}}_{{ chain_name }}{% if rule.family is defined %}_{{ rule.family }}{% endif %} | |||||
{%- endif %} | {%- endif %} | ||||
- save: True | - save: True |
{%- set chains = service.get('chain', {}).keys() %} | {%- set chains = service.get('chain', {}).keys() %} | ||||
{%- for chain_name, chain in service.get('chain', {}).iteritems() %} | {%- for chain_name, chain in service.get('chain', {}).iteritems() %} | ||||
iptables_{{ chain_name }}: | |||||
{%- set tables = [] %} | |||||
{%- for rule in chain.get('rules', []) %} | |||||
{%- set table = rule.get('table', 'filter') %} | |||||
{%- if table not in tables %} | |||||
{%- do tables.append(table) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- if chain.policy is defined %} | |||||
{%- if chain.policy is string %} | |||||
{%- if 'filter' not in tables %} | |||||
{%- do tables.append('filter') %} | |||||
{%- endif %} | |||||
{%- else %} | |||||
{%- for policy in chain.policy %} | |||||
{%- if policy.table not in tables %} | |||||
{%- do tables.append(policy.table) %} | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- for table in tables %} | |||||
iptables_{{ table }}_{{ chain_name }}: | |||||
iptables.chain_present: | iptables.chain_present: | ||||
- family: ipv4 | - family: ipv4 | ||||
- name: {{ chain_name }} | - name: {{ chain_name }} | ||||
- table: filter | |||||
- table: {{ table }} | |||||
- require: | - require: | ||||
- pkg: iptables_packages | - pkg: iptables_packages | ||||
{%- if grains.ipv6|default(False) and service.ipv6|default(True) %} | {%- if grains.ipv6|default(False) and service.ipv6|default(True) %} | ||||
iptables_{{ chain_name }}_ipv6: | |||||
iptables_{{ table }}_{{ chain_name }}_ipv6: | |||||
iptables.chain_present: | iptables.chain_present: | ||||
- family: ipv6 | - family: ipv6 | ||||
- name: {{ chain_name }} | - name: {{ chain_name }} | ||||
- table: filter | |||||
- table: {{ table }} | |||||
- require: | - require: | ||||
- pkg: iptables_packages | - pkg: iptables_packages | ||||
{%- if chain.policy is defined %} | {%- if chain.policy is defined %} | ||||
{%- if chain.policy is string %} | |||||
- require_in: | - require_in: | ||||
- iptables: iptables_{{ chain_name }}_ipv6_policy | |||||
- iptables: iptables_filter_{{ chain_name }}_ipv6_policy | |||||
{%- else %} | |||||
{%- if table in chain.policy %} | |||||
- require_in: | |||||
- iptables: iptables_filter_{{ chain_name }}_ipv6_policy | |||||
{%- endif %} | |||||
{%- endif %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- endif %} | {%- endif %} | ||||
{%- endfor %} | |||||
{%- if chain.policy is defined %} | {%- if chain.policy is defined %} | ||||
iptables_{{ chain_name }}_policy: | |||||
{%- if chain.policy is string %} | |||||
{%- set map = [{'table':'filter', 'policy':chain.policy}] %} | |||||
{%- else %} | |||||
{%- set map = chain.policy %} | |||||
{%- endif %} | |||||
{%- for policy in map %} | |||||
iptables_{{ policy.table }}_{{ chain_name }}_policy: | |||||
iptables.set_policy: | iptables.set_policy: | ||||
- family: ipv4 | - family: ipv4 | ||||
- chain: {{ chain_name }} | - chain: {{ chain_name }} | ||||
- policy: {{ chain.policy }} | |||||
- table: filter | |||||
- policy: {{ policy.policy }} | |||||
- table: {{ policy.table }} | |||||
- require: | - require: | ||||
- iptables: iptables_{{ chain_name }} | |||||
- iptables: iptables_{{ policy.table }}_{{ chain_name }} | |||||
{%- if grains.ipv6|default(False) and service.ipv6|default(True) %} | |||||
iptables_{{ chain_name }}_ipv6_policy: | |||||
{%- if grains.ipv6|default(False) and service.ipv6|default(True) %} | |||||
iptables_{{ policy.table }}_{{ chain_name }}_ipv6_policy: | |||||
iptables.set_policy: | iptables.set_policy: | ||||
- family: ipv6 | - family: ipv6 | ||||
- chain: {{ chain_name }} | - chain: {{ chain_name }} | ||||
- policy: {{ chain.policy }} | |||||
- table: filter | |||||
- policy: {{ policy.policy }} | |||||
- table: {{ policy.table }} | |||||
- require: | - require: | ||||
- iptables: iptables_{{ chain_name }}_ipv6 | |||||
{%- endif %} | |||||
- iptables: iptables_{{ policy.table }}_{{ chain_name }}_ipv6 | |||||
{%- endif %} | |||||
{%- endfor %} | |||||
{%- endif %} | {%- endif %} | ||||
{%- for service_name, service in pillar.items() %} | {%- for service_name, service in pillar.items() %} |
enabled: true | enabled: true | ||||
chain: | chain: | ||||
INPUT: | INPUT: | ||||
policy: | |||||
- table: nat | |||||
policy: ACCEPT | |||||
rules: | rules: | ||||
- position: 1 | - position: 1 | ||||
table: filter | table: filter | ||||
source_network: 127.0.0.1 | source_network: 127.0.0.1 | ||||
jump: ACCEPT | jump: ACCEPT | ||||
comment: Blah | comment: Blah | ||||
OUTPUT: | |||||
policy: ACCEPT | |||||
FORWARD: | |||||
policy: | |||||
- table: mangle | |||||
policy: DROP | |||||
POSTROUTING: | |||||
rules: | |||||
- jump: MASQUERADE | |||||
protocol: icmp | |||||
out_interface: ens3 | |||||
table: nat |