Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firewalld rich rules purged every time when priority enabled #366

Open
adam-kosseck opened this issue Mar 6, 2024 · 1 comment
Open

Comments

@adam-kosseck
Copy link

adam-kosseck commented Mar 6, 2024

I have an issue with FirewallD module 5.0.0 running against Puppet 7.27.

We have a number of firewalld rich rules declared in Hiera in a zone like this:

  internal:
    ensure: present
    target: '%%REJECT%%'
    sources: [ ]  
    purge_rich_rules: true
    purge_services: true
    purge_ports: true
    icmp_block_inversion: false  
    icmp_blocks: [ ]

firewalld::rich_rules:
  '000 Accept ICMP from company Subnets':
    zone: internal
    source:
      ipset: company
    protocol: icmp
    action: accept
  '001 Accept SSH from company Subnets':
    zone: internal
    source:
      ipset: company
    service: ssh
    action: accept

These rules work ok, however if I add a "priority" parameter to the rich rules then EVERY time the Puppet agent runs it purges all the rich rules and re-applies them. Here's the debug output from one of these runs:

Debug: Exec[firewalld::set_log_denied_offline](provider=posix): Executing check '[ $(firewall-offline-cmd --get-log-denied) = unicast ]'
Debug: Executing: '[ $(firewall-offline-cmd --get-log-denied) = unicast ]'
Debug: /Stage[main]/Firewalld/Exec[firewalld::set_log_denied_offline]: '["firewall-offline-cmd", "--set-log-denied", "unicast"]' won't be executed because of failed check 'unless'
Debug: Augeas[firewalld::zone_drifting](provider=augeas): Opening augeas with root /, lens path /opt/puppetlabs/puppet/cache/lib/augeas/lenses, flags 64
Debug: Augeas[firewalld::zone_drifting](provider=augeas): Augeas version 1.13.0 is installed
Debug: Augeas[firewalld::zone_drifting](provider=augeas): Will attempt to save and only run if files changed
Debug: Augeas[firewalld::zone_drifting](provider=augeas): sending command 'set' with params ["/files/etc/firewalld/firewalld.conf/AllowZoneDrifting", "no"]
Debug: Augeas[firewalld::zone_drifting](provider=augeas): Skipping because no files were changed
Debug: Augeas[firewalld::zone_drifting](provider=augeas): Closed the augeas connection
Debug: Augeas[firewalld::firewall_backend](provider=augeas): Opening augeas with root /, lens path /opt/puppetlabs/puppet/cache/lib/augeas/lenses, flags 64
Debug: Augeas[firewalld::firewall_backend](provider=augeas): Augeas version 1.13.0 is installed
Debug: Augeas[firewalld::firewall_backend](provider=augeas): Will attempt to save and only run if files changed
Debug: Augeas[firewalld::firewall_backend](provider=augeas): sending command 'set' with params ["/files/etc/firewalld/firewalld.conf/FirewallBackend", "nftables"]
Debug: Augeas[firewalld::firewall_backend](provider=augeas): Skipping because no files were changed
Debug: Augeas[firewalld::firewall_backend](provider=augeas): Closed the augeas connection
Debug: Executing: '/usr/bin/systemctl is-active -- firewalld'
Debug: Executing: '/usr/bin/systemctl is-enabled -- firewalld'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-zones'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --get-target'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-sources'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-icmp-blocks'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-icmp-block-inversion'
Notice: /Stage[main]/Firewalld/Firewalld_zone[internal]/purge_rich_rules: purge_rich_rules changed 'purgable' to 'true' (corrective)
Debug: Executing: '/usr/bin/firewall-cmd --reload'
Debug: /Stage[main]/Firewalld/Firewalld_zone[internal]: The container Class[Firewalld] will propagate my refresh event
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-zones'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --get-target'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --list-icmp-blocks'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --query-icmp-block-inversion'
Debug: Prefetching firewall_cmd resources for firewalld_service
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-services'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
Debug: /Stage[main]/Firewalld/Firewalld_service[000 Remove Default Cockpit Service Rule]: Nothing to manage: no ensure and the resource doesn't exist
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
Debug: /Stage[main]/Firewalld/Firewalld_service[000 Remove Default dhcpv6-client Service Rule]: Nothing to manage: no ensure and the resource doesn't exist
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
Debug: /Stage[main]/Firewalld/Firewalld_service[000 Remove Default mdns Service Rule]: Nothing to manage: no ensure and the resource doesn't exist
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
Debug: /Stage[main]/Firewalld/Firewalld_service[000 Remove Default samba-client Rule]: Nothing to manage: no ensure and the resource doesn't exist
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv4" priority="-32500" source ipset="company" protocol value="icmp" accept'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --add-rich-rule rule family="ipv4" priority="-32500" source ipset="company" protocol value="icmp" accept'
Notice: /Stage[main]/Firewalld/Firewalld_rich_rule[000 Accept ICMP from company Subnets]/ensure: created (corrective)
Debug: /Stage[main]/Firewalld/Firewalld_rich_rule[000 Accept ICMP from company Subnets]: The container Class[Firewalld] will propagate my refresh event
Info: /Stage[main]/Firewalld/Firewalld_rich_rule[000 Accept ICMP from company Subnets]: Scheduling refresh of Class[Firewalld::Reload]
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv4" priority="-32000" source ipset="company" service name="ssh" accept'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --add-rich-rule rule family="ipv4" priority="-32000" source ipset="company" service name="ssh" accept'
Notice: /Stage[main]/Firewalld/Firewalld_rich_rule[001 Accept SSH from company Subnets]/ensure: created (corrective)
Debug: /Stage[main]/Firewalld/Firewalld_rich_rule[001 Accept SSH from company Subnets]: The container Class[Firewalld] will propagate my refresh event
Info: /Stage[main]/Firewalld/Firewalld_rich_rule[001 Accept SSH from company Subnets]: Scheduling refresh of Class[Firewalld::Reload]

If I remove the priority parameter then the problem goes away immediately.

@adam-kosseck
Copy link
Author

I have also noted the same behavior with inverted rich rules via hiera.
The following hiera rich rules block traffic originating from a loopback adapter that is trying to access a non-loopback address:

firewalld::rich_rules:
'002 Restrict ipv4 loopback traffic':
    zone: internal
    source: '127.0.0.1'
    dest:
      address: '127.0.0.1'
      invert: true
    action: drop
  '003 Restrict ipv6 loopback traffic':
    zone: internal
    source: '::1'
    dest:
      address: '::1'
      invert: true
    family: ipv6
    action: drop

The following is seen in the debug logs of every host which inherits these hiera rules, every time the agent runs:

Debug: Executing: '/usr/bin/systemctl is-enabled -- firewalld'
Debug: Prefetching firewall_cmd resources for firewalld_ipset
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-ipsets'
** --info-ipset and ipset --get-entries queries removed **
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-zones'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --get-target'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-sources'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-icmp-blocks'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-icmp-block-inversion'
Notice: /Stage[main]/Firewalld/Firewalld_zone[internal]/purge_rich_rules: purge_rich_rules changed 'purgable' to 'true' (corrective)
Debug: Executing: '/usr/bin/firewall-cmd --reload'
Debug: /Stage[main]/Firewalld/Firewalld_zone[internal]: The container Class[Firewalld] will propagate my refresh event
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-zones'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --get-target'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --list-icmp-blocks'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone external --query-icmp-block-inversion'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-services'
** Service queries removed **
Debug: Prefetching firewall_cmd resources for firewalld_service
Debug: Executing: '/usr/bin/firewall-cmd --permanent --get-services'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
** Service queries removed **
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --list-services'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv4" source ipset="company" protocol value="icmp" accept'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv4" source ipset="company" service name="ssh" accept'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv4" source address="127.0.0.1" destination NOT address="127.0.0.1" drop'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --add-rich-rule rule family="ipv4" source address="127.0.0.1" destination NOT address="127.0.0.1" drop'
Notice: /Stage[main]/Firewalld/Firewalld_rich_rule[002 Restrict ipv4 loopback traffic]/ensure: created (corrective)
Debug: /Stage[main]/Firewalld/Firewalld_rich_rule[002 Restrict ipv4 loopback traffic]: The container Class[Firewalld] will propagate my refresh event
Info: /Stage[main]/Firewalld/Firewalld_rich_rule[002 Restrict ipv4 loopback traffic]: Scheduling refresh of Class[Firewalld::Reload]
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --query-rich-rule rule family="ipv6" source address="::1" destination NOT address="::1" drop'
Debug: Executing: '/usr/bin/firewall-cmd --permanent --zone internal --add-rich-rule rule family="ipv6" source address="::1" destination NOT address="::1" drop'
Notice: /Stage[main]/Firewalld/Firewalld_rich_rule[003 Restrict ipv6 loopback traffic]/ensure: created (corrective)
Debug: /Stage[main]/Firewalld/Firewalld_rich_rule[003 Restrict ipv6 loopback traffic]: The container Class[Firewalld] will propagate my refresh event
Info: /Stage[main]/Firewalld/Firewalld_rich_rule[003 Restrict ipv6 loopback traffic]: Scheduling refresh of Class[Firewalld::Reload]
** Other rich rule queries removed **
Info: Class[Firewalld::Reload]: Scheduling refresh of Exec[firewalld::reload]
Debug: /Stage[main]/Firewalld::Reload/Exec[firewalld::reload]: 'firewall-cmd --reload' won't be executed because of failed check 'refreshonly'
Debug: Exec[firewalld::reload](provider=posix): Executing check 'firewall-cmd --state'
Debug: Executing: 'firewall-cmd --state'
Debug: /Stage[main]/Firewalld::Reload/Exec[firewalld::reload]/onlyif: running
Debug: Exec[firewalld::reload](provider=posix): Executing 'firewall-cmd --reload'
Debug: Executing: 'firewall-cmd --reload'
Notice: /Stage[main]/Firewalld::Reload/Exec[firewalld::reload]: Triggered 'refresh' from 1 event

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant