|
|
|
@ -4,9 +4,17 @@ |
|
|
|
#!trydef ANTIFLOOD_RATE_EXPIRE 4 |
|
|
|
#!trydef ANTIFLOOD_FAILED_AUTH_WINDOW 300 |
|
|
|
#!trydef ANTIFLOOD_FAILED_AUTH_DENSITY 4 |
|
|
|
#!trydef ANTIFLOOD_FAILED_AUTH_USE_PORT 1 |
|
|
|
#!trydef ANTIFLOOD_FAILED_AUTH_ACTION 2 |
|
|
|
#!trydef ANTIFLOOD_RATE_LIMIT_ENABLED 1 |
|
|
|
#!trydef ANTIFLOOD_AUTH_LIMIT_ENABLED 1 |
|
|
|
#!trydef ANTIFLOOD_RATE_DROP 1 |
|
|
|
#!trydef ANTIFLOOD_CACHE_PERIOD 300 |
|
|
|
|
|
|
|
#!substdef "!ANTIFLOOD_SUBST_CACHE_PERIOD!$def(ANTIFLOOD_CACHE_PERIOD)!g" |
|
|
|
|
|
|
|
######## Flood Prevention Hash Tables ######## |
|
|
|
modparam("htable", "htable", "antiflood=>size=16;autoexpire=ANTIFLOOD_CACHE_PERIOD;initval=0") |
|
|
|
modparam("htable", "htable", "antiflood=>size=16;autoexpire=ANTIFLOOD_SUBST_CACHE_PERIOD;initval=0") |
|
|
|
|
|
|
|
######## Flood Prevention Module ######## |
|
|
|
loadmodule "pike.so" |
|
|
|
@ -14,6 +22,21 @@ modparam("pike", "sampling_time_unit", ANTIFLOOD_RATE_WINDOW) |
|
|
|
modparam("pike", "reqs_density_per_unit", ANTIFLOOD_RATE_DENSITY) |
|
|
|
modparam("pike", "remove_latency", ANTIFLOOD_RATE_EXPIRE) |
|
|
|
|
|
|
|
kazoo.antiflood_failed_auth_use_port = ANTIFLOOD_FAILED_AUTH_USE_PORT descr "should we keep track of ip and port for auth failures" |
|
|
|
kazoo.antiflood_failed_auth_action = ANTIFLOOD_FAILED_AUTH_ACTION descr "0 - log, 1 - drop, 2 - reply with 403" |
|
|
|
kazoo.antiflood_rate_limit_enabled = ANTIFLOOD_RATE_LIMIT_ENABLED descr "antiflood rate limit enabled" |
|
|
|
kazoo.antiflood_auth_limit_enabled = ANTIFLOOD_AUTH_LIMIT_ENABLED descr "antiflood auth limit enabled" |
|
|
|
kazoo.antiflood_rate_drop = ANTIFLOOD_RATE_DROP descr "should we drop on rate limit" |
|
|
|
|
|
|
|
route[ANTIFLOOD_LIMIT] |
|
|
|
{ |
|
|
|
if($sel(cfg_get.kazoo.antiflood_rate_limit_enabled) == 1) { |
|
|
|
route(ANTIFLOOD_RATE_LIMIT); |
|
|
|
} |
|
|
|
if($sel(cfg_get.kazoo.antiflood_auth_limit_enabled) == 1) { |
|
|
|
route(ANTIFLOOD_AUTH_LIMIT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
route[ANTIFLOOD_RATE_LIMIT] |
|
|
|
{ |
|
|
|
@ -25,13 +48,16 @@ route[ANTIFLOOD_RATE_LIMIT] |
|
|
|
|
|
|
|
# use pike to control the rates |
|
|
|
if (!pike_check_req()) { |
|
|
|
xlog("L_WARN", "$ci|end|dropping request from $fu due to rate of requests with source $si:$sp\n"); |
|
|
|
drop(); |
|
|
|
exit; |
|
|
|
if($sel(cfg_get.kazoo.antiflood_rate_drop) == 1) { |
|
|
|
xlog("L_WARN", "$ci|end|dropping request from $fu due to rate of requests with source $si:$sp\n"); |
|
|
|
drop(); |
|
|
|
} else { |
|
|
|
xlog("L_WARN", "$ci|end|request from $fu exceeded rate of requests with source $si:$sp\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
route[ANITFLOOD_AUTH_LIMIT] |
|
|
|
route[ANTIFLOOD_AUTH_LIMIT] |
|
|
|
{ |
|
|
|
if (has_totag() |
|
|
|
|| isflagset(FLAG_TRUSTED_SOURCE) |
|
|
|
@ -39,21 +65,38 @@ route[ANITFLOOD_AUTH_LIMIT] |
|
|
|
return(1); |
|
|
|
} |
|
|
|
|
|
|
|
if ($Au != $null && |
|
|
|
$sht(antiflood=>$Au::$si::count) >= ANTIFLOOD_FAILED_AUTH_DENSITY |
|
|
|
$var(auth_key) = ""; |
|
|
|
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) { |
|
|
|
$var(auth_key) = $_s("$Au::$si::$sp"); |
|
|
|
} else { |
|
|
|
$var(auth_key) = $_s("$Au::$si"); |
|
|
|
} |
|
|
|
if ($Au != $null && |
|
|
|
$sht(antiflood=>$var(auth_key)::count) >= ANTIFLOOD_FAILED_AUTH_DENSITY |
|
|
|
) { |
|
|
|
xlog("L_NOTICE", "$ci|end|request at authorization failure limit for $Au $si:$sp\n"); |
|
|
|
$shtex(antiflood=>$Au::$si::count) = ANTIFLOOD_FAILED_AUTH_WINDOW; |
|
|
|
$sht(antiflood=>$Au::$si::last) = $Ts; |
|
|
|
append_to_reply("Retry-After: 3600\r\n"); |
|
|
|
send_reply("500", "Retry Later"); |
|
|
|
exit; |
|
|
|
$shtex(antiflood=>$var(auth_key)::count) = ANTIFLOOD_FAILED_AUTH_WINDOW; |
|
|
|
$sht(antiflood=>$var(auth_key)::last) = $Ts; |
|
|
|
if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 1) { |
|
|
|
xlog("L_WARNING", "$ci|end|dropping request authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n"); |
|
|
|
drop(); |
|
|
|
} else if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 2) { |
|
|
|
xlog("L_NOTICE", "$ci|end|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n"); |
|
|
|
append_to_reply("Retry-After: 3600\r\n"); |
|
|
|
send_reply("403", "Forbidden"); |
|
|
|
exit; |
|
|
|
} else { |
|
|
|
xlog("L_NOTICE", "$ci|log|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
route[ANTIFLOOD_SUCCESSFUL_AUTH] |
|
|
|
{ |
|
|
|
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::.*"); |
|
|
|
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) { |
|
|
|
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::$sp::.*"); |
|
|
|
} else { |
|
|
|
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::.*"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
route[ANTIFLOOD_RESET_AUTH] |
|
|
|
@ -68,20 +111,27 @@ route[ANITFLOOD_FAILED_AUTH] |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
$var(count) = $shtinc(antiflood=>$Au::$si::count); |
|
|
|
$sht(antiflood=>$Au::$si::last) = $Ts; |
|
|
|
$var(auth_key) = ""; |
|
|
|
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) { |
|
|
|
$var(auth_key) = $_s("$Au::$si::$sp"); |
|
|
|
} else { |
|
|
|
$var(auth_key) = $_s("$Au::$si"); |
|
|
|
} |
|
|
|
|
|
|
|
$var(count) = $shtinc(antiflood=>$var(auth_key)::count); |
|
|
|
$sht(antiflood=>$var(auth_key)::last) = $Ts; |
|
|
|
|
|
|
|
xlog("L_INFO", "$ci|log|$var(count) errounous authorization response for $Au $si:$sp\n"); |
|
|
|
|
|
|
|
if ($var(count) >= ANTIFLOOD_FAILED_AUTH_DENSITY) { |
|
|
|
if ($var(count) >= ANTIFLOOD_FAILED_AUTH_DENSITY) { |
|
|
|
$var(exp) = $Ts - ANTIFLOOD_FAILED_AUTH_WINDOW; |
|
|
|
if($sht(antiflood=>$Au::$si::last) > $var(exp)){ |
|
|
|
xlog("L_NOTICE", "$ci|end|request at authorization failure limit for $Au $si:$sp\n"); |
|
|
|
if($sht(antiflood=>$var(auth_key)::last) > $var(exp)) { |
|
|
|
xlog("L_NOTICE", "$ci|end|request at authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n"); |
|
|
|
append_to_reply("Retry-After: 3600\r\n"); |
|
|
|
send_reply("500", "Retry Later"); |
|
|
|
send_reply("403", "Forbidden"); |
|
|
|
exit; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
event_route[htable:expired:antiflood] |
|
|
|
|