Skip to content

zpe.nodegrid.firewall not updating all options #75

@m-hau

Description

@m-hau

In certain situations, the zpe.nodegrid.firewall may not properly update all defined options of an existing firewall rule, because the used dict_diff() method will omit any option that is not present in the "current rule state". This will cause sub-options to be omitted, which are enabled by other options that are set just before.

Assume a nodegrid system, which has an empty no-op rule in the IPv4 INPUT chain:

[ansible@nodegrid /]# show /settings/ipv4_firewall/chains/INPUT/0/
target = ACCEPT
rule_number = 0
description = 
source_net4 = 
destination_net4 = 
source_mac_address = 
protocol = numeric
protocol_number = 
input_interface = any
output_interface = any
fragments = all_packets_and_fragments
reverse_match_for_source_ip|mask = no
reverse_match_for_destination_ip|mask = no
reverse_match_for_source_mac_address = no
reverse_match_for_source_port = no
reverse_match_for_destination_port = no
reverse_match_for_protocol = no
reverse_match_for_tcp_flags = no
reverse_match_for_icmp_type = no
reverse_match_for_input_interface = no
enable_state_match = no
reverse_match_for_output_interface = no
reject_with = port_unreacheable
log_level = debug
log_prefix = 
log_tcp_sequence_numbers = no
log_options_from_the_tcp_packet_header = no
log_options_from_the_ip_packet_header = no

Executing the following example playbook

- hosts: all 
  tasks:
    - zpe.nodegrid.firewall:
        debug: true
        ipv4_firewall:
          chains:
            INPUT:
              - rule_number: 0
                enable_state_match: "yes"
                invalid: "yes"

result in

TASK [zpe.nodegrid.firewall] *********************
changed: [nodegrid] => 
    changed: true
    cmds:
    -   cmd: config_start
    -   cmd: cd /settings/ipv4_firewall/chains/INPUT/0
    -   cmd: set enable_state_match=yes
    -   cmd: set rule_number=0
    -   cmd: set target=ACCEPT
    -   cmd: commit
    -   cmd: config_confirm
    cmds_output:
      [ ---- 8< ---- ]
    message: ''

While the enable_state_match option is set, the invalid is not. The invalidoption is only available when the enable_state_match option is yes. Because the enable_state_match was initially no, the invalid option was not part of the "current rule state", and filtered out by the dict_diff() method.
Running the playbook again will then properly set the invalid option, because at that point enable_state_match is already yes in the "current rule state".

As a workaround, you can run the task multiple times in a row (three should be enough) using Ansible's loop statement. Do note however that this makes the firewall updates non-atomic, with the potential to lock yourself out using a partially configured firewall ruleset.

The zpe.nodegrid.firewallv2 module is not effected by this, because it uses a more strict match to existing rules. But its iterative nature and multiple task invocations make it inherently non-atomic, with the same potential to lock yourself out using a partially configured firewall ruleset. Or leaving it unprotected with a flushed ruleset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions