Page MenuHomeVyOS Platform

nat: commit failures and weight issue in load-balancing, translation issues for port-ranges
Closed, ResolvedPublicBUG

Description

Load-balanced NAT rules with a translation port or translation options fail to commit

The translation port and translation options are placed between "to" and the load-balancing expression, e.g. "dnat to :443 numgen random ...". nft rejects this and t
he commit fails with "Configuration file errors encountered!". Using "translation options address-mapping persistent" instead of the port fails the same way.

set nat destination rule 3 inbound-interface name eth0
set nat destination rule 3 protocol tcp
set nat destination rule 3 destination port 8443
set nat destination rule 3 translation port 443
set nat destination rule 3 load-balance hash random
set nat destination rule 3 load-balance backend 192.0.2.61 weight 50
set nat destination rule 3 load-balance backend 192.0.2.62 weight 50
commit

Load-balance weights not adding up to 100 leave connections without a backend

The load-balancing hash always runs from 0 to 99, while the backend ranges are built from the configured weights. If the weights add up to less than 100, some hash values have no backend and those connections are not translated. If they add up to more than 100, the last backends never receive traffic. Commit only prints a warning.

In the example below the rule becomes "jhash ip saddr mod 100 map { 0-49 : 192.0.2.51, 50-89 : 192.0.2.52 }", so about 10% of all sources are not translated.

set nat destination rule 2 inbound-interface name eth0
set nat destination rule 2 protocol udp
set nat destination rule 2 destination port 53
set nat destination rule 2 load-balance hash source-address
set nat destination rule 2 load-balance backend 192.0.2.51 weight 50
set nat destination rule 2 load-balance backend 192.0.2.52 weight 40
commit
sudo nft list table ip vyos_nat

Translation to an address prefix silently drops the translation port range

If a rule translates to a prefix and has no source or destination address to map from, it is rendered as "snat prefix to <prefix>" and the configured port range is lost without any warning.

set nat source rule 10 outbound-interface name eth0
set nat source rule 10 protocol tcp
set nat source rule 10 translation address 203.0.113.0/24
set nat source rule 10 translation port 1025-2000
commit
sudo nft list table ip vyos_nat

NAT rule referencing a non-existing mac-group gives an unhelpful commit error

A missing mac-group is not caught by the NAT config validation like the other group types. The nft dry run fails instead and commit only reports "Configuration file errors encountered!" rather than naming the missing group.

set nat source rule 10 source group mac-group DOES-NOT-EXIST
set nat source rule 10 translation address masquerade
commit

False "interface does not exist" warning for interface wildcards

Interface wildcards such as eth* are looked up as literal interface names, so commit always warns: WARNING: Interface "eth*" for source NAT rule "30" does not exist! In addition, the check for "any" is a substring test, so interface names like "a" or "ny" are treated as "any" and never checked.

set nat source rule 30 outbound-interface name 'eth*'
set nat source rule 30 translation address masquerade
commit

NAT, static NAT and NAT66 commits keep failing when the table and its rule file in /run get out of sync

The generated ruleset only deletes the old table if the matching rule file in /run exists. A rule file left behind without its table, for example after a failed commit, makes every following NAT commit fail with "Configuration file errors encountered!" until reboot.

Affected tables: ip vyos_nat (nat source/destination), ip vyos_static_nat (nat static) and ip6 vyos_nat (nat66).

set nat66 source rule 1 outbound-interface name eth1
set nat66 source rule 1 source prefix fc00::/64
set nat66 source rule 1 translation address masquerade
commit
sudo nft delete table ip6 vyos_nat
set nat66 source rule 2 outbound-interface name eth1
set nat66 source rule 2 source prefix fc02::/64
set nat66 source rule 2 exclude
commit

The FQDN_nat_* sets used by NAT rules with a domain name are declared twice in the generated ruleset. nft merges identical declarations, so there is no known effect on traffic, but the generated configuration is wrong.

set nat source rule 10 outbound-interface name eth0
set nat source rule 10 source fqdn example.com
set nat source rule 10 translation address masquerade
commit
grep -c 'set FQDN_nat_' /run/nftables_nat.conf

Details

Version
rolling-20261017
Is it a breaking change?
Perfectly compatible
Issue type
Bug (incorrect behavior)