Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

applying snat based on route out of local network

Howdy,

Our LTM's sit between our client networks and our server networks, switching all data on a vlan group to gain full visibility of all traffic. this is not an exact split though, and obviusly we also require the big-ip to be involved in other server - server balancing not jsut client - server. As such some traffic needs to be snatted, but i would like to avoid it where ever possible for clarity. The simplest solution, if possible, is to have logic that states that if the next hop for the client and the server in each connection are the same then apply a snat, if not, do nothing. This logic appeals to me as it abstracts the actual subnets to the base routing on the box, and i wouldn't need to maintain arbitrary lists of different subnets, which i would expect to also be more computationally expensive.

I've seen the LINK::nexthop option in the wiki, but 1) there is no description of it and 2) i'm running 9.1.1 while it states it was added in 9.2.0. Can anyone say if this would do what i wanted, and if there is a suitable way to achieve what i want on a global level.

I would assume that this irule would need to be added on a per virtual server basis, but that's fair enough i guess. I know there are SNAT objects outside of iRules but these don't look like they would provide sufficent details for what i need to achieve.

Many thanks

Chris
0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Maybe something like this would do the trick?


rule snat_same_subnet {
when LB_SELECTED {
if { [IP::addr [IP::local_addr]/24 equals [IP::remote_addr]/24] } {
snat automap
}
}
}


Or you could use a different virtual server for same-subnet communications vs. different subnets.

i.e.


pool my_servers {
member 5.5.5.5:80
member 5.5.5.6:80
}
virtual internal-web {
destination 1.1.1.1:80
snat automap
pool my_servers
}
virtual external-web {
destination 2.2.2.2:80
pool my_servers
}


Access "1.1.1.1" when you need SNAT, and access "2.2.2.2" otherwise.

Or, since the virtual server lookup key includes the VLAN, this modified version of the above should also work:


pool my_servers {
member 5.5.5.5:80
member 5.5.5.6:80
}
virtual internal-web {
destination 2.2.2.2:80
snat automap
vlans internal enable
pool my_servers
}
virtual external-web {
destination 2.2.2.2:80
vlans internal disable
pool my_servers
}


(same IP address for both virtual servers, but external-web is enabled on all VLANs *except* internal, and internal-web is *only* enabled in the internal VLAN).

I'm sure there are probably 10 more ways, too -- BIG-IP is awesome.

Good luck!

a1l0s2k9
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Thanks for the ideas. I was thinking about seperate snat and non-snat rules, but when you're looking at it in a live environment it doesn't seem too acceptable to have a dns server one side of a router, and a different one for the other side...

I think i'm going to be looking at a matchclass for the time being, containing my server side subnets. Ultimately i'll never ever know all the addresses i could be coming from but a can check whether client and destination and both in or out of a class.

What about this:
when LB_SELECTED {
set ::client_match [matchclass [IP::client_addr] equals $::server_networks]
set ::server_match [matchclass [LB::server addr] equals $::server_networks]

if { $::client_match == 0 and $::server_match > 0 } {
return
} elseif { $::client_match > 0 and $::server_match == 0 } {
return
}
snatpool mt_snatpool
}

Ugliness here rises from there being no XOR operator as far as i am aware and the matchclass returning the number of the entry in the list if there is one, and not just 0 and 1 (otherwise you could add the two results and see if it still equals 1).

Unless i'm missing something fundamental this sort of logic would need to apply to virtually EVERY single connection in order to avoid SNAT's when possible, but add automatically otherwise. Luckily my "internal" networks are finite and small, so is still manageable, but it's still not as nice as being able to check outright if they are on the same side of the box. As i am using an internal and external vlan joined on a vlan group that seems like a shame. I can see what vlan my client is coming from, but can't for the server part of it.

Thanks
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
A bit more work and it's a bit better and more efficient (I think)
  when LB_SELECTED {

# server_networks is a data group / class defined elsewhere

# start with zero score
set snat_score 0

# increase score if client is on server network
if {[matchclass [IP::client_addr] equals $::server_networks]} {
incr snat_score
}

# increase score if server is on server network
if {[matchclass [LB::server addr] equals $::server_networks]} {
incr snat_score
}

# if score is not 1 then client and server are on
# same side of LTM, so SNAT is required
if { $snat_score != 1 } {
snatpool my_snatpool
}
}
Of course if i'm missing something really fundamental here about the need to SNAT then i'd appreciate advice!
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
What are you losing by using SNAT? (Also, what protocols?)

I just use SNAT automap at the VIP level when the application needs will let me get away with it.

-Brian
0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER
Well when possible we want to know where the connection came from on the server, and I am after a way to apply this generically across the board on any service. My tests have generally been on dns lookups and such, but if it's us rediredcting http traffic to a proxy using ident authentication or whatever then we would want to avoid the snat. Also there is the visibility of the traffic in general. If we have 3000 clients coming from a 10 ip snat pool and some are causing trouble, the snat is a big obstacle.

Currently we have servers on both sides of the box, so having a simple way to snat if it's needed, and not if we don't have to should hopefully provide the benefits of no snatting without having to realise whether we need to or not. if a server moves from one side to another, then the requirement to Snat will change, but using this sort of test, it would be taken in its stride.

I wouldn't expect to be using a rule like this on *everything*... i'm sure that stuff like dns would be better off just automapped and then ignored forever more, I just don't want to get caught out with many arbitrary things to check on, when an irule like this will just do what must be done, and nothing else.

I assume you think this all sounds pointless... and you may well be right, but currently i'm just about to put our beasts live in a data center and want to feel comfortable with what's going to happen.

Cheers

Chris
0