Skip to content

Commit

Permalink
Merge pull request #129 from evan-a-a/main
Browse files Browse the repository at this point in the history
firewalld: Add support for firewalld port forwarding

Reviewed-by: Adam Miller <[email protected]>
             https://github.com/maxamillion
  • Loading branch information
ansible-zuul[bot] authored Jan 18, 2021
2 parents 41d49e4 + 1e7d82a commit bc0fb30
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 3 deletions.
24 changes: 21 additions & 3 deletions docs/ansible.posix.firewalld_module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,21 @@ Parameters
<div>Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>port_forward</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Port and protocol to forward using firewalld.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
Expand Down Expand Up @@ -360,17 +375,20 @@ Examples
permanent: yes
icmp_block: echo-request

- name: Redirect port 443 to 8443 with Rich Rule
- name: Redirect port 443 to 8443
become: yes
ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
port_forward:
- port: 443
proto: tcp
toport: 8443
zone: public
permanent: yes
immediate: yes
state: enabled




Status
------

Expand Down
116 changes: 116 additions & 0 deletions plugins/modules/firewalld.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@
- Name of a port or port range to add/remove to/from firewalld.
- Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.
type: str
port_forward:
description:
- Port and protocol to forward using firewalld.
type: list
elements: dict
suboptions:
port:
type: str
required: true
description:
- Source port to forward from
proto:
type: str
required: true
description:
- protocol to forward
choices: [udp, tcp]
toport:
type: str
required: true
description:
- destination port
toaddr:
type: str
description:
- Optional address to forward to
rich_rule:
description:
- Rich rule to add/remove to/from firewalld.
Expand Down Expand Up @@ -678,6 +704,55 @@ def set_disabled_permanent(self):
zone_obj.remove()


class ForwardPortTransaction(FirewallTransaction):
"""
ForwardPortTransaction
"""

def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(ForwardPortTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)

def get_enabled_immediate(self, port, proto, toport, toaddr, timeout):
forward_port = [port, proto, toport, toaddr]
if self.fw_offline:
fw_zone, fw_settings = self.get_fw_zone_settings()
forward_list = fw_settings.getForwardPorts()
else:
forward_list = self.fw.getForwardPorts(self.zone)

if forward_port in forward_list:
return True
else:
return False

def get_enabled_permanent(self, port, proto, toport, toaddr, timeout):
forward_port = (port, proto, toport, toaddr)
fw_zone, fw_settings = self.get_fw_zone_settings()

if forward_port in fw_settings.getForwardPorts():
return True
else:
return False

def set_enabled_immediate(self, port, proto, toport, toaddr, timeout):
self.fw.addForwardPort(self.zone, port, proto, toport, toaddr, timeout)

def set_enabled_permanent(self, port, proto, toport, toaddr, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.addForwardPort(port, proto, toport, toaddr)
self.update_fw_settings(fw_zone, fw_settings)

def set_disabled_immediate(self, port, proto, toport, toaddr, timeout):
self.fw.removeForwardPort(self.zone, port, proto, toport, toaddr)

def set_disabled_permanent(self, port, proto, toport, toaddr, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.removeForwardPort(port, proto, toport, toaddr)
self.update_fw_settings(fw_zone, fw_settings)


def main():

module = AnsibleModule(
Expand All @@ -686,6 +761,7 @@ def main():
icmp_block_inversion=dict(type='str'),
service=dict(type='str'),
port=dict(type='str'),
port_forward=dict(type='list', elements='dict'),
rich_rule=dict(type='str'),
zone=dict(type='str'),
immediate=dict(type='bool', default=False),
Expand Down Expand Up @@ -745,6 +821,21 @@ def main():
else:
port = None

port_forward_toaddr = ''
port_forward = None
if module.params['port_forward'] is not None:
if len(module.params['port_forward']) > 1:
module.fail_json(msg='Only one port forward supported at a time')
port_forward = module.params['port_forward'][0]
if 'port' not in port_forward:
module.fail_json(msg='port must be specified for port forward')
if 'proto' not in port_forward:
module.fail_json(msg='proto udp/tcp must be specified for port forward')
if 'toport' not in port_forward:
module.fail_json(msg='toport must be specified for port forward')
if 'toaddr' in port_forward:
port_forward_toaddr = port_forward['toaddr']

modification_count = 0
if icmp_block is not None:
modification_count += 1
Expand All @@ -754,6 +845,8 @@ def main():
modification_count += 1
if port is not None:
modification_count += 1
if port_forward is not None:
modification_count += 1
if rich_rule is not None:
modification_count += 1
if interface is not None:
Expand Down Expand Up @@ -856,6 +949,29 @@ def main():
)
)

if port_forward is not None:
transaction = ForwardPortTransaction(
module,
action_args=(str(port_forward['port']), port_forward['proto'],
str(port_forward['toport']), port_forward_toaddr, timeout),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate
)

changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if changed is True:
msgs.append(
"Changed port_forward %s to %s" % (
"port=%s:proto=%s:toport=%s:toaddr=%s" % (
port_forward['port'], port_forward['proto'],
port_forward['toport'], port_forward_toaddr
), desired_state
)
)

if rich_rule is not None:

transaction = RichRuleTransaction(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Test playbook for the firewalld module - port operations
# (c) 2017, Adam Miller <[email protected]>

# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

- name: firewalld port forward test permanent enabled
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: enabled
register: result

- name: assert firewalld port test permanent enabled worked
assert:
that:
- result is changed

- name: firewalld port test permanent enabled rerun (verify not changed)
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: enabled
register: result

- name: assert firewalld port test permanent enabled rerun worked (verify not changed)
assert:
that:
- result is not changed

- name: firewalld port test permanent disabled
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: disabled
register: result

- name: assert firewalld port test permanent disabled worked
assert:
that:
- result is changed

- name: firewalld port test permanent disabled rerun (verify not changed)
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: disabled
register: result

- name: assert firewalld port test permanent disabled rerun worked (verify not changed)
assert:
that:
- result is not changed

0 comments on commit bc0fb30

Please sign in to comment.