Browse Source

acl-role

3.20
SIPLABS, LLC 11 years ago
parent
commit
85cba65aaa
3 changed files with 256 additions and 0 deletions
  1. +238
    -0
      kamailio/acl-role.cfg
  2. +17
    -0
      kamailio/default.cfg
  3. +1
    -0
      kamailio/local.cfg

+ 238
- 0
kamailio/acl-role.cfg View File

@ -0,0 +1,238 @@
######## DoS prevention module ########
# Default "order" is "Deny,Allow"(DA).
# So if there is no data from DB request will be permitted by default.
#
loadmodule "ipops.so"
modparam("htable", "htable", "acl=>initval=-1;autoexpire=7200")
#!trydef ACL_MESSAGE_DENY "Rejected by ACL"
#!trydef ACL_CODE_DENY "603"
#!trydef ACL_ORDER_ALLOW_DENY "AD"
#!trydef ACL_IP_ADDR_ANY "0.0.0.0/0"
#!trydef IP_REGEX "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}"
## Route for ACL functionality
route[ACL_CHECK] {
if (isflagset(FLAG_IS_REPLY)) {
$var(sip-packet) = $rs;
} else {
$var(sip-packet) = $rm;
}
# FIXUP for BYE method with IPinstead of REALM in From, take REALM fron To header
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci |ACL-realm| Fixup for $var(sip-packet) with IP in from URI: use to-domain");
$var(realm) = $td;
} else {
$var(realm) = $fd;
}
$var(acl-realm-request) = "false";
$var(acl-device-request) = "false";
$var(realm-decision) = $sht(acl=>$var(realm)/$si);
if ($var(realm-decision) == -1) { # we do not have cached decision
$var(acl-realm-request) = "true";
} else if ($var(realm-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
if (not_empty("$fU")) {
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci |ACL-device| Fixup for $var(sip-packet) with IP in from URI: use to-domain");
$var(device) = $fU + "@" + $td;
} else {
$var(device) = $fU + "@" + $fd;
}
$var(device-decision) = $sht(acl=>$var(device)/$si);
if ($var(device-decision) == -1) { # we do not have cached decision
$var(acl-device-request) = "true";
} else if ($var(device-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
}
if ($var(acl-realm-request) == "true" || $var(acl-device-request)) {
if (not_empty("$fU"))
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(device) + "', 'With-Realm': " + $var(acl-realm-request) + "}";
else
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(realm) + "'}";
xlog("L_INFO", "$ci |ACL log| Query: $var(query)");
if (kazoo_query("frontier", "sbc_config", $var(query), "$var(acl-response)")) {
xlog("L_INFO", "$ci |ACL log| Response: $var(acl-response)");
kazoo_json($var(acl-response), "Realm.Order", "$var(acl-realm-order)");
kazoo_json($var(acl-response), "Realm.CIDR", "$var(acl-realm-cidr)");
kazoo_json($var(acl-response), "Realm.CIDR.length", "$var(acl-realm-cidr-len)");
kazoo_json($var(acl-response), "Realm.User-Agent", "$var(acl-realm-ua)");
kazoo_json($var(acl-response), "Device.Order", "$var(acl-device-order)");
kazoo_json($var(acl-response), "Device.CIDR", "$var(acl-device-cidr)");
kazoo_json($var(acl-response), "Device.CIDR.length","$var(acl-device-cidr-len)");
kazoo_json($var(acl-response), "Device.User-Agent", "$var(acl-device-ua)");
} else {
xlog("L_ERROR","$ci |ACL log| DB is unreachable");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
}
route(ACL_CHECK_REALM);
if (not_empty("$fU")) {
route(ACL_CHECK_DEVICE);
}
}
# Check ORDER setting for REALM
route[ACL_CHECK_REALM] {
if (not_empty("$var(acl-realm-order)")) {
if ($var(acl-realm-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_REALM_ALLOW);
} else {
route(ACL_CHECK_REALM_DENY);
}
} else {
xlog("L_INFO","$ci |ACL-realm| undefined Order in response for $var(realm)");
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
}
}
route[ACL_CHECK_REALM_ALLOW] {
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
xlog("L_INFO", "$ci |ACL-realm| checking $var(acl-realm-cidr-len) record(s)");
while($var(i) < $var(acl-realm-cidr-len)) {
kazoo_json($var(acl-realm-cidr), "[$var(i)]", "$var(record)");
xlog("L_INFO", "$ci |ACL-realm| checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
$var(i) = $var(i) + 1;
}
} else {
xlog("L_INFO", "$ci |ACL-realm| undefined CIDR in response for $var(realm)");
}
# Remember in CACHE and DENY
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
route[ACL_CHECK_REALM_DENY] {
$var(size) = $(kzR{kz.json,Realm.CIDR.length});
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
xlog("L_INFO", "$ci |ACL-realm| checking $var(acl-realm-cidr-len) record(s)");
while($var(i) < $var(acl-realm-cidr-len)) {
kazoo_json($var(acl-realm-cidr), "[$var(i)]", "$var(record)");
xlog("L_INFO", "$ci |ACL-realm| checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
$var(i) = $var(i) + 1;
}
} else {
xlog("L_INFO", "$ci |ACL-realm| undefined CIDR in response for $var(realm)");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
# Check ORDER setting for DEVICE
route[ACL_CHECK_DEVICE] {
if (not_empty("$var(acl-device-order)")) {
if ($var(acl-device-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_DEVICE_ALLOW);
} else {
route(ACL_CHECK_DEVICE_DENY);
}
} else {
xlog("L_INFO","$ci |ACL-device| undefined Order in response for $var(device)");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(device)\n");
}
}
route[ACL_CHECK_DEVICE_ALLOW] {
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
xlog("L_INFO", "$ci |ACL-realm| checking $var(acl-device-cidr-len) record(s)");
while($var(i) < $var(acl-device-cidr-len)) {
kazoo_json($var(acl-device-cidr), "[$var(i)]", "$var(record)");
xlog("L_INFO", "$ci |ACL-realm| checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
$var(i) = $var(i) + 1;
}
} else {
xlog("L_INFO", "$ci |ACL-realm| undefined CIDR in response for $var(device)");
}
# Remember in CACHE and DENY
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
route[ACL_CHECK_DEVICE_DENY] {
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
xlog("L_INFO", "$ci |ACL-device| checking $var(acl-device-cidr-len) record(s)");
while($var(i) < $var(acl-device-cidr-len)) {
kazoo_json($var(acl-device-cidr), "[$var(i)]", "$var(record)");
xlog("L_INFO", "$ci |ACL-device| checking if $si is in $var(record)");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
$var(i) = $var(i) + 1;
}
} else {
xlog("L_INFO", "$ci |ACL-device| undefined CIDR in response for $var(device)");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci |ACL| $var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}

+ 17
- 0
kamailio/default.cfg View File

@ -190,6 +190,9 @@ include_file "antiflood-role.cfg"
#!ifdef TRAFFIC-FILTER-ROLE
include_file "traffic-filter-role.cfg"
#!endif
#!ifdef ACL-ROLE
include_file "acl-role.cfg"
#!endif
#!ifdef RATE-LIMITER-ROLE
include_file "rate-limiter-role.cfg"
#!endif
@ -221,6 +224,10 @@ route
route(TRAFFIC_FILTER);
#!endif
#!ifdef ACL-ROLE
route(ACL_CHECK);
#!endif
#!ifdef RATE-LIMITER-ROLE
route(DOS_PREVENTION);
#!endif
@ -502,6 +509,11 @@ onreply_route[EXTERNAL_REPLY]
route(NAT_TEST_AND_CORRECT);
#!endif
#!ifdef ACL-ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE-LIMITER-ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
@ -518,6 +530,11 @@ onreply_route[INTERNAL_REPLY]
route(NAT_WEBSOCKETS_CORRECT);
#!endif
#!ifdef ACL-ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE-LIMITER-ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);


+ 1
- 0
kamailio/local.cfg View File

@ -18,6 +18,7 @@ debug = L_INFO
# # #!trydef TLS-ROLE
# # #!trydef ANTIFLOOD-ROLE
# # #!trydef RATE-LIMITER-ROLE
# # #!trydef ACL-ROLE
################################################################################
## SERVER INFORMATION


Loading…
Cancel
Save