From a41c15b603c77831985e13ecdd57e53175de4f57 Mon Sep 17 00:00:00 2001 From: lazedo Date: Wed, 27 Feb 2019 18:19:13 +0000 Subject: [PATCH] antiflood macros & auth by port --- kamailio/antiflood-role.cfg | 92 ++++++++++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/kamailio/antiflood-role.cfg b/kamailio/antiflood-role.cfg index 2f0345f..edb0455 100644 --- a/kamailio/antiflood-role.cfg +++ b/kamailio/antiflood-role.cfg @@ -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]