Time windows crossing midnight in UTC never match
A rule with time starttime and stoptime is rendered as two separate checks, "meta hour >= start" and "meta hour < stop". nft converts both times to UTC when the ruleset is loaded. If the window crosses midnight, either in local time or only after the conversion to UTC, both checks can never be true at the same time and the rule never matches. A rule with only a starttime or only a stoptime has the same problem.
On a system in Europe/Berlin (CEST) the window 01:00-02:00 becomes "meta hour >= 23:00 meta hour < 00:00" and never matches. A window of 22:00-06:00 never matches in any time zone.
set system time-zone Europe/Berlin set firewall ipv4 name TEST rule 10 action drop set firewall ipv4 name TEST rule 10 protocol tcp set firewall ipv4 name TEST rule 10 destination port 25 set firewall ipv4 name TEST rule 10 time starttime 01:00 set firewall ipv4 name TEST rule 10 time stoptime 02:00 commit sudo nft list chain ip vyos_filter NAME_TEST
Time based firewall rules are shifted after a daylight saving or time-zone change
nft converts hour matches to UTC using the UTC offset in effect when the ruleset is loaded. After a daylight saving change, or after changing the system time-zone, every hour window is off by the difference until the next firewall commit. Changing the time-zone does not reload the firewall or policy route rules.
In the example below the window stays at 06:00-15:00 UTC, which is 02:00-11:00 in New York instead of 08:00-17:00. The switch from CEST to CET shifts all windows by one hour in the same way.
set system time-zone Europe/Berlin set firewall ipv4 name TEST rule 10 action accept set firewall ipv4 name TEST rule 10 time starttime 08:00 set firewall ipv4 name TEST rule 10 time stoptime 17:00 commit set system time-zone America/New_York commit sudo nft list chain ip vyos_filter NAME_TEST
Fragment match-frag stops working when packet marks are used
Before reassembly, fragments are tagged by overwriting the whole packet mark with 0xffff1. Any later mark change replaces this tag: a firewall "set mark", or a policy route "set table" or "set vrf". After that, "fragment match-frag" and "fragment match-non-frag" give wrong results. A mark already present on a fragment is lost, and a user mark of 1048561 (0xffff1) is mistaken for the fragment tag.
In the example below fragmented packets are not dropped, as their mark is 55 by the time the input filter runs.
set firewall ipv4 prerouting raw rule 10 action accept set firewall ipv4 prerouting raw rule 10 set mark 55 set firewall ipv4 input filter rule 10 action drop set firewall ipv4 input filter rule 10 fragment match-frag commit # from a host connected to the router ping -s 4000 <router-ip>
Commits keep failing when an nftables table is gone but its rule file in /run still exists
The generated ruleset only deletes the old table if the matching rule file in /run exists. If the file exists but the table does not, for example after a failed commit or a manual nft change, deleting the table fails and every following commit fails with it until reboot.
Affected tables: ip/ip6/bridge vyos_filter (firewall), ip/ip6 vyos_mangle (policy route), ip/ip6 vyos_conntrack (system conntrack) and ip vyos_wanloadbalance (load-balancing wan).
set firewall ipv6 name TEST rule 1 action accept set firewall ipv6 name TEST rule 1 source address 2001:db8::1 commit sudo nft delete table ip6 vyos_filter set firewall ipv6 name TEST rule 2 action drop set firewall ipv6 name TEST rule 2 source address 2001:db8::2 commit