From f48ad99a3fdb172e322b7535121560e49310e22d Mon Sep 17 00:00:00 2001 From: Anca Vamanu Date: Wed, 4 Sep 2013 00:32:16 +0300 Subject: [PATCH] registrar-role.cfg: DOS prevention - reject Register to IP domain - check for brute force attack - allow only two consecutive attempts to authenticate. If both failed block the account for 2 minutes. --- kamailio/registrar-role.cfg | 51 ++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/kamailio/registrar-role.cfg b/kamailio/registrar-role.cfg index ef267ba..24d0697 100644 --- a/kamailio/registrar-role.cfg +++ b/kamailio/registrar-role.cfg @@ -2,6 +2,7 @@ ######## Generic Hash Table container in shared memory ######## modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200") +modparam("htable", "htable", "failed_auth_hash=>size=14;autoexpire=180;") ####### Authentication Interface module ########## loadmodule "auth.so" @@ -37,6 +38,9 @@ modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)") route[HANDLE_REGISTER] { if (is_method("REGISTER")) { + + route(DOMAIN_FORMAT_CHECK); + #!ifdef NAT-TRAVERSAL-ROLE if (nat_uac_test("3")) { xlog("L_INFO", "$ci|log|Correcting NATed contact in registration\n"); @@ -50,11 +54,18 @@ route[HANDLE_REGISTER] #!endif if (is_present_hf("Authorization")) { + + if (!route(PREVENT_BRUTEFORCE)) { + auth_challenge("$fd", "0"); + exit; + } + if ($sht(auth_cache=>$Au) != $null && pv_auth_check("$fd", "$sht(auth_cache=>$Au)", "0", "0")) { xlog("L_INFO", "$ci|log|Authenticated $Au via cached SIP creds\n"); } else { ## RABBITMQ - Credentials fetch if (!auth_check("$fd", "subscriber", "1")) { + route(FAILED_AUTH_COUNT); auth_challenge("$fd", "0"); xlog("L_INFO", "$ci|log|Issued new auth challenge to failed registration attempt\n"); exit; @@ -77,4 +88,42 @@ route[HANDLE_REGISTER] } } -## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab +# AUTH: check to see if user if present in failed_auth_hash +route[PREVENT_BRUTEFORCE] +{ + if($sht(failed_auth_hash=>$Au::count) >= 2) { + $var(exp) = $Ts - 120; + if($sht(failed_auth_hash=>$Au::last) > $var(exp)){ + xlog("L_ERR", "Possible password brute force, from $ct on user $Au"); + return(-1); + } else { + $sht(failed_auth_hash=>$Au::count) = 0; + } + } + return(1); +} + + +#AUTH: add to failed_auth_hash in case of authentication password error +route[FAILED_AUTH_COUNT] +{ + if ($rc == -2) { + if($sht(failed_auth_hash=>$Au::count) == $null) { + $sht(failed_auth_hash=>$Au::count) = 0; + } + $sht(failed_auth_hash=>$Au::count) = $sht(failed_auth_hash=>$Au::count) + 1; + $sht(failed_auth_hash=>$Au::last) = $Ts; + } +} + +route[DOMAIN_FORMAT_CHECK] +{ + if ($rd =~ "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})" || + $td =~ "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3}" ) { + send_reply("403", "Forbidden"); + exit; + } + +} + +# vim:tabstop=4 softtabstop=4 shiftwidth=4 expandtab