Matching in SNAT after DNAT

Gday, I would like some advice on how to use VyOS for a specific type of NAT.

I have a situation where I would like to NAT a connection matched on destination address and destination port. But I’d like to translate not only the destination port, but the source address also. So I need a DNAT and a corresponding SNAT.

There will be multiple connections, and the idea is, they will get different source addresses based on the original destination, and be re-routed to a common destination.

The problem is that the DNAT goes first, and since it translates the destination, I don’t know what to match on in the SNAT. If I was able to make the SNAT happen first, that would solve the problem. Or if I was somehow able to ‘mark’ the connection with the DNAT and then match on that in the SNAT, that would work too.

Here’s an example of two connections, where I’ve invented some non-existent connection marking feature to illustrate what I want to do:

set nat destination rule 89 destination address 192.168.222.222
set nat destination rule 89 destination port 10089
set nat destination rule 89 translation port 10000
set nat destination rule 89 modify mark '89'
set nat source rule 89 connection mark '89'
set nat source rule 89 translation address 10.1.1.89

set nat destination rule 96 destination address 192.168.222.222
set nat destination rule 96 destination port 10096
set nat destination rule 96 translation port 10000
set nat destination rule 96 modify mark '96'
set nat source rule 96 connection mark '96'
set nat source rule 96 translation address 10.1.1.96

Notice both connections are translated to the same destination, so I can’t use that in the SNAT rule.

Is there any way to do SNAT before DNAT, or achieve what I want in any other way in VyOS?

Other things to note:

  • All connections come from the same host, so I can’t match on that
  • The original source port is ephemeral, so I can’t match on that
  • The purpose of such a setup is to simulate connections from multiple clients to a common destination, when in reality they’re coming from a single host using a different destination port to differentiate each simulated client.

EDIT: I think it’s possible if I was using iptables instead of VyOS like this:

iptables -t mangle -A PREROUTING -d 192.168.222.222 -p tcp --dport 10106 -j CONNMARK --set-mark 89
iptables -t nat -A PREROUTING -d 192.168.222.222 -p tcp --dport 10089 -j DNAT --to-destination 192.168.222.222:10000
iptables -t nat -A POSTROUTING -m connmark --mark 89 -j SNAT --to-source 10.1.1.89

iptables -t mangle -A PREROUTING -d 192.168.222.222 -p tcp --dport 10096 -j CONNMARK --set-mark 96
iptables -t nat -A PREROUTING -d 192.168.222.222 -p tcp --dport 10096 -j DNAT --to-destination 192.168.222.222:10000
iptables -t nat -A POSTROUTING -m connmark --mark 96 -j SNAT --to-source 10.1.1.96

If iptables can do it, I would have guessed VyOS could… but maybe not?

It’s impossible to make source-nat happen before destination-nat.

So far we didn’t have options to match or set firewall marks in nat rules. You can create a feature request at https://vyos.dev/

And in the Iptables example you have provided, you are setting marks at table mangle → This can be done if you use policy route in VyOS Configuration. So setting mark to a connection can be done. We are only missing marks at source NAT in order to achieve this.

Thanks for the confirmation that I wasn’t missing anything. I’ll probably use iptables for my immediate needs, but I’ll investigate opening a feature request and/or what might be involved in developing and contributing a solution myself.

I haven’t so much as looked at the VyOS codebase, or tried building it. But assuming I can figure out an underlying netfilter feature to leverage, I can’t imagine it would be too difficult (famous last words) to figure out to add a new SNAT option.

Cheers.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.