RoutingLoop_179
Jan 29, 2013Cirrus
my DNS irule - how can i optimise it further or is there a better way?
Hi - i've created an irule losely based on DNS blackhole irules i've seend to rewrite DNS responses.
But my rule basically has to check a client source address against a list of subnets in a datagroup and if it matches it then needs to check the DNS name is contained in say a whitelist datagroup and then return the DNS response based on the datagroup value. However, i have to repeat this for different source address datagroups and whitelists.
The issue i have because i'm checking against datagroups i've ended up with multiple if - elseif and embedded if/else. Which optimisation 101 says avoid if you can. I cna't use switch because datagroups aren't supported. I've tried ot look at the timings with "timings on" but haven't got my head around the numbers yet.
Anyway speed and performance is most important - but is there a better way of doing this?
Any help or hints are appreciated
Adrian
my DNS irule:
timing on
when RULE_INIT {
set static::whitelist_ttl "300"
}
when DNS_REQUEST {
set fqdn [DNS::question name]
debugging statement see all questions and request details
log -noname local0. "Client: [IP::client_addr] Question:[DNS::question name] Type:[DNS::question type] Class:[DNS::question class] Origin:[DNS::origin]"
Whitelist_Match is used to track when a Query matches the whitelist
Ensure it is always set to 0 or false at beginning of the DNS request
set Whitelist_Match 0
does the client source address exist in site address external data-group
if { [class match [IP::client_addr] equals site1_address_datagroup] } {
does FQDN exist in our whitelist datagroup for that site.
if { [class match $fqdn equals site1_whitelist] } {
Client made a DNS request for a Whitelist site.
set Whitelist_Match 1
set FakeIPv4 [class match -value $fqdn equals site1_whitelist]
DNS::return
} elseif { [class match $fqdn ends_with site1_wildcard] } {
set Whitelist_Match 1
set FakeIPv4 "198.18.255.254"
DNS::return
}
} elseif { [class match [IP::client_addr] equals site2_address_datagroup] } {
does FQDN exist in our whitelist string:value datagroup for that site.
if { [class match $fqdn equals site1_whitelist] } {
Client made a DNS request for a Whitelist site.
set Whitelist_Match 1
set FakeIPv4 [class match -value $fqdn equals site2_whitelist]
DNS::return
} elseif { [class match $fqdn ends_with site2_wildcard] } {
set Whitelist_Match 1
set FakeIPv4 "198.18.255.254"
DNS::return
}
} elseif { [class match [IP::client_addr] equals site3_address_datagroup] } {
does FQDN exist in our whitelist string:value datagroup for that site.
if { [class match $fqdn equals site3_whitelist] } {
Client made a DNS request for a Whitelist site.
set Whitelist_Match 1
set FakeIPv4 [class match -value $fqdn equals site3_whitelist]
DNS::return
} elseif { [class match $fqdn ends_with site3_wildcard] } {
set Whitelist_Match 1
set FakeIPv4 "198.18.255.254"
DNS::return
}
}
add further elseif's for more sites.... e.g site3, site4 site_n....
If Whitelist match is still 0 check common whitelist datagroup.
if { !$Whitelist_Match } {
if { [class match $fqdn equals CM_HTTPS_WL] } {
set Whitelist_Match 1
set FakeIPv4 [class match -value $fqdn equals CM_HTTPS_WL]
DNS::return
} elseif { [class match $fqdn ends_with CM_WC_WL] } {
set Whitelist_Match 1
set FakeIPv4 "198.18.255.254"
DNS::return
}
}
}
when DNS_RESPONSE {
debugging statement to see all questions and request details
log -noname local0. "Request: $fqdn_name Answer: [DNS::answer] Origin:[DNS::origin] Status: [DNS::header rcode] Flags: RD [DNS::header rd] RA [DNS::header ra]"
if { $Whitelist_Match } {
This DNS request was for a Whitelist FQDN. Take different actions based on the request type.
switch [DNS::question type] {
"A" {
Clear out any DNS responses and insert the custom response. RA header = recursive answer
DNS::answer clear
DNS::answer insert "$fqdn. $static::whitelist_ttl [DNS::question class] [DNS::question type] $FakeIPv4"
DNS::header ra "1"
whitelist: 10.1.1.1484902 requested foo.com query type: A class IN A-response: 10.1.1.60
log -noname local0. "whitelist: [IP::client_addr][UDP::client_port] requested [DNS::question name] query type: [DNS::question type] class [DNS::question class] A-response: $FakeIPv4"
}
"AAAA" {
DNS::last_act reject
}
default {
For other record types, e.g. MX, NS, TXT, etc, provide a blank NOERROR response
DNS::last_act reject
rejected: 10.1.1.1484902 requested foo.com query type: A class IN unable to respond
log -noname local0. "rejected onwl1: [IP::client_addr][UDP::client_port] requested $fqdn query type: [DNS::question type] class [DNS::question class] non whitelisted DNSRR"
}
}
}
}