Page MenuHomeVyOS Platform

NAT source/destination negated ports throws an error
Closed, ResolvedPublicBUG

Description

Completion:

vyos@vyos# set nat source rule 10 destination port
Possible completions:
   <1-65535>    Numeric IP port
   start-end    Numbered port range (e.g. 1001-1005)
   None

Multiple destination ports can be specified as a comma-separated list.
The whole list can also be negated using '!'.
For example: '!22,telnet,http,123,1001-1005'

Using the example in completion results in an exception:

Traceback (most recent call last):
  File "/usr/libexec/vyos/conf_mode/nat.py", line 206, in <module>
    generate(c)
  File "/usr/libexec/vyos/conf_mode/nat.py", line 188, in generate
    if os.path.exists(nftables_ct_file):
NameError: name 'nftables_ct_file' is not defined

noteworthy:
cmd 'nft -c -f /tmp/vyos-nat-rules.nft'
returned (out):

returned (err):
/tmp/vyos-nat-rules.nft:20:72-72: Error: syntax error, unexpected !
add rule ip nat POSTROUTING oifname "eth0" ip protocol tcp tcp dport { !22,telnet,http,123,1001-1005 } counter snat to 172.16.10.1 comment "SRC-NAT-10"

Details

Difficulty level
Unknown (require assessment)
Version
1.4 / 1.3.0
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

This issue is due to negated source/destination port not being handled properly in code, not validation.

This will work: telnet,http,123,1001-1005 but if you add a "not" port (!22) to the list, the command will fail.

I've used for these tests (VyOS 1.4-rolling-202202010836)
The same situation in general when you want to use "!".
Bad exampels.

set nat source rule 10 destination port !1-5
set nat source rule 10 destination port !22
set nat source rule 10 destination port !http
set nat source rule 10 destination port telnet,!http,!123,1001-1005
set nat source rule 10 destination port telnet,http,!123,1001-1005

Without "!" everything is well.


VYOS 1.3.0 works well !!!

Version:          VyOS 1.3.0
Release train:    equuleus

Built by:         Sentrium S.L.
Built on:         Sun 19 Dec 2021 12:59 UTC


vyos@vyos# set nat source rule 10 destination port !1-5
[edit]
vyos@vyos# commit
[edit]
  1. Negated ports: erros while writing command.

For example:

set nat source rule 10 destination port !80

Gives next error:

returned (err):
/tmp/vyos-nat-rules.nft:14:72-72: Error: syntax error, unexpected !
add rule ip nat POSTROUTING oifname "eth0" ip protocol tcp tcp dport { !80 } counter masquerade comment "SRC-NAT-10"

While actually rule should be something like this:

add rule ip nat POSTROUTING oifname "eth0" ip protocol tcp tcp dport != { 80 } counter masquerade comment "SRC-NAT-10"

If this is corrected, user will be able to define negated range or negate multiple ports. Example, using negated port group and range:

chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		oifname "eth0" tcp dport != 66 counter packets 0 bytes 0 masquerade
		oifname "eth0" tcp dport != { 88, 99 } counter packets 0 bytes 0 masquerade
		oifname "eth0" tcp dport != { 101-110 } counter packets 0 bytes 0 masquerade
  1. As far as I've tested, it's not possible to add a rule matching negated and non negated values, as describe in the help "!22,telnet,http,123,1001-1005"

So, to conclude, besides from correcting how negated port is written, I would also suggest modifying options in our cli, moving from:

vyos@vyos# set nat source rule 10 destination port 
Possible completions:
   <text>       Named port (any name in /etc/services, e.g., http)
   <1-65535>    Numeric IP port
   start-end    Numbered port range (e.g. 1001-1005)
   None         

Multiple destination ports can be specified as a comma-separated list.
The whole list can also be negated using '!'.
For example: '!22,telnet,http,123,1001-1005'

To (trying to look similar as addresses, and how, for example, negated tcp flags are available in new firewall cli):

vyos@vyos# set nat source rule 10 destination port 
Possible completions:
   <text>       Named port (any name in /etc/services, e.g., http)
   <x>          Numeric IP port from 1 to 65535
   <x>-<x>      Numbered port range (e.g. 1001-1005)
   > not        Match negated port/ports
   None          

Multiple destination ports can be specified as a comma-separated list.
For example: '22,telnet,http,123,1001-1005'



vyos@vyos# set nat source rule 10 destination port not 
Possible completions:
   <text>       Named port (any name in /etc/services, e.g., http)
   <x>          Numeric IP port from 1 to 65535
   <x>-<x>      Numbered port range (e.g. 1001-1005)
   None

Multiple destination ports can be specified as a comma-separated list.
For example: '22,telnet,http,123,1001-1005'
Viacheslav changed the task status from Open to In progress.Apr 25 2022, 11:22 AM
Viacheslav claimed this task.

PR https://github.com/vyos/vyos-1x/pull/1300

vyos@tstrtr2# run show conf com | match nat
set nat source rule 10 destination port '!80'
set nat source rule 10 outbound-interface 'eth4'
set nat source rule 10 protocol 'tcp'
set nat source rule 10 translation address 'masquerade'
set nat source rule 20 outbound-interface 'eth4'
set nat source rule 20 protocol 'tcp'
set nat source rule 20 source port '!99'
set nat source rule 20 translation address 'masquerade'

Nft rules:

table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
		counter packets 0 bytes 0 jump VYOS_PRE_DNAT_HOOK
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		counter packets 72 bytes 4320 jump VYOS_PRE_SNAT_HOOK
		oifname "eth4" tcp dport != { 80 } counter packets 0 bytes 0 masquerade comment "SRC-NAT-10"
		oifname "eth4" tcp sport != { 99 } counter packets 0 bytes 0 masquerade comment "SRC-NAT-20"
	}
Viacheslav changed the task status from In progress to Needs testing.Apr 26 2022, 6:22 AM

VyOS 1.3.1-S1 is not affected:

table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority dstnat; policy accept;
		counter packets 1 bytes 112 jump VYATTA_PRE_DNAT_HOOK
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority srcnat; policy accept;
		counter packets 1 bytes 112 jump VYATTA_PRE_SNAT_HOOK
		oifname "eth3" meta l4proto tcp tcp dport != 80 counter packets 0 bytes 0 masquerade  comment "SRC-NAT-10"
		oifname "eth3" meta l4proto tcp tcp sport != 99 counter packets 0 bytes 0 masquerade  comment "SRC-NAT-20"
	}
Viacheslav moved this task from Need Triage to Finished on the VyOS 1.4 Sagitta board.

Fixed VyOS 1.4-rolling-202204260601

set nat source rule 10 destination port '!22,telnet,http,123,1001-1005'

nft:

oifname "eth4" tcp dport != { 22-23, 80, 123, 1001-1005 } counter packets 0 bytes 0 masquerade comment "SRC-NAT-10"