Page MenuHomeVyOS Platform

Migrated Firewall Global State Policy ineffective on latest firewall zone config
Closed, ResolvedPublic

Description

After the recent (1) firewall refactoring (T5160) and (2) the re-addition of support for zone-based firewall syntax (forum mention), I've found that the global state-policy that corresponded with the "old" zone syntax does not properly migrate when going from the "old" zone system to the "new" zone system.

Basically the presence of custom tables (zone-relationships) and the way they are invoked in the backend nftables post-migration prevents the entire migrated Forward/Input/Output filter state policies (see below) from ever taking effect, therefore stateful traffic filtering does Not work -- session/flow return traffic fails.

In example below, on the migrated (1.5) configuration, a ping initiated from the "northwindslan" zone to the "internet" zone will not receive ICMP responses until a rule is added to explicitly allow ESTABLISHED traffic. Eg. firewall ipv4 name internet-northwindslan rule 1 action accept & firewall ipv4 name internet-northwindslan rule 1 state established.

Suggested resolution: automatically add any global state policy rules on the "old" configuration to each custom table in the "new" configuration during the config migration process.


The problem in detail:

Working configuration: replies to pings from northwindslan to internet are received as expected.
1.4-rolling-202306020317 containing this example configuration under firewall:

firewall {
    name northwindslan-internet {
        default-action accept
    }
    name northwindslan-local {
        default-action accept
    }
    name internet-northwindslan {
        default-action drop
    }
    name internet-local {
        default-action drop
    }
    name local-northwindslan {
        default-action accept
    }
    name local-internet {
        default-action accept
    }
    state-policy {
        established {
            action accept
        }
        invalid {
            action drop
        }
        related {
            action accept
        }
    }
    zone northwindslan {
        from internet {
            firewall {
                name internet-northwindslan
            }
        }
        from local {
            firewall {
                name local-northwindslan
            }
        }
        interface eth5
    }
    zone internet {
        from northwindslan {
            firewall {
                name northwindslan-internet
            }
        }
        from local {
            firewall {
                name local-internet
            }
        }
        interface eth4
    }
    zone local {
        from northwindslan {
            firewall {
                name northwindslan-local
            }
        }
        from internet {
            firewall {
                name internet-local
            }
        }
        local-zone
    }
}

Then install:

1.5-rolling-202311220024 which runs migration scripts to the latest implementation of the firewall that accommodates zones.

Failing condition: with the config below, replies to pings initiated from the northwindslan zone to the internet zone are Not recieved (until one adds a rule accepting ESTABLISHED traffic under internet-northwindslan, as noted above).

Auto-Migrated configuration:

firewall {
    ipv4 {
        forward {
            filter {
                default-action "accept"
                rule 1 {
                    action "accept"
                    state "established"
                }
                rule 2 {
                    action "drop"
                    state "invalid"
                }
                rule 3 {
                    action "accept"
                    state "related"
                }
            }
        }
        input {
            filter {
                default-action "accept"
                rule 1 {
                    action "accept"
                    state "established"
                }
                rule 2 {
                    action "drop"
                    state "invalid"
                }
                rule 3 {
                    action "accept"
                    state "related"
                }
            }
        }
        name northwindslan-internet {
            default-action "accept"
            rule 1 {
                action "accept"
                state "established"
            }
        }
        name northwindslan-local {
            default-action "accept"
        }
        name internet-northwindslan {
            default-action "drop"
            rule 1 {
                action "accept"
                state "established"
            }
        }
        name internet-local {
            default-action "drop"
        }
        name local-northwindslan {
            default-action "accept"
        }
        name local-internet {
            default-action "accept"
        }
        output {
            filter {
                default-action "accept"
                rule 1 {
                    action "accept"
                    state "established"
                }
                rule 2 {
                    action "drop"
                    state "invalid"
                }
                rule 3 {
                    action "accept"
                    state "related"
                }
            }
        }
    }

Details

Difficulty level
Unknown (require assessment)
Version
1.4, 1.5
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)

Event Timeline

marvin created this object in space S1 VyOS Public.
marvin updated the task description. (Show Details)
marvin updated the task description. (Show Details)
marvin updated the task description. (Show Details)
n.fort changed the task status from Open to Confirmed.Nov 23 2023, 10:48 AM
n.fort added a project: VyOS 1.5 Circinus.

Should we return global state policy?
It was useful.

I agree, without it, you end up repeating yourself alot, with the established, related and invalid rules.
As long as they are applied before the zone specific rules (which is how I guess it used to work), it makes sense.

Agree with @Viacheslav and @GurliGebis comments above.

Personally I'd prefer to at least have the option of global state policy, especially for migration scenarios detailed, As Long As zone-specific state policies (when configured) take priority.

My main concern was that "demanding" a complete return to global state policy would somehow impact the flexibility of the new design, which I'm not looking to do. I just want, at a minimum, migrations to work, either via zone-level state policy or a re-added global state policy. :)

BTW, @n.fort huge thanks for all the work you've been doing on the firewall. It's much appreciated!

We'll discuss this internally, but for sure a fix should be applied.
Thanks for such a detailed bug-report.

n.fort changed the task status from Confirmed to In progress.Nov 28 2023, 12:49 PM

@n.fort I have a branch with a backport of this for 1.4 (needs manual changes).

Should I create a PR for it, or do you want to do it? (it's your commits I have cherry-pick'ed, just with a few changes)

Excellent; thanks @GurliGebis! I built 1.4 today and confirmed it's working as expected.

As far as I'm concerned, this issue is now resolved and the ticket can now be closed.

Excellent; thanks @GurliGebis! I built 1.4 today and confirmed it's working as expected.

As far as I'm concerned, this issue is now resolved and the ticket can now be closed.

Great ๐Ÿ™‚