Forum Discussion
GTM iRule - answering DNS based on some criteria.
Hi, I need some help with developing an iRule for DNS queries. Requirements:
-
check IP range a request came from (this is the easy bit which I have done already)
-
check monitor status - if specific IP is responding (on the client site - over VPN, MPLS, or any other private connection), answer the query with host (member) A, if the IP is not responding answer with host (member) B (this is the bit I am straggling with).
Any help much appreciated.
Regards Mariusz
11 Replies
- Brad_Parker
Cirrus
Have you thought about using a wideIP with two different pools with monitors attached? Setup your wideIP with global availibility with host A being in the pool with order 0.
- Mariusz_B
Nimbostratus
Thanks Brad.
At the moment I have one pool per wide IP which contains one server from DC1 and one server from DC2, with global fail-over as LB method so it's something similar to your suggestion. This works fine for one client, but I need to have a separate monitor for every single client. I don't want to re-direct all my MPLS and VPN clients if only one line fails. The idea is for GTM in DC2 to response with DC1 wide IP only, if the primary line (to DC1) fails. The problem is related to Linux BIND forwarder which does round-robin instead of global fail-over.
I hope that make more sense now.
Is it possible to refer to a monitor status in iRule?
So far I have the following:
when DNS_REQUEST if { [IP::addr [IP::client_addr] equals 10.1.10.136/29] or [IP::addr [IP::client_addr] equals 10.10.10.64/27] or [IP::addr [IP::client_addr] equals 10.1.10.96/28] } { if {monitor status which pings client IP is up } { host 1.1.1.1 else host 1.1.1.2So I am just trying to find the missing function.
- Brad_Parker
Cirrus
How about somthing like this:
when DNS_REQUEST { if { [IP::addr [IP::client_addr] equals 10.1.10.136/29] or [IP::addr [IP::client_addr] equals 10.10.10.64/27] or [IP::addr [IP::client_addr] equals 10.1.10.96/28] } { if {LB::status vs up} { host 1.1.1.1 } else { host 1.1.1.2 } } }You may also try using a data group if you ever decide to expand or change the IPs your are checking for.
- Mariusz_B
Nimbostratus
Thanks for suggestion with the data group.
I'll test this on Monday and let you know the outcome.
Many thanks!
- Mariusz_B
Nimbostratus
Hi Brad,
I have now developed this:
when DNS_REQUEST { if { [IP::addr [IP::remote_addr] equals $::All_Client_IPs] } { if {[LB::status vs Client_VPN_1] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } }but it doesn't work. Looks like is not possible to use data groups from the GSLB level.
I have successfully tested this instead:
when DNS_REQUEST { if { [IP::addr [IP::remote_addr] equals 10.10.10.10] } { if {[LB::status vs Client_VPN_1] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } }it's ok, but bit painful to use multiple "or" statements for multiple network ranges/IPs
Is there any workaround for that?
Many thanks
Mariusz
- StephanManthey
Nacreous
Hi Mariusz,
you can use a jump table (aka "switch") command to evaluate multiple conditions:switch [IP::remote_addr] { "10.10.10.10" if {[LB::status vs Client_VPN_1] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } "20.20.20.20" if {[LB::status vs Client_VPN_2] eq "up" } { host 3.3.3.3 } else { host 4.4.4.4 } }I´m not aware of another shortcut to simplify the VS availability check.
Thanks, Stephan - Brad_Parker
Cirrus
Are you using BigIP 11.x? If so, you can't use $::All_Client_IPs. Try this:
when DNS_REQUEST { if { class match [IP::remote_addr] equals All_Client_IPs } { if {[LB::status vs Client_VPN_1] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } } - Mariusz_B
Nimbostratus
Hi guys,
Thank you both for your suggestions.
@Stephan
I just did a small tweak to get this working, as it was complaining about a missing statement:
when DNS_REQUEST { switch [IP::remote_addr] { "10.10.100.0/24" { if {[LB::status vs LInk_Test_GTM] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } "10.10.200.0/24" { if {[LB::status vs LInk_Test_GTM] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } "10.10.10.10" { if {[LB::status vs LInk_Test_GTM] eq "up" } { host 1.1.1.1 } else { host 2.2.2.2 } } } }@Brad
Tried this way as well, but I get "invalid IP address" error. With the "$" sign syntax is accepted, but I am observing errors in the GTM log (this is probably valid for predefined variables within the iRule only). Data groups option is only available from DNS>Delivery>iRules>Data Group List, but I need the iRule to be created/applied on GSLB section where DGL is missing (there is only GSLB>iRules available). Unless there is a way to create them "on the fly" within the iRule...
- Brad_Parker
Cirrus
If the switch method is working that's all that matters, its more than ok to do it that way. I think with the small list you are working with here it would actually be a little more efficient using the switch, though it would probably be a negligible performance difference. - Mariusz_B
Nimbostratus
Thank you Brad once again! Sorry for late reply.
- mriggs_140553
Nimbostratus
We use separate pools for each answer and just base it off whether the pool has any active members.
if {[active_members pool1] < 1 }{ DNS::disable all pool pool2 } else { DNS::disable all pool pool1 }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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