Forum Discussion
hooleylist
Jun 13, 2012Cirrostratus
Here's an untested version that implements caching of the PTR records in the session table. Let me know if you see any issues testing this.
Look up the client IP to map its pointer record suffix to a pool name
Use a data group to map domain names to pool names
Manually cache pointer records in the session cache as there is a bug (BZ360270) which prevents TMM from caching PTR records as it should.
Check the config options for tmm.resolv.retry and tmm.resolv.timeout on the RESOLV::lookup wiki page!
https://devcentral.f5.com/wiki/iRules.resolv__lookup.ashx
when RULE_INIT {
Log debug to /var/log/ltm? 1=yes, 0=no.
set static::dns_debug 1
Ideally, use a DNS virtual server to perfor lookups against for redundancy
set static::dns_server my_dns_vs
...or less optimally, hardcode a DNS server IP address
set static::dns_server 4.2.2.2
Time (in seconds) to cache successful PTR lookups.
If the entry is not accessed in this time period a new resolution attempt will be made.
This is a workaround for BZ360270 which notes that RESOLV::lookup -ptr lookups are not cached like other records are
set static::cache_time 3600
Data group name which maps the domain names to a pool name
The logical data group format is expected to be:
Name=domain1.org, value=prod_pool
Name=domain1.com, value=non_prod_pool
The exact format of the data group depends on the LTM version
See these articles for details:
v11 - https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086510/v11-iRules-Data-Group-Updates.aspx
v10 - https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086448/iRules-Data-Group-Formatting-Rules.aspx
set static::ptr_to_pool_dg "ptr_to_pool_dg"
If the pointer to pool mapping data group does not exist, log an error
if {not [class exists $static::ptr_to_pool_dg]}{
log local0.emerg "Required data group $static::ptr_to_pool_dg does not exist! Using VS default pool"
}
}
when CLIENT_ACCEPTED {
If the pointer to pool mapping data group does not exist, log an error and exit
if {not [class exists $static::ptr_to_pool_dg]}{
log "[IP::client_addr]:[TCP::client_port]: Required data group $static::ptr_to_pool_dg does not exist! Using VS default pool [LB::server pool]"
return
}
Get pointer record for client IP address.
Check the session cache first using ptr_1.1.1.1 as the key, where 1.1.1.1 is the client IP address
set ptr [table lookup "ptr_[IP::client_addr]"]
Check if a pointer record was returned
if {$ptr eq ""}{
No cached ptr record so try a new resolution
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: No cached ptr, attempting resolution"}
set ptr [RESOLV::lookup @$static::dns_server -ptr [IP::client_addr]]
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Resolved $ptr"}
Check if a pointer record was returned
if {$ptr eq ""}{
No PTR, so use the VS default pool
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: No ptr from resolution, using default pool, [LB::server pool]"}
pool [LB::server pool]
Stop processing this event in this rule as there is no PTR
return
} else {
New resolution returned a result so cache it in the session table using ptr_1.1.1.1 as the key
where 1.1.1.1 is the client IP address
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Adding new ptr to cache for $static::cache_time seconds: $ptr"}
table set "ptr_[IP::client_addr]" $ptr $static::cache_time indefinite
}
}
We have a valid PTR either from cache or new resolution.
Check the data group named ptr_to_pool_dg to get the pool name
set pool [class match -value -- $ptr ends_with $static::ptr_to_pool_dg]
if {$pool eq ""}{
No match for domain, so use the VS default pool
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: No pool found for $ptr in $static::ptr_to_pool_dg"}
pool [LB::server pool]
} else {
Try to assign the matched pool, but use the default pool if the assignment fails
if {[catch {pool $pool} result]}{
if {$static::dns_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Error assigning pool $pool. Using default pool [LB::server pool]. Error: $error"}
pool [LB::server pool]
}
}
}
Aaron