tripleo-ansible/tripleo_ansible/roles/tripleo-firewall/tasks/tripleo_firewall_add.yml
Harald Jensås 68ec102343 Support 'ipversion' property in rules
The firewall role incorrectly used the 'proto' field in
a rule as a conditional to decide if the rule should be
created in iptables|ip6tables (or both). When proto was
'ipv6' the rule was not created in iptables, and when
proto was 'ipv4' the rule was not created in ip6tables.

When the proto field have 'ipv4' or 'ipv6' it is to
create rules for ip-in-ip encapsulation. Encapsulating
ipv4 in ipv6 or vice-versa is a valid usecase.

This change adds the 'ipversion' property for rules.

Closes-Bug: #1845170
Change-Id: I4b3463f27714721b2252640d8714da820da2eed6
2019-09-24 16:55:39 +02:00

157 lines
7.4 KiB
YAML

---
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# NOTE(Cloudnull): This task exists because the iptables module will not
# create a chain. There is a feature request open for this
# [ https://github.com/ansible/ansible/issues/25099 ].
# A change has been added to support this functionality but
# it is awaiting review and merge.
# [ https://github.com/ansible/ansible/pull/32158 ]. When
# this change is merged this task should be removed.
- name: Ensure chains exist
shell: |-
EXIT_CODE=0
if ! iptables --list "{{ item['rule']['chain'] }}"; then
iptables -N "{{ item['rule']['chain'] }}"
EXIT_CODE=99
fi
if ! ip6tables --list "{{ item['rule']['chain'] }}"; then
ip6tables -N "{{ item['rule']['chain'] }}"
EXIT_CODE=99
fi
exit ${EXIT_CODE}
when:
- (item['rule']['chain'] | default('INPUT')) != 'INPUT'
- tripleo_firewall_port_states[(item['rule']['extras'] | default({}))['ensure'] | default('enabled')] == "present"
register: iptables_chain
changed_when: iptables_chain.rc == 99
failed_when: not (iptables_chain.rc in [0, 99])
- include_tasks: tripleo_firewall_state.yml
# NOTE(Cloudnull): This task adds multiport rules using a loop instead of using
# the multiport key word. While multiport is perfectly functional
# using raw iptables rules, it is not supported in the ansible
# module. The use of the loop will be revised just as soon as the
# pull request [ https://github.com/ansible/ansible/pull/21071 ]
# is merged.
- name: Firewall port rule (ipv4)
iptables:
action: insert
table: "{{ item['rule']['table'] | default(omit) }}"
chain: "{{ item['rule']['chain'] | default('INPUT') }}"
in_interface: "{{ item['rule']['interface'] | default(omit) }}"
protocol: "{{ item['rule']['proto'] | default('tcp') }}"
destination_port: "{{ port | replace('-', ':') }}"
destination: "{{ item['rule']['destination'] | default(omit) }}"
source_port: "{{ item['rule']['sport'] | default(omit) | replace('-', ':') }}"
source: "{{ item['rule']['source'] | default(omit) }}"
comment: "{{ item['rule_name'] }} ipv4"
jump: "{{ item['rule']['jump'] | default('ACCEPT') }}"
ctstate: "{{ tripleo_ctstate }}"
limit: "{{ item['rule']['limit'] | default(omit) }}"
limit_burst: "{{ item['rule']['limit_burst'] | default(omit) }}"
ip_version: ipv4
state: "{{ tripleo_firewall_port_states[(item['rule']['extras'] | default({}))['ensure'] | default('enabled')] }}"
when:
- item['rule']['dport'] is defined
- (item['rule']['ipversion'] | default('ipv4')) != 'ipv6'
- item['rule']['source'] | default('127.0.0.1') | ipv4
- item['rule']['destination'] | default('127.0.0.1') | ipv4
loop: "{{ ((item['rule']['dport'] is iterable) and (item['rule']['dport'] is not string)) | ternary(item['rule']['dport'], [item['rule']['dport']]) }}"
loop_control:
loop_var: port
notify:
- Save firewall rules
# NOTE(Cloudnull): This task adds multiport rules using a loop instead of using
# the multiport key word. While multiport is perfectly functional
# using raw iptables rules, it is not supported in the ansible
# module. The use of the loop will be revised just as soon as the
# pull request [ https://github.com/ansible/ansible/pull/21071 ]
# is merged.
- name: Firewall port rule (ipv6)
iptables:
action: insert
table: "{{ item['rule']['table'] | default(omit) }}"
chain: "{{ item['rule']['chain'] | default('INPUT') }}"
in_interface: "{{ item['rule']['interface'] | default(omit) }}"
protocol: "{{ item['rule']['proto'] | default('tcp') }}"
destination_port: "{{ port | replace('-', ':') }}"
destination: "{{ item['rule']['destination'] | default(omit) }}"
source_port: "{{ item['rule']['sport'] | default(omit) | replace('-', ':') }}"
source: "{{ item['rule']['source'] | default(omit) }}"
comment: "{{ item['rule_name'] }} ipv6"
jump: "{{ item['rule']['jump'] | default('ACCEPT') }}"
ctstate: "{{ tripleo_ctstate }}"
limit: "{{ item['rule']['limit'] | default(omit) }}"
limit_burst: "{{ item['rule']['limit_burst'] | default(omit) }}"
ip_version: ipv6
state: "{{ tripleo_firewall_port_states[(item['rule']['extras'] | default({}))['ensure'] | default('enabled')] }}"
when:
- item['rule']['dport'] is defined
- (item['rule']['ipversion'] | default('ipv6')) != 'ipv4'
- item['rule']['source'] | default('::') | ipv6
- item['rule']['destination'] | default('::') | ipv6
loop: "{{ ((item['rule']['dport'] is iterable) and (item['rule']['dport'] is not string)) | ternary(item['rule']['dport'], [item['rule']['dport']]) }}"
loop_control:
loop_var: port
notify:
- Save firewall rules
- name: Firewall protocol rule (ipv4)
iptables:
action: insert
table: "{{ item['rule']['table'] | default(omit) }}"
chain: "{{ item['rule']['chain'] | default('INPUT') }}"
in_interface: "{{ item['rule']['interface'] | default(omit) }}"
protocol: "{{ item['rule']['proto'] | default(omit) }}"
source_port: "{{ item['rule']['sport'] | default(omit) | replace('-', ':') }}"
source: "{{ item['rule']['source'] | default(omit) }}"
comment: "{{ item['rule_name'] }} ipv4"
jump: "{{ item['rule']['jump'] | default('ACCEPT') }}"
ctstate: "{{ tripleo_ctstate }}"
limit: "{{ item['rule']['limit'] | default(omit) }}"
limit_burst: "{{ item['rule']['limit_burst'] | default(omit) }}"
ip_version: ipv4
state: "{{ tripleo_firewall_port_states[(item['rule']['extras'] | default({}))['ensure'] | default('enabled')] }}"
when:
- (item['rule']['ipversion'] | default('ipv4')) != 'ipv6'
- item['rule']['proto'] is defined
- item['rule']['dport'] is undefined
- name: Firewall protocol rule (ipv6)
iptables:
action: insert
table: "{{ item['rule']['table'] | default(omit) }}"
chain: "{{ item['rule']['chain'] | default('INPUT') }}"
in_interface: "{{ item['rule']['interface'] | default(omit) }}"
protocol: "{{ item['rule']['proto'] | default(omit) }}"
source_port: "{{ item['rule']['sport'] | default(omit) | replace('-', ':') }}"
source: "{{ item['rule']['source'] | default(omit) }}"
comment: "{{ item['rule_name'] }} ipv6"
jump: "{{ item['rule']['jump'] | default('ACCEPT') }}"
ctstate: "{{ tripleo_ctstate }}"
limit: "{{ item['rule']['limit'] | default(omit) }}"
limit_burst: "{{ item['rule']['limit_burst'] | default(omit) }}"
ip_version: ipv6
state: "{{ tripleo_firewall_port_states[(item['rule']['extras'] | default({}))['ensure'] | default('enabled')] }}"
when:
- (item['rule']['ipversion'] | default('ipv6')) != 'ipv4'
- item['rule']['proto'] is defined
- item['rule']['dport'] is undefined