Forum Discussion
squeezebox_2829
Nimbostratus
Aug 05, 2016HTTP::retry doesn't work on BIGIP LTM 10.2.4
I am attempting to reference an external service which performs a lookup based on the request's ip address and returns a response either allowing or disallowing the traffic. I am using the solution p...
Kai_Wilke
MVP
Aug 08, 2016Hi Squeezebox,
good to know that the iRules is (more or less) working for you and that you've found the remaining glitches by your own. I've also found a remaining bug, which is fixed in the version below...
when RULE_INIT {
set string to match for valid connection
set static::valid_string "Sure"
set static::table_cache_duration "10" ; seconds
}
when CLIENT_ACCEPTED {
set flag to control logical flow. 1 means lookup is pending.
set lookup 1
set get_request 0
}
when HTTP_REQUEST {
If each request on the same connection must force a lookup,
re-initialize the value of the flag here
In this case, lookup result based on client IP is good for
the life of the connection, so we'll leave the flag alone here.
if { $lookup } then {
verify only GET request.
if { [HTTP::method] eq "GET" } then {
try to offload the verification of the current request with data of previous lookup results
if { [table lookup -notouch "is_allowed_[IP::client_addr]"] eq "" } then {
No previous request data is cached. Performing an online verification...
save the request so we can replay it to the LB server later;
set orig_request [HTTP::request]
inject lookup URI in place of original request;
HTTP::uri "/getAllowed?ip=[IP::client_addr]"
remove any cookie information for security purposes
HTTP::header remove "Cookie"
and send the out-of-band validation query to the DB_pool.
pool geo_pool
} else {
The client is verified using cached results.
set lookup 0
pool reg_pool
}
set get_request 1
} else {
Current request is not a GET request. Do not verify the request to reduce complexity of collection and replay of HTTP::payload data.
set get_request 0
pool reg_pool
}
}
}
when HTTP_RESPONSE {
If lookup flag is still on in response event, this is the response
to the lookup, so we collect entire payload (up to 1MB limit)
both to evaluate the DB server response and to prevent this response
from being returned to the client.
Already-validated connections will bypass the rest of the rule.
if { $lookup and $get_request } then {
if { ( [HTTP::header value "Content-Length"] ne "" ) and
( [HTTP::header value "Content-Length"] < 1048576) } then {
HTTP::collect [HTTP::header "Content-Length"]
} else {
HTTP::collect 1048576
}
}
}
when HTTP_RESPONSE_DATA {
HTTP_RESPONSE_DATA will only be triggered for a DB lookup.
(All other requests have already been forwarded to the LB pool.)
If response from DB indicates connection is valid, reset the
lookup flag & replay the request to the LB server.
Otherwise, reject the connection
if { [HTTP::payload] contains $static::valid_string} then {
Cache the OK response to offload subsequent requests
table set "is_allowed_[IP::client_addr]" "1" indefinite $static::table_cache_duration
Replay the origianl request
set lookup 0
pool reg_pool
HTTP::retry $orig_request
} else {
log "rejected"
reject
}
}
Note: The bugfix makes sure that just the non-GET requests can bypass the IP validation (added the variable
and additional checks). In the previous version of my iRule it was possible, to unlock the full communication by using a single non-GET request.$get_request
Cheers, Kai
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