Hi Furkansed,
you may use the iRule below as a starting point. It checks for Err500 codes and tracks the total number a given Client IP has already triggered a err500 condition via LTMs session table. If the client exceeds its configured tresholds, the iRule will redirect him to a error page URL...
when RULE_INIT {
# Global Configuration options
set static::err500_threshold 2 ;# Number of err500 responses to activate the filtering
set static::err500_timeout 60 ;# Timeout in seconds of an active filtering. If another err500 happens during the timeout period, it will restart the timeout window and keeps the filtering active.
set static::err500_lifetime 300 ;# Maximum lifetime in seconds of an active filtering. After the lifetime is elapsed, the filtering will be removed. (set to "indef" if filtering timers should be base on timeouts only.)
set static::err500_error_page "/" ;# Redirect URL for err500 responses exceeeding the limits
}
when HTTP_REQUEST {
# Storing HTTP host and path for logging during HTTP response
set temp(orig_path) [HTTP::path]
set temp(orig_host) [HTTP::host]
}
when HTTP_RESPONSE {
# Check if err5xx is responded...
if { [HTTP::status] >= 500 } then {
# Error 500 detected. Checking the filtering state of the requesting Client IP Adress.
if { [set temp(counter_value) [table incr -mustexist "err500_[IP::client_addr]" 1]] > $static::err500_threshold } then {
# Err500 treshold has been massively exceeded. Silently redirecting the response to the error page.
HTTP::respond 302 \
noserver \
"Location" $static::err500_error_page
} elseif { $temp(counter_value) == $static::err500_threshold } then {
# Err500 treshold has been just exceeded. Logging the request and redirecting the response to the error page.
log local0.debug "IP=\"[IP::client_addr]\" just saw an ErrorCode=\"[HTTP::status]\" on Host=\"$temp(orig_host)\" and Path=\"$temp(orig_path)\". Err500 response counter for the client has just been exceeded. Redirecting to the error page."
HTTP::respond 302 \
noserver \
"Location" $static::err500_error_page
} elseif { $temp(counter_value) eq "" } then {
# Client IP generate Err500 for the first time. Logging the request, initializing a new counter for the client and allowing the response to pass.
log local0.debug "IP=\"[IP::client_addr]\" just saw an ErrorCode=\"[HTTP::status]\" on Host=\"$temp(orig_host)\" and Path=\"$temp(orig_path)\". Initializing a new err500 response counter for the client and allowing the response to pass."
table set "err500_[IP::client_addr]" 1 $static::err500_timeout $static::err500_lifetime
} else {
# Client IP subsequently generate Err500. Logging the request, increasing counter for the client and allowing the response to pass.
log local0.debug "IP=\"[IP::client_addr]\" just saw an ErrorCode=\"[HTTP::status]\" on Host=\"$temp(orig_host)\" and Path=\"$temp(orig_path)\". Increasing the err500 response counter for the client and allowing the response to pass."
}
}
}
Cheers, Kai