68ec102343
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
157 lines
7.4 KiB
YAML
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
|