Browse Source

break the anti-flood and traffic filter roles apart

3.17
karl anderson 11 years ago
parent
commit
ae04e71228
5 changed files with 265 additions and 203 deletions
  1. +72
    -0
      kamailio/antiflood-role.cfg
  2. +61
    -87
      kamailio/default.cfg
  3. +1
    -0
      kamailio/local.cfg
  4. +74
    -116
      kamailio/registrar-role.cfg
  5. +57
    -0
      kamailio/traffic-filter-role.cfg

+ 72
- 0
kamailio/antiflood-role.cfg View File

@ -0,0 +1,72 @@
#!trydef ANTIFLOOD_RATE_WINDOW 2
#!trydef ANTIFLOOD_RATE_DENSITY 50
#!trydef ANTIFLOOD_RATE_EXPIRE 4
#!trydef ANTIFLOOD_FAILED_AUTH_WINDOW 120
#!trydef ANTIFLOOD_FAILED_AUTH_DENSITY 3
######## Flood Prevention Hash Tables ########
modparam("htable", "htable", "ipban=>size=8;autoexpire=300;")
modparam("htable", "htable", "failed_auth_hash=>size=8;autoexpire=125;")
######## Flood Prevention Module ########
loadmodule "pike.so"
modparam("pike", "sampling_time_unit", ANTIFLOOD_RATE_WINDOW)
modparam("pike", "reqs_density_per_unit", ANTIFLOOD_RATE_DENSITY)
modparam("pike", "remove_latency", ANTIFLOOD_RATE_EXPIRE)
route[ANTIFLOOD_RATE_LIMIT]
{
xlog("$ci|log|maybe allow $si:$sp");
if (has_totag() || isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
if($sht(ipban=>$si)!=$null) {
# ip is already blocked
xlog("$ci|log|dropping $rm request from $fu with banned IP $si:$sp");
drop();
exit;
}
# use pike to control the rates
if (!pike_check_req()) {
xlog("L_WARN", "$ci|log|pike dropping $rm from $fu due to rate of requests with source $si:$sp");
$sht(ipban=>$si) = 1;
drop();
exit;
}
}
route[ANITFLOOD_AUTH_LIMIT]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return(1);
}
if($sht(failed_auth_hash=>$Au::count) >= ANTIFLOOD_FAILED_AUTH_DENSITY) {
$var(exp) = $Ts - ANTIFLOOD_FAILED_AUTH_WINDOW;
if($sht(failed_auth_hash=>$Au::last) > $var(exp)){
$sht(failed_auth_hash=>$Au::last) = $Ts;
xlog("L_WARN", "$ci|log|ignoring erroneous endpoint registrations from $ct for $Au");
return(-1);
} else {
$sht(failed_auth_hash=>$Au::count) = 0;
}
}
return(1);
}
route[ANITFLOOD_FAILED_AUTH]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
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;
}

+ 61
- 87
kamailio/default.cfg View File

@ -113,10 +113,8 @@ loadmodule "siputils.so"
######## SIP message formatting sanity checks [requires sl] ########
loadmodule "sanity.so"
# sip_version, scheme, req_headers, cseq_method/value
# content_length, parse_uri, digest
modparam("sanity", "default_checks", 3303)
modparam("sanity", "uri_checks", 3)
modparam("sanity", "default_checks", 1511)
modparam("sanity", "uri_checks", 7)
modparam("sanity", "autodrop", 0)
######## Text operations module ########
@ -141,9 +139,6 @@ modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
######## UAC Redirection module ########
loadmodule "uac_redirect.so"
######## DoS prevention mdule ########
loadmodule "pike.so"
####### DB Text module ##########
loadmodule "db_text.so"
modparam("db_text", "db_mode", 1)
@ -188,6 +183,12 @@ include_file "tls-role.cfg"
#!ifdef ACCOUNTING-ROLE
include_file "accounting-role.cfg"
#!endif
#!ifdef ANTIFLOOD-ROLE
include_file "antiflood-role.cfg"
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
include_file "traffic-filter-role.cfg"
#!endif
####### Permissions module ##########
loadmodule "permissions.so"
@ -205,12 +206,14 @@ route
route(SANITY_CHECK);
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
route(CLASSIFY_SOURCE);
#!ifdef ANTIFLOOD-ROLE
route(ANTIFLOOD_RATE_LIMIT);
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
route(DOS_PREVENTION);
route(TRAFFIC_FILTER);
#!endif
#!ifdef WEBSOCKETS-ROLE
@ -223,8 +226,6 @@ route
route(HANDLE_MESSAGE);
route(HANDLE_MOVE_REQUEST);
#!ifdef PRESENCE-ROLE
route(HANDLE_SUBSCRIBE);
route(HANDLE_PUBLISH);
@ -271,17 +272,28 @@ route[SANITY_CHECK]
}
}
route[CLASSIFY_SOURCE]
{
if (isflagset(FLAG_INTERNALLY_SOURCED) || allow_source_address(TRUSTED_ADR_GROUP) || is_myself($si)) {
xlog("L_INFO", "$ci|log|request from trusted IP");
setflag(FLAG_TRUSTED_SOURCE);
}
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
#!endif
}
route[HANDLE_OPTIONS]
{
if (is_method("OPTIONS")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
#!ifdef TRAFFIC-FILTER-ROLE
} else if (!isflagset(FLAG_TRUSTED_SOURCE)
&& $rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_WARN", "$ci|end|dropping OPTIONS request with IP domain");
#!endif
} else {
#!ifdef TRAFFIC-FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
sl_send_reply("200", "Rawr!!");
}
exit;
@ -293,12 +305,11 @@ route[HANDLE_NOTIFY]
if (is_method("NOTIFY")) {
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
#!ifdef TRAFFIC-FILTER-ROLE
} else if (!isflagset(FLAG_TRUSTED_SOURCE)
&& $rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_WARN", "$ci|end|dropping OPTIONS request with IP domain");
#!endif
} else {
#!ifdef TRAFFIC-FILTER-ROLE
route(FILTER_REQUEST_DOMAIN);
#!endif
sl_send_reply("200", "Rawr!!");
}
exit;
@ -317,23 +328,6 @@ route[HANDLE_MESSAGE]
}
}
route[HANDLE_MOVE_REQUEST]
{
if (is_method("INVITE") && $rU == "*6683*") {
$var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host});
if ($sht(associations=>$var(contact_uri)) != $null) {
$sht(associations=>$var(contact_uri)) = $null;
xlog("L_INFO", "$ci|log|removed contact association for $var(contact_uri)
with media server $sht(associations=>$var(contact_uri))");
}
send_reply("503", "Removed association");
exit;
}
}
route[HANDLE_IN_DIALOG_REQUESTS]
{
if (has_totag()) {
@ -341,11 +335,12 @@ route[HANDLE_IN_DIALOG_REQUESTS]
record_route();
}
if (loose_route()) {
#!ifdef ACCOUNTING-ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!ifdef ACCOUNTING-ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
#!ifdef WEBSOCKETS-ROLE
@ -395,7 +390,7 @@ route[PREPARE_INITIAL_REQUESTS]
if (t_check_trans()) {
route(RELAY);
} else {
sl_send_reply("481", "Call Leg/Transaction Does Not Exist");
sl_send_reply("481", "Call leg/transaction does not exist");
}
exit();
} else if (is_method("ACK")) {
@ -405,8 +400,21 @@ route[PREPARE_INITIAL_REQUESTS]
exit();
}
# handle re-transmissions
t_check_trans();
if (is_method("UPDATE")) {
xlog("L_WARN", "$ci|end|update outside dialog not allowed");
send_reply("403", "Dialog does not exist");
break;
}
if (is_method("BYE|PRACK")) {
xlog("L_WARN", "$ci|end|originating subsequent requests outside dialog not allowed");
send_reply("403", "Dialog does not exist");
break;
}
if (loose_route()) {
xlog("L_WARN", "$ci|end|denying initial request with route-set");
sl_send_reply("403", "No pre-loaded routes");
@ -432,10 +440,10 @@ route[RELAY]
route[INTERNAL_TO_EXTERNAL_RELAY]
{
#!ifdef ACCOUNTING-ROLE
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
remove_hf_re("X-.*");
@ -450,10 +458,10 @@ route[INTERNAL_TO_EXTERNAL_RELAY]
route[EXTERNAL_TO_INTERNAL_RELAY]
{
#!ifdef ACCOUNTING-ROLE
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
@ -473,39 +481,6 @@ route[EXTERNAL_TO_INTERNAL_RELAY]
t_relay();
}
route[DOS_PREVENTION]
{
# allow request from internal network or from whitelist
if (isflagset(FLAG_INTERNALLY_SOURCED) || allow_source_address(TRUSTED_ADR_GROUP) || is_myself($si)) {
xlog("L_INFO", "$ci|log|request from trusted IP");
setflag(FLAG_TRUSTED_SOURCE);
return;
}
# drop requests with no To domain or IP To domain (friendly-scanner)
if (is_method("REGISTER|SUBSCRIBE|OPTIONS") &&
($td == $null || $td=~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}")) {
xlog("L_WARN", "$ci|log|dropping request with IP domain in To header");
exit;
}
# drop Invite with IP auth realm
if (is_method("INVITE") && is_present_hf("Proxy-Authorization") &&
$ar =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}" ) {
xlog("L_WARN", "$ci|log|dropping request with IP domain in Proxy-Authorization header");
exit;
}
# use pike check for the others
if (!pike_check_req()) {
# If it is a new flood, emit a log
if($rc == -2) {
xlog("L_WARN", "$ci|log|dropping due to rate of requests from IP");
}
exit;
}
}
onreply_route[EXTERNAL_REPLY]
{
xlog("L_INFO", "$ci|log|external reply $T_reply_code");
@ -559,7 +534,6 @@ failure_route[INTERNAL_FAULT]
# cancelled then we are complete
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled");
exit;
}


+ 1
- 0
kamailio/local.cfg View File

@ -11,6 +11,7 @@ debug = L_INFO
#!trydef NAT-TRAVERSAL-ROLE
#!trydef REGISTRAR-ROLE
#!trydef PRESENCE-ROLE
#!trydef ANTIFLOOD-ROLE
## Disabled Roles - remove all but the last '#' to enable
# # #!trydef TRAFFIC-FILTER-ROLE


+ 74
- 116
kamailio/registrar-role.cfg View File

@ -1,6 +1,10 @@
#!trydef REGISTRAR_NAT_PING_INTERVAL 30
#!trydef REGISTRAR_NAT_PING_WORKERS 5
#!trydef REGISTRAR_MIN_EXPIRES 300
#!trydef REGISTRAR_MAX_EXPIRES 3600
######## 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;")
modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200;")
####### Authentication Interface module ##########
loadmodule "auth.so"
@ -16,17 +20,17 @@ modparam("usrloc", "nat_bflag", FLB_NATB)
#!ifdef NAT-TRAVERSAL-ROLE
#!trydef NATHELPER-LOADED
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "natping_interval", REGISTRAR_NAT_PING_INTERVAL)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "natping_processes", 5)
modparam("nathelper", "natping_processes", REGISTRAR_NAT_PING_WORKERS)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
#!endif
####### SIP Registrar implementation module ##########
loadmodule "registrar.so"
modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)")
modparam("registrar", "min_expires", 300)
modparam("registrar", "max_expires", 3600)
modparam("registrar", "min_expires", REGISTRAR_MIN_EXPIRES)
modparam("registrar", "max_expires", REGISTRAR_MAX_EXPIRES)
####### Registrar Logic ########
@ -34,10 +38,6 @@ route[HANDLE_REGISTER]
{
if (is_method("REGISTER")) {
#!ifdef TRAFFIC-FILTER-ROLE
route(DOMAIN_FORMAT_CHECK);
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
if (nat_uac_test("3")) {
xlog("L_INFO", "$ci|log|correcting NATed contact in registration");
@ -53,134 +53,92 @@ route[HANDLE_REGISTER]
#!endif
if (is_present_hf("Authorization")) {
#!ifdef TRAFFIC-FILTER-ROLE
if (!route(PREVENT_BRUTEFORCE)) {
auth_challenge("$fd", "0");
exit;
}
#!endif
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");
} else {
## RABBITMQ - Credentials fetch
$var(amqp_payload_request) = "{'Event-Category' : 'directory' , 'Event-Name' : 'authn_req', 'Method' : 'REGISTER', 'Auth-Realm' : '" + $fd + "', 'Auth-User' : '" + $fU + "', 'From' : '" + $fu + "', 'To' : '" + $tu +"' }";
$var(amqp_routing_key) = "authn.req." + $(fd{kz.encode});
if(kazoo_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request))) {
$var(password) = $(kzR{kz.json,Auth-Password});
if($var(password) != $null) {
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
#!ifdef TRAFFIC-FILTER-ROLE
route(FAILED_AUTH_COUNT);
#!endif
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|failed registration attempt from $si:$sp for $Au");
exit;
} else {
xlog("L_DBG", "$ci|log|caching SIP credentials for $Au");
$sht(auth_cache=>$Au) = $var(password);
}
} else {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|log|error getting password from kazoo response");
exit;
}
} else {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|log|error query kazoo for credentials");
exit;
}
}
route(ATTEMPT_AUTHORIZATION);
} else {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|issued new auth challenge to registration attempt from $Au $si:$sp");
xlog("L_INFO", "$ci|end|issued auth challenge to new registration for $Au $si:$sp");
exit;
}
}
}
# user authenticated - remove auth header
consume_credentials();
save("location");
$var(expires) = @contact.expires;
if($var(expires) == $null) {
$var(expires) = $hdr(Expires);
}
if($var(expires) == $null) {
$var(expires) = 190;
}
$var(fs_path) = "%3C" + $rz + "%3A" + $Ri + "%3A" + $Rp + "%3Btransport=" + $proto + "%3Blr%3Breceived=" + $si+":"+$sp+"%3E";
$var(fs_contact) = "<" + $(ct{tobody.uri}) + ";fs_path=" + $var(fs_path) + ">";
if($(ct{tobody.params}) != $null) {
$var(fs_contact) = $var(fs_contact) + ";" + $(ct{tobody.params});
route[ATTEMPT_AUTHORIZATION]
{
#!ifdef ANTIFLOOD-ROLE
if (!route(ANITFLOOD_AUTH_LIMIT)) {
xlog("L_WARN", "$ci|log|dropping erroneous endpoint registration for $Au $si:$sp");
drop();
exit;
}
#!endif
if ($sht(auth_cache=>$Au) != $null) {
xlog("L_INFO", "$ci|log|authenticating $Au via cached SIP creds");
$var(password) = $sht(auth_cache=>$Au);
} else {
$var(amqp_payload_request) = "{'Event-Category' : 'directory' , 'Event-Name' : 'authn_req', 'Method' : 'REGISTER', 'Auth-Realm' : '" + $fd + "', 'Auth-User' : '" + $fU + "', 'From' : '" + $fu + "', 'To' : '" + $tu +"' }";
$var(amqp_routing_key) = "authn.req." + $(fd{kz.encode});
if(kazoo_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request))) {
$var(password) = $(kzR{kz.json,Auth-Password});
xlog("L_INFO", "$ci|log|authenticating $Au via Kazoo query response");
} else {
xlog("L_INFO", "$ci|log|failed to query Kazoo for authentication credentials for $Au $si:$sp");
}
}
xlog("L_INFO", "$ci|end|successful registration with contact $var(fs_contact)");
$var(register_contants) = " 'Presence-Hosts' : 'n/a', 'Profile-Name' : 'sipinterface_1', 'Status' : 'Registered', 'Event-Timestamp' : '" + $TS + "'";
if($var(expires) != $null) {
$var(register_contants) = $var(register_contants) + ", 'Expires' : " + $var(expires);
}
$var(amqp_payload_request) = "{'Event-Category' : 'directory', 'Event-Name' : 'reg_success', 'Contact' : '" + $var(fs_contact) + "', 'Call-ID' : '" + $ci + "', 'Realm' : '" + $fd +"', 'Username' : '" + $fU + "', 'From-User' : '" + $fU + "', 'From-Host' : '" + $fd + "', 'To-User' : '" + $tU +"', 'To-Host' : '" + $td + "', 'User-Agent' : '" + $ua +"' ," + $var(register_contants)+ " }";
if($var(password) == $null) {
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp");
exit;
}
$var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $fU;
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
#!ifdef ANTIFLOOD-ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
kazoo_publish("callmgr", $var(amqp_routing_key), $var(amqp_payload_request));
auth_challenge("$fd", "0");
xlog("L_INFO", "$ci|end|issued auth challenge to failed registration attempt for $Au $si:$sp");
exit;
}
}
# AUTH: check to see if user if present in failed_auth_hash
route[PREVENT_BRUTEFORCE]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return(1);
if ($kzR != $null) {
xlog("L_DBG", "$ci|log|caching SIP credentials for $Au");
$sht(auth_cache=>$Au) = $avp(password);
}
if($sht(failed_auth_hash=>$Au::count) >= 2) {
$var(exp) = $Ts - 120;
if($sht(failed_auth_hash=>$Au::last) > $var(exp)){
xlog("L_WARN", "$ci|log|possible password brute force, from $ct on user $Au");
return(-1);
} else {
$sht(failed_auth_hash=>$Au::count) = 0;
}
}
return(1);
}
# user authenticated - remove auth header
consume_credentials();
save("location");
#AUTH: add to failed_auth_hash in case of authentication password error
route[FAILED_AUTH_COUNT]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
$var(expires) = @contact.expires;
if($var(expires) == $null) {
$var(expires) = $hdr(Expires);
}
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;
if($var(expires) == $null) {
$var(expires) = 190;
}
}
route[DOMAIN_FORMAT_CHECK]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
$var(fs_path) = "%3C" + $rz + "%3A" + $Ri + "%3A" + $Rp + "%3Btransport=" + $proto + "%3Blr%3Breceived=" + $si+":"+$sp+"%3E";
$var(fs_contact) = "<" + $(ct{tobody.uri}) + ";fs_path=" + $var(fs_path) + ">";
if($(ct{tobody.params}) != $null) {
$var(fs_contact) = $var(fs_contact) + ";" + $(ct{tobody.params});
}
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})" ) {
xlog("L_WARN", "$ci|end|denying request with IP domain in From or To header");
send_reply("403", "Forbidden");
exit;
xlog("L_INFO", "$ci|end|successful registration with contact $var(fs_contact)");
$var(register_contants) = " 'Presence-Hosts' : 'n/a', 'Profile-Name' : 'sipinterface_1', 'Status' : 'Registered', 'Event-Timestamp' : '" + $TS + "'";
if($var(expires) != $null) {
$var(register_contants) = $var(register_contants) + ", 'Expires' : " + $var(expires);
}
$var(amqp_payload_request) = "{'Event-Category' : 'directory', 'Event-Name' : 'reg_success', 'Contact' : '" + $var(fs_contact) + "', 'Call-ID' : '" + $ci + "', 'Realm' : '" + $fd +"', 'Username' : '" + $fU + "', 'From-User' : '" + $fU + "', 'From-Host' : '" + $fd + "', 'To-User' : '" + $tU +"', 'To-Host' : '" + $td + "', 'User-Agent' : '" + $ua +"' ," + $var(register_contants)+ " }";
$var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $fU;
kazoo_publish("callmgr", $var(amqp_routing_key), $var(amqp_payload_request));
xlog("L_INFO", "$ci|end|successful registration with contact $ct");
exit;
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 57
- 0
kamailio/traffic-filter-role.cfg View File

@ -0,0 +1,57 @@
route[TRAFFIC_FILTER]
{
# allow request from internal network or from whitelist
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
# drop requests with no To domain or IP To domain (friendly-scanner)
if (is_method("REGISTER|SUBSCRIBE") {
route(FILTER_TO_DOMAIN);
route(FILTER_FROM_DOMAIN);
}
# drop Invite with IP auth realm
if (is_method("INVITE") {
route(FILTER_REQUEST_DOMAIN);
route(FILTER_AUTHORIZATION_DOMAIN);
}
}
route[FILTER_REQUEST_DOMAIN]
{
if ($rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_WARN", "$ci|end|dropping $rm request with IP domain");
drop();
exit();
}
}
route[FILTER_AUTHORIZATION_DOMAIN]
{
if (is_present_hf("Proxy-Authorization") &&
$ar =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}" ) {
xlog("L_WARN", "$ci|log|dropping request with IP domain in Proxy-Authorization header");
drop();
exit;
}
}
route[FILTER_TO_DOMAIN]
{
if ($fd =~ "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})") {
xlog("L_WARN", "$ci|end|dropping request with IP domain in From header");
drop();
exit;
}
}
route[FILTER_FROM_DOMAIN]
{
if ($td =~ "([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})") {
xlog("L_WARN", "$ci|end|dropping request with IP domain in To header");
drop();
exit;
}
}

Loading…
Cancel
Save