Forum Discussion
J_Peterman_4266
Nimbostratus
Jul 18, 2012Having trouble with destination based SNAT irule
We are looking to implement destination based SNAT via iRule where all traffic destined to RFC 1918 space does not get SNAT outbound and it retains its private addressing, all other traffic destined to public addressing gets SNAT outbound for internet specific connectivity. The problem is that the iRule that I have created and applied to a basic IP forwarding Virtual Server is not matching and performing "snat none" or simply "forward" and instead all traffic outbound is getting SNAT. Can anyone point out what might be going on?
[IP addressing has been changed to protect the innocent]
Here is my iRule:
when CLIENT_ACCEPTED {
Check if the remote address is part of the private_nosnat data group
if { [class match [IP::remote_addr] equals private_nosnat]} {
don't do anything
log local0. "MATCH NO SNAT CLASS"
snat none
} else {
snat behind this address
snat 1.1.1.1
}
}
the datagroup private_nosnat includes three networks defined:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Again, this is applied to a virtual server that just matches all destinations and forwards on. The problem is that the first if statement isn't working and all traffic is getting SNAT on the final else statement.
Any insight is greatly appreciated.
20 Replies
- nitass
Employee
if { [class match [IP::remote_addr] equals private_nosnat]} {i understand IP::remote_addr is client address in client-side context event e.g. CLIENT_ACCEPTED. can you try IP::local_addr? - J_Peterman_4266
Nimbostratus
The change to local_addr from remote_addr doesn't make any difference. It is still natting everything outbound regardless of the destination address.
when CLIENT_ACCEPTED {
Check if the remote address is part of the private_nosnat data group
if { [class match [IP::local_addr] equals private_nosnat]} {
don't do anything
log local0. "MATCH NO SNAT CLASS"
snat none
} else {
snat behind this address
snat 1.1.1.1
}
} - J_Peterman_4266
Nimbostratus
The change to local_addr from remote_addr doesn't make any difference. It is still natting everything outbound regardless of the destination address.
when CLIENT_ACCEPTED {
Check if the remote address is part of the private_nosnat data group
if { [class match [IP::local_addr] equals private_nosnat]} {
don't do anything
log local0. "MATCH NO SNAT CLASS"
snat none
} else {
snat behind this address
snat 1.1.1.1
}
} - nitass
Employee
The change to local_addr from remote_addr doesn't make any difference. It is still natting everything outbound regardless of the destination address. have you got "MATCH NO SNAT CLASS" log? - J_Peterman_4266
Nimbostratus
Here is what I have from the log. I updated to Log on both instances. Here is what I'm seeing. It is only matching the second rule in which it logs MATCH AND SNAT. This is true when I use local_addr, client_addr, or remote_addr.
iRule:
when CLIENT_ACCEPTED {
Check if the remote address is part of the private_nosnat data group
if { [class match [IP::remote_addr] equals private_nosnat]} {
don't do anything
log local0. "MATCH NO SNAT CLASS"
snat none
} else {
snat behind this address
log local0. "MATCH AND SNAT"
snat 1.1.1.1
}
}
LOGS:
ltm 07-19 17:14:56 info local/tmm1 tmm1[5219]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:57 info local/tmm3 tmm3[5222]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:57 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:58 info local/tmm1 tmm1[5219]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:58 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:59 info local/tmm3 tmm3[5222]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:59 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:59 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:14:59 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:00 info local/tmm1 tmm1[5219]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:00 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:01 info local/tmm3 tmm3[5222]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:01 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:02 info local/tmm1 tmm1[5219]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:02 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:03 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:04 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 17:15:04 info local/tmm tmm[5217]: Rule prod_nonprivate_snat : MATCH AND SNAT - nitass
Employee
can you list private_nosnat data group i.e. b class private_nosnat list?
and can you add log command in the irule to log IP::local_addr address? - Brian_Van_Stone
Nimbostratus
In the context of this iRule and these connections I would expect remote_addr to return the IP of the server (identical to client_addr in the clientside context) and local_addr to return the self IP of BigIP in the vlan where the server lives (unless I misunderstood how local_addr should work).
I was thinking that [IP::server_addr], which is the same as [serverside {IP::remote_addr}], might be what you're looking for. You're interested in getting the destination address, and the three options you have tried are all in the clientside context.
The part that boggles me is: and it retains its private addressing
I would expect that if the server initiating this connection has a local address the first piece would always execute when using [IP::client_addr] or [IP::remote_addr] rather than the other way around. - J_Peterman_4266
Nimbostratus
Posted By Brian Van Stone on 07/19/2012 10:52 AM
In the context of this iRule and these connections I would expect remote_addr to return the IP of the server (identical to client_addr in the clientside context) and local_addr to return the self IP of BigIP in the vlan where the server lives (unless I misunderstood how local_addr should work).
I was thinking that [IP::server_addr], which is the same as [serverside {IP::remote_addr}], might be what you're looking for. You're interested in getting the destination address, and the three options you have tried are all in the clientside context.
The part that boggles me is: and it retains its private addressing
I would expect that if the server initiating this connection has a local address the first piece would always execute when using [IP::client_addr] or [IP::remote_addr] rather than the other way around.
Hopefully this explanation helps clarify what I'm attempting to accomplish.
What I mean is that we want traffic that has a destination address in the RFC1918 ranges outlined in private_snat group to not be SNAT outbound, but all traffic destined to everything else (Public) to be SNAT to a public facing external address.
Topology of outbound traffic:
Server -> Loadbalancer -> Internet
Example where we do want SNAT to occur (the last else statement):
Server IP: 10.x.x.x attempting to connect out to an internet server, yahoo for sake of example
Traffic needs to hit the LB and get SNAT to a public address (1.1.1.1) so that it is publically routable out to the internet.
Example where we do not want SNAT to occur (the first if statement):
Server IP: 10.x.x.x attempting to connect to a server in another data center with a destination of 192.168.x.x (all private internal network connectivity, no internet and thus no public SNAt required).
Traffic in this example should come from the server destined to 192.168.x.x and match the first IF statement and simply be forwarded on without SNAT because the destination falls within the private_nosnat group.
This was considerably easier on other platforms to accomplish (ACE LB, firewalls with nat lists, etc). Struggling to get this iRule to work appropriately and figure out the correct syntax to accomplish SNAT or NO SNAT based upon the destination of traffic outbound. - J_Peterman_4266
Nimbostratus
Posted By nitass on 07/19/2012 10:47 AM
can you list private_nosnat data group i.e. b class private_nosnat list?
and can you add log command in the irule to log IP::local_addr address?
ltm data-group private_nosnat {
partition Production
records {
10.0.0.0/8 { }
172.16.0.0/12 { }
192.168.0.0/16 { }
}
type ip
}
I have turned on logging of both the remote_addr, and the local_addr below and am attempting to connect to the remote_addr (which should be matched in the first if clause based on the logic of "if class match IP::remote_addr equals private_nosnat, but as you can see below, it isn't matching and it is instead just going onto the else statement and SNAT'ing outbound.
ltm 07-19 19:04:17 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : MATCH AND SNAT
ltm 07-19 19:04:17 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : 10.128.10.15%1
ltm 07-19 19:04:17 info local/tmm2 tmm2[5220]: Rule prod_nonprivate_snat : 10.35.157.15%1
Very confused... - hoolio
Cirrostratus
The issue is that the class command doesn't support route domains. See this post for details and possible workarounds:
https://devcentral.f5.com/Community/GroupDetails/tabid/1082223/asg/50/aft/1172490/showtab/groupforums/Default.aspx
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects