Browse Source

Unhardcode tables for chains.

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: Ib5ba97dad165d3ef2dec7e053b391ea36a996103
pull/19/head
Dzmitry Stremkouski 6 years ago
parent
commit
1a1e8c7db2
4 changed files with 124 additions and 34 deletions
  1. +28
    -0
      README.rst
  2. +27
    -19
      iptables/_rule.sls
  3. +54
    -15
      iptables/rules.sls
  4. +15
    -0
      tests/pillar/iptables_server.sls

+ 28
- 0
README.rst View File

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
========= =========



+ 27
- 19
iptables/_rule.sls View File

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

+ 54
- 15
iptables/rules.sls View File

{%- 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() %}

+ 15
- 0
tests/pillar/iptables_server.sls View File

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

Loading…
Cancel
Save