-
Notifications
You must be signed in to change notification settings - Fork 25
/
rate-limit-failed-requests-timeframe.tcl
57 lines (54 loc) · 1.84 KB
/
rate-limit-failed-requests-timeframe.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#
# Copyright 2014, Mischa Peters <mpeters AT a10networks DOT com>, A10 Networks.
# Version 1.0 - 20140312
#
# aFleX script to rate-limit based on requests
# per second and failed responses from the server.
#
# ::MAX_FAILED holds the number of requests that can be
# done before the client is blacklisted.
#
# The ::HOLDTIME_FAILED is the time in seconds.
#
# ::RATE is the amount of requests per timeframe (in seconds)
#
# ::DEBUG can be set to 1, 2 or 3.
#
# Scalability of this aFleX is unknown.
#
when RULE_INIT {
set ::DEBUG 0
set ::MAX_FAILED 10
set ::HOLDTIME_FAILED 20
set ::RATE 2
}
when HTTP_REQUEST {
set IP [IP::client_addr]
if { [table lookup blacklist $IP] != "" } {
reject
if { $::DEBUG > 1 } { log "$IP -> blacklist expires in [table lifetime blacklist -remaining $IP] seconds" }
return
}
if { [table lookup tmp_blacklist $IP] == "" } {
table set tmp_blacklist $IP 1
if { $::DEBUG > 2 } { log "$IP -> request counter created" }
}
}
when HTTP_RESPONSE {
if { ([HTTP::status] == 404) or ([HTTP::status] == 500) or ([HTTP::status] == 503) } {
if { [table lookup tmp_failed $IP] == "" } {
table set tmp_failed $IP $::RATE
if { $::DEBUG > 2 } { log "$IP -> failed response counter created" }
}
set failed_count [table incr tmp_failed $IP]
if { $::DEBUG > 2 } { log "$IP -> $failed_count of $::MAX_FAILED failed requests" }
table lifetime tmp_failed $IP $::RATE
if { $failed_count > $::MAX_FAILED } {
table add blacklist $IP "failed response" indef $::HOLDTIME_FAILED
if { $::DEBUG >= 1 } { log "$IP -> blacklisted for $::HOLDTIME_FAILED seconds" }
table delete tmp_failed $IP
if { $::DEBUG > 2 } { log "$IP -> removed from tmp_failed" }
return
}
}
}