Forum Discussion

andrew_C1's avatar
andrew_C1
Icon for Nimbostratus rankNimbostratus
Nov 11, 2015

possible to double/twice nat on F5?

Hi,

 

I have the fun task of making a F5 with ltm+afm replace a cisco FWSM that is a bridge between overlapping networks ( company mergers).

 

Right now the FWSM does 4 task related to nat, 3 of them are easy to cover off, 1. DNS rewrite/doctor of real/nat addresses, done with an irue and a data group 2. one way pats ( 1 pat address for a prefix) again a simple irule doing snat + a data group lookup 3. static one to one nats, done with nat lists.

 

Now for the hard one that im not sure how to approach. When both 2 and 3 happen to the same flow at the same time or if 3 happens twice. So what happens on the FWSM is that nat occurs on both ingress and egress. On ingress the FWSM either 1:1 nats or pats and on egress 1:1 nats.

 

The end result is both and source and destination addresses are translated via a two step process, the source on ingress and the destination on egress. To make things even more fun either side of the FWSM can be the originator of connections.

 

So does any one have any example of how to accomplish this?

 

my initial thought looking through the irule wiki is two data group lookups one for snat ( set the source) and the other using the node command( to set the dest). But before i go down that path ( i find simple tasks in tcl frustrating compared to languages i actually know) is there a better way?

 

cheers

 

2 Replies

  • You can accomplish this with virtual servers, but that will require two virtual servers for each of your NATs to cover traffic flowing in both directions. To do this in an iRule may be "easier" as you will only need one vip, 0.0.0.0/0, and two data groups. You could try something like this. Obviously you will need entries for both sides connections could originate from.

    when CLIENT_ACCEPTED {
        if source matches in the data group snat it to the value of that entry
        if {[class match [IP::client_addr] patList_dg]}{
            snat [class lookup [IP::client_addr] patList_dg]
        }
        if destination matches in the data group direct traffic to the value of the entry
        if {[class match [IP::local_addr] natList_dg]}{
            node [class mlookup [IP::local_addr] natList_dg]
        }
    }
    
  • ok this ended up taking far more time then i expected, i was originally developing on a 3600/ 11.1 box... big mistake.. Then i couldn't get the node command to actually do anything for ages, until i found the translate command...........

    There is no routing setup on the F5 at all all forwarding is via the set next_hop command when CLIENT_ACCEPTED {

        log local5. " vlan id is [LINK::vlan_id]  src [IP::client_addr] dst [IP::local_addr]"
        if { [LINK::vlan_id] == "200"} {
            log local5. " vlan id is [LINK::vlan_id] inside "
            if source matches in the data group snat it to the value of that entry
            if { [class match [IP::client_addr] equals inside_patList_dg] } {
                snat [class lookup [IP::client_addr] inside_patList_dg]
                log local5. " inside snat lookup [class lookup [IP::client_addr] inside_patList_dg]"
            }
        set next_vlan f5-test-outside-transit
        set next_hop 10.210.0.1%1
        }
    
    
    
        if { [LINK::vlan_id] == "210"} {
    
            log local5. " vlan id is [LINK::vlan_id] outside "
            if source matches in the data group snat it to the value of that entry
            if { [class match [IP::client_addr] equals outside_patList_dg] } {
                set test [class lookup [IP::client_addr] outside_patList_dg]
                snat $test
    
                 log local5. "outside snat check worked new src [IP::client_addr] dst [IP::local_addr] test $test"
            }
        set next_vlan f5-test-inside-transit
        set next_hop 10.200.0.1%1
    
        }
    
        if destination matches in the data group direct traffic to the value of the entry
        if {[class match [IP::local_addr] equals natList_dg]}{
            translate address enable
             node [class lookup [IP::local_addr] natList_dg]
             log local5. "outside node lookup [class lookup [IP::local_addr] natList_dg] src [IP::client_addr] "
        }
    
    log local5. "next hop vlan $next_vlan ip $next_hop"
    nexthop $next_vlan $next_hop
    }
    

    the packet cap of victory

    01:51:38.806639 IP 192.168.1.10.ewall > 10.10.0.10.microsoft-ds: S 3188598590:3188598590(0) win 65535 
    01:51:38.806753 IP 10.10.0.10.ewall > 192.168.1.10.microsoft-ds: S 3188598590:3188598590(0) win 65535 
    01:51:38.806638 IP 192.168.1.10.netdb-export > 10.10.0.10.netbios-ssn: S 1916429907:1916429907(0) win 65535 
    01:51:38.806773 IP 10.10.0.10.netdb-export > 192.168.1.10.netbios-ssn: S 1916429907:1916429907(0) win 65535 
    01:51:38.808348 IP 192.168.1.10.netbios-ssn > 10.10.0.10.netdb-export: S 1171958153:1171958153(0) ack 1916429908 win 65535 
    01:51:38.808354 IP 10.10.0.10.netbios-ssn > 192.168.1.10.netdb-export: S 1171958153:1171958153(0) ack 1916429908 win 65535 
    01:51:38.808605 IP 192.168.1.10.microsoft-ds > 10.10.0.10.ewall: S 3142739781:3142739781(0) ack 3188598591 win 65535 
    01:51:38.808610 IP 10.10.0.10.microsoft-ds > 192.168.1.10.ewall: S 3142739781:3142739781(0) ack 3188598591 win 65535 
    01:51:38.810366 IP 192.168.1.10.ewall > 10.10.0.10.microsoft-ds: . ack 1 win 65535
    01:51:38.810369 IP 10.10.0.10.ewall > 192.168.1.10.microsoft-ds: . ack 1 win 65535
    01:51:38.810618 IP 192.168.1.10.ewall > 10.10.0.10.microsoft-ds: P 1:138(137) ack 1 win 65535
    01:51:38.810620 IP 10.10.0.10.ewall > 192.168.1.10.microsoft-ds: P 1:138(137) ack 1 win 65535