Compare commits

...

19 Commits
master ... 3.17

Author SHA1 Message Date
  lazedo ab8a9a72fb 3.18 allow null values on presentity sender field 11 years ago
  lazedo 624501a077 blame the mac or or sublimetext 11 years ago
  Luis Azedo fa6697f714 extra ^X- corrections 11 years ago
  karl anderson e3d650af44 the regex is case-insensitive and erronously matching the ma"x-"forward header 11 years ago
  karl anderson 62ff24a90a disable the new role by default 11 years ago
  karl anderson ca4b0441d8 make the auth limit more generic and fix the missing routing key 11 years ago
  karl anderson 4ca65a7a7d update port value 11 years ago
  karl anderson b11593cfa4 update registrar fs_path to support tls 11 years ago
  karl anderson a28cf52491 remove ipban hash and fix type (var =/= avp) 11 years ago
  karl anderson 5685a86a3a remove debug line 11 years ago
  karl anderson ae04e71228 break the anti-flood and traffic filter roles apart 11 years ago
  karl anderson 93efa2c29e 3.17: encode the call-id and restore the accepted ignore-display-updates patch 11 years ago
  karl anderson 3737f1ed1d KAZOO-2902: remove the deprecated register_fs_path parameter 11 years ago
  lazedo 232e6c447b KAZOO-2902 subscriptions db_mode = 1 11 years ago
  lazedo 7434556201 KAZOO-2902 missing tables and defition in version 11 years ago
  karl anderson 82d7d87979 3.17: remove the erroneous comment on MY_AMQP_URL_TERTIARY and add missing dbtext files 11 years ago
  karl anderson 72c3a41dac KAZOO-2780: backport 11 years ago
  karl anderson 45407a6536 manual merge and backport of pull #20 adding an accounting role 11 years ago
  karl anderson 79de6fe59a 3.17: continue collecting changes to avoid creating .rpmnew files 11 years ago
17 changed files with 422 additions and 273 deletions
Split View
  1. +6
    -34
      config.ini
  2. +1
    -1
      freeswitch/freeswitch.xml
  3. +23
    -24
      haproxy/haproxy.cfg
  4. +22
    -0
      kamailio/accounting-role.cfg
  5. +81
    -0
      kamailio/antiflood-role.cfg
  6. +1
    -0
      kamailio/dbtext/active_watchers
  7. +1
    -0
      kamailio/dbtext/location
  8. +1
    -0
      kamailio/dbtext/presentity
  9. +4
    -0
      kamailio/dbtext/version
  10. +1
    -0
      kamailio/dbtext/watchers
  11. +112
    -82
      kamailio/default.cfg
  12. +4
    -5
      kamailio/dispatcher-role.cfg
  13. +1
    -0
      kamailio/local.cfg
  14. +21
    -10
      kamailio/presence-role.cfg
  15. +84
    -115
      kamailio/registrar-role.cfg
  16. +57
    -0
      kamailio/traffic-filter-role.cfg
  17. +2
    -2
      rabbitmq/rabbitmq.config

+ 6
- 34
config.ini View File

@ -1,53 +1,25 @@
; section are between [] = [section]
; key = value
; to comment add ";" in front of the line
;
;
; NOTE: You must add all your FreeSWITCH servers to the trusted ACLs
; if you are using zones!
;
[amqp]
uri = "amqp://guest:guest@127.0.0.1:5672"
[bigcouch]
compact_automatically = true
cookie = change_me
ip = "127.0.0.1"
port = 15984
;username = "kazoo"
;password = "supermegaexcellenttelephonyplatform"
; username = "kazoo"
; password = "supermegaexcellenttelephonyplatform"
admin_port = 15986
; Define your AMQPs and zones here
[zone]
name = zone_1
amqp_uri = "amqp://guest:guest@127.0.0.1:5672"
;[zone]
;name = zone_2
;amqp_uri = "amqp://guest:guest@127.0.0.2:5672"
; Define your whistles here
[whistle_apps]
;host = apps001.2600hz.com
zone = zone_1
cookie = change_me
;[whistle_apps]
;host = apps002.2600hz.com
;zone = zone_2
;cookie = change_me
; Define your ecallmgr's here
[ecallmgr]
;host = apps001.2600hz.com
zone = zone_1
cookie = change_me
;[ecallmgr]
;host = apps002.2600hz.com
;zone = zone_2
;cookie = change_me
[log]
syslog = debug
syslog = info
console = notice
file = error

+ 1
- 1
freeswitch/freeswitch.xml View File

@ -31,7 +31,7 @@
<X-PRE-PROCESS cmd="set" data="sit=%(274,0,913.8);%(274,0,1370.6);%(380,0,1776.7)"/>
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://default"/>
<X-PRE-PROCESS cmd="set" data="ignore_display_updates=true"/>
<X-PRE-PROCESS cmd="set" data="ignore_display_updates=false"/>
<X-PRE-PROCESS cmd="set" data="recordings_dir=/tmp/"/>
<X-PRE-PROCESS cmd="set" data="send_silence_when_idle=400"/>


+ 23
- 24
haproxy/haproxy.cfg View File

@ -1,40 +1,39 @@
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
user haproxy
group haproxy
stats socket /tmp/haproxy.sock mode 777
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
user haproxy
group haproxy
stats socket /tmp/haproxy.sock mode 777
defaults
log global
mode http
option httplog
option dontlognull
option redispatch
option httpchk GET /
option allbackups
option http-server-close
maxconn 2000
retries 3
timeout connect 6000ms
timeout client 120000ms
timeout server 120000ms
log global
mode http
option httplog
option dontlognull
option redispatch
option httpchk GET /
option allbackups
maxconn 2000
retries 3
timeout connect 6000ms
timeout client 12000ms
timeout server 12000ms
listen bigcouch-data 127.0.0.1:15984
balance roundrobin
balance roundrobin
server db1.zone1.mydomain.com 127.0.0.1:5984 check
server db2.zone1.mydomain.com 127.0.0.2:5984 check
server db3.zone2.mydomain.com 127.0.0.3:5984 check backup
server db4.zone2.mydomain.com 127.0.0.4:5984 check backup
listen bigcouch-mgr 127.0.0.1:15986
balance roundrobin
balance roundrobin
server db1.zone1.mydomain.com 127.0.0.1:5986 check
server db2.zone1.mydomain.com 127.0.0.2:5986 check
server db3.zone2.mydomain.com 127.0.0.3:5986 check backup
server db4.zone2.mydomain.com 127.0.0.4:5986 check backup
listen haproxy-stats 127.0.0.1:22002
mode http
stats uri /
mode http
stats uri /

+ 22
- 0
kamailio/accounting-role.cfg View File

@ -0,0 +1,22 @@
####### Flags #######
flags
FLAG_ACC: 7,
FLAG_ACCMISSED: 8,
FLAG_ACCFAILED: 9;
######## Accounting module ########
loadmodule "acc.so"
######## Accounting params ########
modparam("acc", "early_media", 0)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 1)
modparam("acc", "detect_direction", 0)
modparam("acc", "log_flag", 7)
modparam("acc", "log_level", 2)
modparam("acc", "log_missed_flag", 8)
modparam("acc", "failed_transaction_flag", 9)
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "log_facility", "LOG_LOCAL6")

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

@ -0,0 +1,81 @@
#!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", "failed_auth_hash=>size=8;autoexpire=3600;")
######## 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]
{
if (has_totag() || isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
# 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");
drop();
exit;
}
}
route[ANITFLOOD_AUTH_LIMIT]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return(1);
}
if ($Au != $null &&
$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)){
xlog("L_NOTICE", "$ci|end|request at authorization failure limit for $Au $si:$sp");
drop();
exit;
} else {
$sht(failed_auth_hash=>$Au::count) = 0;
}
}
}
route[ANTIFLOOD_SUCCESSFUL_AUTH]
{
if ($Au != $null && $sht(failed_auth_hash=>$Au::count) != $null) {
$sht(failed_auth_hash=>$Au::count) = 0;
}
}
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;
xlog("L_INFO", "$ci|log|$sht(failed_auth_hash=>$Au::count) errounous authorization response for $Au $si:$sp");
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)){
xlog("L_INFO", "$ci|end|registration forbidden $Au $si:$sp");
send_reply("403", "Forbidden");
exit;
}
}
}

+ 1
- 0
kamailio/dbtext/active_watchers View File

@ -0,0 +1 @@
id(int,auto) presentity_uri(string) watcher_username(string) watcher_domain(string) to_user(string) to_domain(string) event(string) event_id(string,null) to_tag(string) from_tag(string) callid(string) local_cseq(int) remote_cseq(int) contact(string) record_route(string,null) expires(int) status(int) reason(string,null) version(int) socket_info(string) local_contact(string) from_user(string) from_domain(string) updated(int) updated_winfo(int)

+ 1
- 0
kamailio/dbtext/location View File

@ -0,0 +1 @@
id(int,auto) ruid(string) username(string) domain(string,null) contact(string) received(string,null) path(string,null) expires(int) q(double) callid(string) cseq(int) last_modified(int) flags(int) cflags(int) user_agent(string) socket(string,null) methods(int,null) instance(string,null) reg_id(int)

+ 1
- 0
kamailio/dbtext/presentity View File

@ -0,0 +1 @@
id(int,auto) username(string) domain(string) event(string) etag(string) expires(int) received_time(int) body(blob) sender(string,null)

+ 4
- 0
kamailio/dbtext/version View File

@ -2,3 +2,7 @@ table_name(string) table_version(int)
address:6
trusted:5
pua:7
active_watchers:11
presentity:3
watchers:3
location:6

+ 1
- 0
kamailio/dbtext/watchers View File

@ -0,0 +1 @@
id(int,auto) presentity_uri(string) watcher_username(string) watcher_domain(string) event(string) status(int) reason(string,null) inserted_time(int)

+ 112
- 82
kamailio/default.cfg View File

@ -23,8 +23,9 @@ max_while_loops = 500
####### Logging Parameters #########
debug = L_INFO
memdbg = 10
memlog = 10
memlog = L_INFO
corelog = L_ERR
mem_summary = 12
log_stderror = no
log_facility = LOG_LOCAL0
log_name="kamailio"
@ -112,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 ########
@ -140,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)
@ -150,13 +146,12 @@ modparam("db_text", "db_mode", 1)
####### Kazoo Integration module ##########
loadmodule "db_kazoo.so"
modparam("db_kazoo", "node_hostname", "MY_HOSTNAME")
modparam("db_kazoo", "register_fs_path", "MY_IP_ADDRESS")
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL")
#!ifdef MY_AMQP_URL_SECONDARY
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL_SECONDARY")
#!endif
#!ifdef MY_AMQP_URL_TERTIARY
#modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL_TERTIARY")
modparam("db_kazoo", "amqp_connection", "MY_AMQP_URL_TERTIARY")
#!endif
#!ifdef MY_AMQP_MAX_CHANNELS
modparam("db_kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS)
@ -164,7 +159,7 @@ modparam("db_kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS)
modparam("db_kazoo", "amqp_max_channels", 100)
#!endif
modparam("db_kazoo", "amqp_internal_loop_count", 1);
modparam("db_kazoo", "amqp_consumer_loop_count", 3);
modparam("db_kazoo", "amqp_consumer_loop_count", 4);
####### Role Configurations ##########
#!ifdef DISPATCHER-ROLE
@ -185,6 +180,15 @@ include_file "websockets-role.cfg"
#!ifdef TLS-ROLE
include_file "tls-role.cfg"
#!endif
#!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"
@ -202,12 +206,15 @@ route
route(SANITY_CHECK);
#!ifdef DISPATCHER-ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
route(CLASSIFY_SOURCE);
#!ifdef ANTIFLOOD-ROLE
route(ANTIFLOOD_RATE_LIMIT);
route(ANITFLOOD_AUTH_LIMIT);
#!endif
#!ifdef TRAFFIC-FILTER-ROLE
route(DOS_PREVENTION);
route(TRAFFIC_FILTER);
#!endif
#!ifdef WEBSOCKETS-ROLE
@ -220,8 +227,6 @@ route
route(HANDLE_MESSAGE);
route(HANDLE_MOVE_REQUEST);
#!ifdef PRESENCE-ROLE
route(HANDLE_SUBSCRIBE);
route(HANDLE_PUBLISH);
@ -268,17 +273,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;
@ -290,12 +306,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;
@ -314,23 +329,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()) {
@ -338,6 +336,14 @@ route[HANDLE_IN_DIALOG_REQUESTS]
record_route();
}
if (loose_route()) {
#!ifdef ACCOUNTING-ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
#!ifdef WEBSOCKETS-ROLE
if ($du == $null) {
handle_ruri_alias();
@ -385,7 +391,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")) {
@ -395,8 +401,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");
@ -421,7 +440,14 @@ route[RELAY]
route[INTERNAL_TO_EXTERNAL_RELAY]
{
remove_hf_re("X-.*");
#!ifdef ACCOUNTING-ROLE
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
remove_hf_re("^X-.*");
t_on_reply("EXTERNAL_REPLY");
@ -432,13 +458,20 @@ 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);
}
#!endif
#!ifdef NAT-TRAVERSAL-ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(NAT_TEST_AND_CORRECT);
}
#!endif
remove_hf_re("X-.*");
remove_hf_re("^X-.*");
append_hf("X-AUTH-IP: $si\r\n");
t_on_reply("INTERNAL_REPLY");
@ -449,39 +482,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");
@ -535,7 +535,6 @@ failure_route[INTERNAL_FAULT]
# cancelled then we are complete
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled");
exit;
}
@ -555,7 +554,7 @@ failure_route[INTERNAL_FAULT]
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null;
}
remove_hf_re("X-.*");
remove_hf_re("^X-.*");
# change 6xx to 4xx
if (t_check_status("6[0-9][0-9]") && !t_check_status("600|603|604|606")) {
@ -601,8 +600,29 @@ onsend_route {
event_route[kazoo:mod-init]
{
#!ifdef PRESENCE-ROLE
kazoo_subscribe("dialoginfo", "direct", "BLF-QUEUE-MY_HOSTNAME", "BLF-MY_HOSTNAME");
### use this simple form of binding a listener
### kazoo_subscribe("dialoginfo", "direct", "BLF-QUEUE-MY_HOSTNAME", "BLF-MY_HOSTNAME");
###
### or unleash the power of rabbit to kazoo-blf
###
### 'no_ack' : 1 => needs ack,
### 'wait_for_consumer_ack'
### : 1 => when it receives, it processses on the AMQP Worker ad after that it confirms
### : 0 => when it receives, it acks then processes in the AMQP Worker
### only works if no_ack : 0
###
### Rabbit Policy for ha-mode
### pattern : ^BLF
### definition : ha-mode: all
###
###
$var(payload) = "{ 'exchange' : 'dialoginfo' , 'type' : 'direct', 'queue' : 'BLF-QUEUE-MY_HOSTNAME', 'routing' : 'BLF-MY_HOSTNAME', 'auto_delete' : 0, 'durable' : 1, 'no_ack' : 0, 'wait_for_consumer_ack' : 1 }";
xlog("L_INFO","SUBSCRIBE $var(payload)");
kazoo_subscribe("$var(payload)");
#!endif
}
event_route[kazoo:consumer-event]
@ -610,5 +630,15 @@ event_route[kazoo:consumer-event]
xlog("L_INFO","unhandled AMQP event, payload: $kzE");
}
event_route[kazoo:consumer-event-connection-open]
{
xlog("L_INFO","connection to $(kzE{kz.json,host}) opened");
}
event_route[kazoo:consumer-event-connection-closed]
{
xlog("L_INFO","connection to $(kzE{kz.json,host}) closed");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 4
- 5
kamailio/dispatcher-role.cfg View File

@ -72,11 +72,10 @@ route[DISPATCHER_FIND_ROUTES]
if($hdr(Replaces)!= $null) {
$var(replaced_call_id) = $(hdr(Replaces){s.select,0,;});
xlog("L_INFO", "$ci|log|replaces call-id $var(replaced_call_id)");
$var(amqp_payload_request) = "{'Event-Category' : 'call_event' , 'Event-Name' : 'channel_status_req', 'Call-ID' : '$var(replaced_call_id)', 'Active-Only' : false }";
$var(amqp_routing_key) = "call.status_req." + $var(replaced_call_id);
if(kazoo_query("callevt", $var(amqp_routing_key), $var(amqp_payload_request), "$var(amqp_result)")) {
xlog("L_INFO", "$ci|log|amqp_result = $var(amqp_result)");
kazoo_json("$var(amqp_result)", "Switch-URL", "$du");
$var(amqp_payload_request) = '{"Event-Category" : "call_event" , "Event-Name" : "channel_status_req", "Call-ID" : "' + $var(replaced_call_id) + '", "Active-Only" : false }';
$var(amqp_routing_key) = "call.status_req." + $(var(replaced_call_id){kz.encode});
if(kazoo_query("callevt", $var(amqp_routing_key), $var(amqp_payload_request))) {
$du = $(kzR{kz.json,Switch-URL});
if($du != $null) {
xlog("L_INFO", "$ci|log|call-id $var(replaced_call_id) found redirecting call to $du, courtesy of kazoo");
return;


+ 1
- 0
kamailio/local.cfg View File

@ -16,6 +16,7 @@ debug = L_INFO
# # #!trydef TRAFFIC-FILTER-ROLE
# # #!trydef WEBSOCKETS-ROLE
# # #!trydef TLS-ROLE
# # #!trydef ANTIFLOOD-ROLE
################################################################################
## SERVER INFORMATION


+ 21
- 10
kamailio/presence-role.cfg View File

@ -4,25 +4,33 @@ loadmodule "presence_dialoginfo.so"
loadmodule "presence_mwi.so"
loadmodule "presence_xml.so"
modparam("presence", "subs_db_mode", 0)
modparam("presence", "subs_db_mode", 1)
modparam("presence", "expires_offset", 60)
modparam("presence", "send_fast_notify", 0)
modparam("presence", "clean_period", 30)
modparam("presence", "publ_cache", 0)
modparam("presence", "min_expires", 0)
modparam("presence", "max_expires", 3600)
modparam("presence", "db_url", "MY_AMQP_URL/dialoginfo")
modparam("presence", "send_fast_notify", 0)
modparam("presence", "clean_period", 30)
## use this
#modparam("presence", "db_url", "MY_AMQP_URL/dialoginfo")
## or this
modparam("presence", "db_url", "text:///etc/kazoo/kamailio/dbtext")
modparam("db_kazoo", "db_url", "text:///etc/kazoo/kamailio/dbtext")
modparam("db_kazoo", "pua_mode", 1)
modparam("presence_xml", "force_active", 1)
######## Presence User Agent module ########
loadmodule "pua.so"
modparam("pua", "db_mode", 0)
modparam("pua", "db_url", "text:///etc/kazoo/kamailio/dbtext")
modparam("pua", "update_period", 6)
modparam("pua", "min_expires", 300)
modparam("pua", "outbound_proxy", "sip:MY_IP_ADDRESS")
#loadmodule "pua.so"
#modparam("pua", "db_mode", 0)
#modparam("pua", "db_url", "text:///etc/kazoo/kamailio/dbtext")
#modparam("pua", "update_period", 6)
#modparam("pua", "min_expires", 300)
#modparam("pua", "outbound_proxy", "sip:MY_IP_ADDRESS")
####### Presence Logic ########
@ -74,7 +82,10 @@ route[HANDLE_PUBLISH]
event_route[kazoo:consumer-event-presence-update]
{
xlog("L_INFO", "received $(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From})");
kazoo_pua_publish($kzE);
pres_refresh_watchers("$(kzE{kz.json,From})", "$(kzE{kz.json,Event-Package})", 1);
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 84
- 115
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,103 @@ 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 $fu $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]
{
if ($sht(auth_cache=>$Au) != $null) {
xlog("L_INFO", "$ci|log|authenticating $fu 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);
}
#!ifdef ANTIFLOOD-ROLE
route(ANTIFLOOD_SUCCESSFUL_AUTH);
#!endif
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;
}
if ($sht(auth_cache=>$Au) == $null) {
xlog("L_INFO", "$ci|log|caching SIP credentials for $Au");
$sht(auth_cache=>$Au) = $var(password);
}
return(1);
}
#AUTH: add to failed_auth_hash in case of authentication password error
route[FAILED_AUTH_COUNT]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
# 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;
}
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) == 0) {
xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp");
exit;
}
}
route[DOMAIN_FORMAT_CHECK]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
if($(proto{s.tolower}) == "udp" || $(proto{s.tolower}) == "tcp" || $(proto{s.tolower}) == "tls") {
$var(return_port) = $Rp;
} else {
$var(return_port) = "5060";
}
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;
$var(params) = "fs_path=<sip:MY_IP_ADDRESS:" + $var(return_port) + ";lr;received='" + $rz + ":" + $si + ":" + $sp + ";transport=" + $proto + "'>";
## TODO: fix escaping, some phones send us -- reg-id=1;+sip.instance="urn:uuid:9b8bd513-0e6e-4660-ad5e-5e35d88cc68f";
## and if we can store it but not use it because it looses the escapes (that weren't there...)
#if($(ct{tobody.params}) != $null) {
# $var(params) = $(ct{tobody.params}{s.escape.common}) + ";" + $var(params);
#}
if ($avp(AVP_RECV_PARAM) == $null) {
$var(fs_contact) = "<" + $(ct{tobody.uri}) + ";" + $var(params) + ">";
} else {
$var(fs_contact) = "<sip:" + $(ct{tobody.user}) + "@" + $si + ":" + $sp + ";transport=" + $proto + ";" + $var(params) + ">";
}
$var(register_contants) = ' "Presence-Hosts" : "n/a", "Profile-Name" : "sipinterface_1", "Status" : "Registered", "Event-Timestamp" : "' + $TS + '", "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 $var(fs_contact)");
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|end|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;
}
}

+ 2
- 2
rabbitmq/rabbitmq.config View File

@ -1,6 +1,6 @@
[{rabbit, [{disk_free_limit, 5242880}
[
{rabbit, [{disk_free_limit, 5242880}
,{vm_memory_high_watermark, 0.8}
,{hipe_compile, true}
,{loopback_users, []}
]}
].

Loading…
Cancel
Save