NAT + Different outbound interface based on source

Hey there

I’ve got a router with a working NAT setup (172.16.0.x range) which forwards ports correctly, and users are able to SSH into the VM.

Outbound traffic works too as all traffic goes via eth1 (static IP). So far so good.

The requirement: I want to route outbound traffic for some of the VM’s out through another interface - eth4 (FYI this is a DHCP interface)

My current setup:

NAT-ROUTER# show nat source
 rule 50 {
     outbound-interface eth4
     protocol tcp
     source {
         address 172.16.0.20/32 // I want to route outbound traffic from this host through eth4
     }
     translation {
         address masquerade
     }
 }
 rule 100 {
     outbound-interface eth1
     protocol all
     source {
         address 172.16.0.0/24 // All other hosts outbound traffic should go via eth1 (this works fine already)
     }
     translation {
         address masquerade
     }
 }

Policy table:

NAT-ROUTER# show policy
 route eth1 {
     rule 3 {
         description "New rule - setup to route outbound traffic from eth4"
         destination {
             address 0.0.0.0/0
         }
         protocol all
         set {
             table 103
         }
         source {
             address 172.16.0.20/32
         }
     }
     rule 10 {
         destination {
             address 0.0.0.0/0
         }
         protocol all
         set {
             table 102
         }
         source {
             address 172.16.0.0/24
         }
     }
 }

And finally show protocols

NAT-ROUTER# show protocols
 static {
     route 0.0.0.0/0 {
         next-hop **HIDDEN - This is the eth1 gateway** {
         }
     }
     table 101 {
         interface-route 0.0.0.0/0 {
             next-hop-interface eth3 {
             }
         }
     }
     table 102 {
         route 0.0.0.0/0 {
             next-hop **HIDDEN - This is the eth1 gateway** {
             }
         }
     }
     table 103 {
         interface-route 0.0.0.0/0 {
             next-hop-interface eth4 { //eth4 is a DHCP interface
             }
         }
     }
 }

The problem:

Outbound traffic for 172.16.0.20 continues to be from eth1, instead of eth4.

Any ideas?

Thanks in advance :slight_smile:

Hi!

how do to determine that traffic is still going out through eth1? how are you testing?

Thanks!

Hey!

2 things - I’ve run a tcpdump on the interface, and I dont see anything on eth4. + I just run curl ifconfig.me to verify the outbound IP

Did you add policy to input interface ?

phpcat,

I have Tested your configuration on the rolling release and seems to be working

vyos@NAT-Router:~$ show policy route
Ruleset Information

---------------------------------
IPv4 Policy Route "to_eth0"

Active on: (eth2,route)

  Rule  Action    Protocol      Packets    Bytes  Conditions
------  --------  ----------  ---------  -------  -------------------------------------------------------------------
     5  set       all                 1       84  ip daddr 0.0.0.0/0 ip saddr 172.16.0.20  meta mark set 0x7fffff98
    10  set       all                 2      168  ip daddr 0.0.0.0/0 ip saddr 172.16.0.0/24  meta mark set 0x7fffff99

vyos@NAT-Router:~$ show nat sour translations 
Pre-NAT              Post-NAT             Prot  Timeout  
172.16.0.10          10.1.1.1             icmp  5        
172.16.0.20          10.0.0.1             icmp  9        
172.16.0.10          10.1.1.1             icmp  4

run these commands to check if you have hits under the policies:

show nat source statistics
show policy route <NAME>

also, check whether the static route has been installed properly under the corresponding table.

can you confirm what version are you using?

Unfortunately most of those commands return different results to the ones you’ve shared, probably because of the version. I’m unfortunately running an old version, 1.1.8.

Strange that you’ve got it working with the same setup…I’m guessing I’ve still got something wrong then. Is there any other commands I can run/share results with you to see where I’ve gone wrong?

Thank you!

Managed to run those commands…

NAT-ROUTER:~$ show nat source statistics  
rule   pkts    bytes   interface   
----   ----    -----   ---------   
50     0       0       eth4      (clearly nothing going out of eth4)  
60     0       0       eth1        
100    359M    10G     eth1

And…

NAT-ROUTER:~$ show nat source translations
Pre-NAT              Post-NAT             Prot  Timeout 
172.16.0.20         **eth1 IP**        udp   23

And… I think we may have found the problem @Lean - Looks like Rule 3 (the new one I setup with the eth4 interface) is throwing some errors? Specifically in vyatta-show-firewall.pl? Similar issue with rule10 too.

NAT-ROUTER:~$ show policy route 

-----------------------------
Rulesets Information
-----------------------------
--------------------------------------------------------------------------------
IPv4 Policy Route "eth1":

 Inactive - Not applied to any interfaces or zones.

rule  action   proto     packets  bytes                                   
----  ------   -----     -------  -----                                   
3     set      all       0        0                                       
  condition - saddr 172.16.0.20 daddr 0.0.0.0/0                                 
splice() offset past end of array at /opt/vyatta/bin/vyatta-show-firewall.pl line 330.
splice() offset past end of array at /opt/vyatta/bin/vyatta-show-firewall.pl line 353.
splice() offset past end of array at /opt/vyatta/bin/vyatta-show-firewall.pl line 359.
Use of uninitialized value $string_words_part2[1] in concatenation (.) or string at /opt/vyatta/bin/vyatta-show-firewall.pl line 365.
Use of uninitialized value $string_words_part2[0] in concatenation (.) or string at /opt/vyatta/bin/vyatta-show-firewall.pl line 366.
Use of uninitialized value $string_words_part1[3] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397.
Use of uninitialized value $string_words_part1[0] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397.
Use of uninitialized value $string_words_part1[1] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397.

10    set                                                                 
  condition - saddr  daddr                                                      
splice() offset past end of array at /opt/vyatta/bin/vyatta-show-firewall.pl line 330.
splice() offset past end of array at /opt/vyatta/bin/vyatta-show-firewall.pl line 353.
Use of uninitialized value $string_words_part2[1] in concatenation (.) or string at /opt/vyatta/bin/vyatta-show-firewall.pl line 365.
Use of uninitialized value $string_words_part2[0] in concatenation (.) or string at /opt/vyatta/bin/vyatta-show-firewall.pl line 366.
Use of uninitialized value $string_words_part1[3] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397.
Use of uninitialized value $string_words_part1[0] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397.
Use of uninitialized value $string_words_part1[1] in string at /opt/vyatta/bin/vyatta-show-firewall.pl line 397

@Lean Update: Restarted the router, errors have now disappeared. However the problem still exists…

NAT-ROUTER:~$ show policy route 

-----------------------------
Rulesets Information
-----------------------------
--------------------------------------------------------------------------------
IPv4 Policy Route "eth1":

 Inactive - Not applied to any interfaces or zones.

Based on your output, looks like the policy is not applied to the interface.

you need to configure the policy route inside the interface for them to work.

set interface eth ethX policy route <NAME>

the actual command might be different on your version.

Forgot to update the thread - this fixed it! I know we’re on an EOL and we’re looking to upgrade, but this just needed fixing.

Thanks for your help! I now have another issue but that deserves a separate thread.

Great to know, can you point towards the resolution? in the case that someone else has the same issue.