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

[Bug] nftables chain policy is not restored when disabling the firewall #1225

Closed
aCursedComrade opened this issue Nov 30, 2024 · 2 comments
Closed

Comments

@aCursedComrade
Copy link

aCursedComrade commented Nov 30, 2024

Describe the bug

The daemon does not restore nftables input chain policy when disabling the firewall. So when the input policy was configured to be deny, it remains as deny which causes all incoming traffic to fail. This includes traffic from localhost as the associated rule for excluding local traffic from the filter is removed when the firewall is disabled.

  • OpenSnitch version: 1.6.5 (and 1.6.6)
  • OS: Manjaro Linux
  • Version: n/a
  • Window Manager: KDE Wayland
  • Kernel version: Linux comrade-arch 6.11.2-4-MANJARO #1 SMP PREEMPT_DYNAMIC Tue Oct 8 11:52:01 UTC 2024 x86_64 GNU/Linux

To Reproduce

  1. Open the system firewall prompt from the menu bar at the top of the window
  2. Change to the Inbound policy to "Deny"
  3. Observe the chain policy has changed through # nft list chain inet filter input through CLI
  4. Return to the firewall prompt and disable the firewall using the switch at the top
  5. Observe the policy has not changed (but rules have been removed if there have been any) in the input chain with # nft list chain inet filter input through CLI

Post error logs:

(handpicked from high volume of logs and moved to additional context section)

Expected behavior (optional)

When disabling the system firewall management, the policy (specifically for inet->filter->input) needs be restored to accept if it has been modified to deny to prevent any inconvenience.

Screenshots

2024-11-30.20-28-09.mp4

Additional context

Currently, the version packaged by Manjaro is 1.6.5 version. When disabling the firewall, the notable log line are these (on DEBUG level):

[2024-11-30 19:39:16]  INF  [notification] reloading firewall
[2024-11-30 19:39:16]  INF  nftables config changed, reloading
[2024-11-30 19:39:16]  INF  fw configuration loaded
[2024-11-30 19:39:16]  IMP  reloadConfCallback changed, reloading
[2024-11-30 19:39:16]  IMP  [nftables] AddSystemRules() fw disabled
[2024-11-30 19:39:16]  INF  nftables config changed, reloading
[2024-11-30 19:39:16]  INF  fw configuration loaded
[2024-11-30 19:39:16]  IMP  reloadConfCallback changed, reloading
[2024-11-30 19:39:16]  IMP  [nftables] AddSystemRules() fw disabled
[2024-11-30 19:39:18]  DBG  [notification] reload firewall. timeout fired, no errors?

I downloaded the daemon from 1.6.6 release and observed the same behavior when disabling the firewall, but something new got printed:

[2024-11-30 21:14:43]  INF  [notification] reloading firewall
[2024-11-30 21:14:43]  INF  nftables config changed, reloading
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: guest_nat, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: forward, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: guest_nat, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: forward, libvirt_network
[2024-11-30 21:14:43]  INF  fw configuration loaded
[2024-11-30 21:14:43]  IMP  reloadConfCallback changed, reloading
[2024-11-30 21:14:43]  IMP  [nftables] AddSystemRules() fw disabled
[2024-11-30 21:14:43]  INF  nftables config changed, reloading
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: guest_nat, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: forward, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: guest_nat, libvirt_network
[2024-11-30 21:14:43]  DBG  nftables: Restoring chain policy to accept: forward, libvirt_network
[2024-11-30 21:14:44]  INF  fw configuration loaded
[2024-11-30 21:14:44]  IMP  reloadConfCallback changed, reloading
[2024-11-30 21:14:44]  IMP  [nftables] AddSystemRules() fw disabled
[2024-11-30 21:14:45]  DBG  [notification] reload firewall. timeout fired, no errors?

It seems that the daemon only counts the chains created by libvirt and not the "standard" filter, nat and mangle tables/chains. I cannot see lines marked as errors or warns regarding this in the log.

Following is my usual nftables rule set:
table ip libvirt_network {
        chain forward {
                type filter hook forward priority filter; policy accept;
                counter packets 0 bytes 0 jump guest_cross
                counter packets 0 bytes 0 jump guest_input
                counter packets 0 bytes 0 jump guest_output
        }

        chain guest_output {
                ip saddr 192.168.100.0/24 iif "virbr0" counter packets 0 bytes 0 accept
                iif "virbr0" counter packets 0 bytes 0 reject
        }

        chain guest_input {
                oif "virbr0" ip daddr 192.168.100.0/24 ct state established,related counter packets 0 bytes 0 accept
                oif "virbr0" counter packets 0 bytes 0 reject
        }

        chain guest_cross {
                iif "virbr0" oif "virbr0" counter packets 0 bytes 0 accept
        }

        chain guest_nat {
                type nat hook postrouting priority srcnat; policy accept;
                ip saddr 192.168.100.0/24 ip daddr 224.0.0.0/24 counter packets 18 bytes 1028 return
                ip saddr 192.168.100.0/24 ip daddr 255.255.255.255 counter packets 0 bytes 0 return
                meta l4proto tcp ip saddr 192.168.100.0/24 ip daddr != 192.168.100.0/24 counter packets 0 bytes 0 masquerade to :1024-65535
                meta l4proto udp ip saddr 192.168.100.0/24 ip daddr != 192.168.100.0/24 counter packets 608 bytes 100366 masquerade to :1024-65535
                ip saddr 192.168.100.0/24 ip daddr != 192.168.100.0/24 counter packets 0 bytes 0 masquerade
        }
}
table ip6 libvirt_network {
        chain forward {
                type filter hook forward priority filter; policy accept;
                counter packets 0 bytes 0 jump guest_cross
                counter packets 0 bytes 0 jump guest_input
                counter packets 0 bytes 0 jump guest_output
        }

        chain guest_output {
        }

        chain guest_input {
        }

        chain guest_cross {
        }

        chain guest_nat {
                type nat hook postrouting priority srcnat; policy accept;
        }
}
table inet filter {
        chain forward {
                type filter hook forward priority filter; policy accept;
        }

        chain output {
                type filter hook output priority filter; policy accept;
        }

        chain input {
                type filter hook input priority filter; policy drop;
                udp sport 53 queue flags bypass to 0
                iifname "lo" accept
                ct state established,related accept
                udp dport 9993 accept
                tcp dport { 9050, 9051 } drop
                udp dport 5353 accept
                meta l4proto { tcp, udp } th dport { 21027, 22000 } accept
                meta l4proto { tcp, udp } th dport 1714-1764 accept
        }
}
table inet nat {
        chain filter-prerouting {
                type filter hook prerouting priority filter; policy accept;
        }

        chain prerouting {
                type nat hook prerouting priority dstnat; policy accept;
        }

        chain postrouting {
                type nat hook postrouting priority srcnat; policy accept;
        }

        chain input {
                type nat hook input priority srcnat; policy accept;
        }

        chain output {
                type nat hook output priority 100; policy accept;
        }
}
table inet mangle {
        chain prerouting {
                type filter hook prerouting priority mangle; policy accept;
        }

        chain postrouting {
                type filter hook postrouting priority mangle; policy accept;
        }

        chain output {
                type filter hook output priority mangle; policy accept;
                icmp type { echo-reply, destination-unreachable, echo-request } accept
                icmpv6 type { destination-unreachable, echo-request, echo-reply } accept
                meta l4proto != tcp ct state related,new queue flags bypass to 0
                tcp flags & (fin | syn | rst | ack) == syn queue flags bypass to 0
        }

        chain forward {
                type filter hook forward priority mangle; policy accept;
        }
}
@gustavo-iniguez-goya
Copy link
Collaborator

Hi @aCursedComrade ,

Issue reproduced, thanks for the detailed bug report. I'll take a look at it.

@gustavo-iniguez-goya
Copy link
Collaborator

The quickest fix would be to send 2 configuration changes: one to change the policy and another one to disable the firewall:

fwcfg = self._nodes.get_node(addr)['firewall']
fwcfg.Enabled = True if enable else False
self.send_notification(addr, fwcfg)

 fwcfg = self._nodes.get_node(addr)['firewall']
 self.send_notification(addr, fwcfg) 
 time.sleep(0.5)
 fwcfg.Enabled = True if enable else False 
 self.send_notification(addr, fwcfg) 

There's a problem reloading files that would require deeper changes.

gustavo-iniguez-goya added a commit that referenced this issue Dec 16, 2024
When disabling the fw, we change the default input and output policy to
Accept, not to block connections.

Due to a problem reloading the fw in the daemon, the policy was not
changed as expected.

This problem must be fixed in the daemon, but for the time being,
sending two configuration changes solves the issue (one for changing the
policy, and another one for disabling the fw).

Closes: #1225
(cherry picked from commit d825f1e)
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

2 participants