Forum Discussion
ryan_111816
Nimbostratus
Nov 18, 2009Limiting Duplicate HTTP GETs
Hi folks. I'm new to DevCentral so I apologize if I'm posting in the wrong place. I've been running a couple of old v4 BIG-IPs for years and just recently made the jump to a couple of LTM-1600's wi...
hoolio
Cirrostratus
Dec 18, 2009Hi Matt / Ryan,
I was thinking of just tracking the number of requests made to a restricted URI over the course of a timeout period using the session table. A request would only be allowed if the cookie / path combination was under a limit of requests over a configured time interval.
One downside I can see with using the session table like this is that the count of requests could get distorted if requests are spaced out in the timeout interval. For example if the timeout interval was 5 seconds, and there was a request every four seconds, the count would accumulate all of the requests until the count reached the limit. This might not be an issue based on the problem statement of lots of requests over a very short period of time.
The other option I can think of for handling this with the session table would be to use the cookie/path as the key and insert a list of the request times. You could then loop through the list and clear out any requests that are older than the timeout period. This could get very expensive in terms of CPU usage, especially if the request limit is set to a high value.
Anyhow, here is one approach to the scenario:
when RULE_INIT {
Log debug messages to /var/log/ltm? 1=yes, 0=no
set static::get_debug 1
Name of the session cookie that the application sets
set static::session_cookie "workstationid"
Datagroup name containing the paths to limit GET requests to
The requested path is checked to see if it starts with any path string in this class
set static::get_class "get_limit_paths_class"
Timeout to track requests for (in seconds)
set static::timeout 10
Max number of requests to a restricted path per the timeout period
set static::max_requests 1
HTML content to send to clients who exceed the max number of requests
You shouldn't need to escape any characters in between the curly braces (except curly braces).
set static::reject_html [subst -nocommands {Give it a restYou're making too many requests}]
}
when HTTP_REQUEST {
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: [HTTP::method] to [HTTP::host][HTTP::uri]"}
Exit this event in this rule, if request is not a GET
if {not ([HTTP::method] eq "GET")}{
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Exiting for method [HTTP::method]"}
return
}
Exit this event in this rule if request is not to a restricted path
if {[class search $static::get_class starts_with [HTTP::path]]}{
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Exiting for path [HTTP::path]"}
return
}
Exit this event in this rule if request does not include the session cookie
if {[HTTP::cookie $static::session_cookie] eq ""}{
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Exiting for no session cookie"}
return
}
If we're still executing here, it's a GET request to a restricted URI with a session cookie
Check if the cookie / path combo has a request count
set count [session lookup uie "[HTTP::cookie $static::session_cookie][HTTP::path]"]
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: count: $count"}
Check if session table entry exists
if {$count eq ""}{
No session table entry for this cookie/path, so add one
session add uie "[HTTP::cookie $static::session_cookie][HTTP::path]" 1 $static::timeout
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Initialized count for\
[HTTP::cookie $static::session_cookie][HTTP::path]"}
} else {
Check if count is less than max allowed
if {$count < $static::max_requests}{
Increment the session table entry count for this cookie / path
session add uie "[HTTP::cookie $static::session_cookie][HTTP::path]" [incr count] $static::timeout
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Incremented count to $count\
for [HTTP::cookie $static::session_cookie][HTTP::path]"}
} else {
Client is over maximum allowed number of requests to this URI
HTTP::respond 503 content $static::reject_html
if {$static::get_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: $count over limit $static::max_requests\
for [HTTP::cookie $static::session_cookie][HTTP::path]"}
}
}
}
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
