#!KAMAILIO # # vim: ai ####### Defined Values ######### #!define FLB_NATB 6 #!define FLB_NATSIPPING 7 ####### Global Parameters ######### ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR #!ifdef WITH_DEBUG debug=4 log_stderror=yes #!else debug=2 log_stderror=no #!endif memdbg=5 memlog=5 log_facility=LOG_LOCAL0 fork=yes children=4 dns_srv_lb=yes dns_try_ipv6=no dns_use_search_list=no use_dns_failover=yes dns_retr_time=1 dns_retr_no=1 dns_try_naptr=no use_dns_cache=on dns=no rev_dns=no check_via=no /* uncomment the next line to disable TCP (default on) */ #disable_tcp=yes /* add local domain aliases */ listen=udp:LBIPADDR:5060 listen=tcp:LBIPADDR:5060 listen=tls:LBIPADDR:5061 enable_tls=yes # life time of TCP connection when there is no traffic # - a bit higher than registration expires to cope with UA behind NAT tcp_connection_lifetime=3605 force_rport=yes mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/" loadmodule "tm.so" loadmodule "sl.so" loadmodule "rr.so" loadmodule "mi_fifo.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "tmx.so" loadmodule "pv.so" loadmodule "maxfwd.so" loadmodule "usrloc.so" loadmodule "registrar.so" loadmodule "textops.so" loadmodule "siputils.so" loadmodule "xlog.so" loadmodule "sanity.so" loadmodule "ctl.so" loadmodule "cfg_rpc.so" loadmodule "mi_rpc.so" loadmodule "ipops.so" loadmodule "nathelper.so" loadmodule "tls.so" loadmodule "htable.so" loadmodule "pike.so" #!ifdef WITH_DEBUG loadmodule "debugger.so" #!endif loadmodule "path.so" loadmodule "dispatcher.so" loadmodule "gzcompress.so" modparam("path", "use_received", 1) # ----- dispatcher ----- modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list") modparam("dispatcher", "flags", 2) modparam("dispatcher", "dst_avp", "$avp(AVP_DST)") modparam("dispatcher", "grp_avp", "$avp(AVP_GRP)") modparam("dispatcher", "cnt_avp", "$avp(AVP_CNT)") modparam("dispatcher", "ds_ping_method", "OPTIONS"); modparam("dispatcher", "ds_ping_interval", 1); modparam("dispatcher", "ds_probing_mode", 1); modparam("dispatcher", "ds_ping_from", "sip:loadbalancer@LBIPADDR"); # ----- mi_fifo params ----- modparam("mi_fifo", "fifo_name", "/var/run/kamailio/kamailio_fifo") # ----- tm params ----- # auto-discard branches from previous serial forking leg modparam("tm", "failure_reply_mode", 3) # default retransmission timeout: 30sec modparam("tm", "fr_timer", 30000) # default invite retransmission timeout after 1xx: 120sec modparam("tm", "fr_inv_timer", 120000) # ----- rr params ----- # set next param to 1 to add value to ;lr param (helps with some UAs) modparam("rr", "enable_full_lr", 0) # do not append from tag to the RR (no need for this script) modparam("rr", "append_fromtag", 0) # ----- nathelper params ----- modparam("nathelper", "natping_interval", 30) modparam("nathelper", "ping_nated_only", 0) modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org") # params needed for NAT traversal in other modules modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") modparam("usrloc", "nat_bflag", FLB_NATB) # ----- tls params ----- modparam("tls", "config", "/etc/kamailio/tls.cfg") # ----- pike params ----- modparam("pike", "sampling_time_unit", 2) modparam("pike", "reqs_density_per_unit", 32) modparam("pike", "remove_latency", 4) # ----- htable params ----- # ip ban htable with autoexpire after 5 minutes modparam("htable", "htable", "ipban=>size=8;autoexpire=300;") #!ifdef WITH_DEBUG # ----- debugger params ----- modparam("debugger", "cfgtrace", 1) modparam("debugger", "log_level_name", "exec") #!endif ####### Routing Logic ######## # Main SIP request routing logic # - processing of any incoming SIP request starts with this route # - note: this is the same as route { ... } request_route { if(t_precheck_trans()) { t_check_trans(); exit; } else { if(is_method("INVITE") && !has_totag()) { t_newtran(); t_reply("100","Trying"); } } route(REQINIT); remove_hf_re("^[XP]-"); remove_hf_re("^User-Agent"); remove_hf_re("^Server"); route(NATDETECT); route(WITHINDLG); if (is_method("INVITE|SUBSCRIBE")) { record_route(); } if(!is_in_subnet($si, "REGISTRARNET/30")) { if($ai!=$null) { append_hf("P-Asserted-Identity: <$ai>\r\n"); } add_path_received("loadbalancer"); if($rd!="sip.itco.nl") { $rd="sip.itco.nl"; } ds_select_dst(1, 0); t_on_failure("RTF_DISPATCH"); } else { remove_hf("Route"); loose_route(); } route(RELAY); } # Wrapper for relaying requests route[RELAY] { # enable additional event routes for forwarded requests # - serial forking, RTP relaying handling, a.s.o. if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) { if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH"); } if (is_method("INVITE|SUBSCRIBE|UPDATE")) { if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY"); } if (is_method("INVITE")) { if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); } if (!t_relay()) { sl_reply_error(); } exit; } # Per SIP request initial checks route[REQINIT] { # flood dection from same IP and traffic ban for a while # be sure you exclude checking trusted peers, such as pstn gateways # - local host excluded (e.g., loop to self) if(src_ip!=myself && !is_in_subnet($si, "REGISTRARNET/30")) { if($sht(ipban=>$si)!=$null) { # ip is already blocked xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n"); exit; } if (!pike_check_req()) { xlog("L_ALERT","ALERT: pike blocking $rm from $fu (IP:$si:$sp)\n"); $sht(ipban=>$si) = 1; exit; } } if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); sl_send_reply("400","Insane request"); exit; } if($ua =~ "friendly-scanner") { drop; } if($ua =~ "sipcli") { drop; } if($ua =~ "VaxSIPUserAgent") { drop; } if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; } if(is_method("OPTIONS") && $rU=="cluster") { ds_select_dst(1, 0); t_on_failure("RTF_OPTIONS_DISPATCH"); route(RELAY); exit; } if(is_method("OPTIONS") && $fU=="pinger" && is_in_subnet($si, "REGISTRARNET/30")) { record_route(); remove_hf("Route"); $avp(route)=$(hdr(Route)[0]); $avp(route)=$(avp(route){s.strip,1}); $avp(route)=$(avp(route){s.striptail,1}); $avp(received)=$(avp(route){uri.param,received}); $avp(received)=$(avp(received){s.unescape.param}); $du=$avp(received); route(RELAY); exit; } if(is_method("OPTIONS")) { sl_send_reply("200","Keepalive"); exit; } if(is_method("OPTIONS") && uri==myself && $rU==$null) { sl_send_reply("200","Keepalive"); exit; } } # Handle requests within SIP dialogs route[WITHINDLG] { if (!has_totag()) return; # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { route(DLGURI); if ( is_method("ACK") ) { # ACK is forwarded statelessy route(NATMANAGE); } else if ( is_method("NOTIFY") ) { # Add Record-Route for in-dialog NOTIFY as per RFC 6665. record_route(); } route(RELAY); exit; } if (is_method("SUBSCRIBE") && uri == myself) { # in-dialog subscribe requests exit; } if ( is_method("ACK") ) { if ( t_check_trans() ) { # no loose-route, but stateful ACK; # must be an ACK after a 487 # or e.g. 404 from upstream server route(RELAY); exit; } else { # ACK without matching transaction ... ignore and discard exit; } } sl_send_reply("404","Not here"); exit; } # Caller NAT detection route[NATDETECT] { if(!is_in_subnet($si, "REGISTRARNET/30")) { if (!is_method("REGISTER") && is_first_hop()) { set_contact_alias(); } } return; } # RTPProxy control and singaling updates for NAT traversal route[NATMANAGE] { if(!is_in_subnet($si, "REGISTRARNET/30")) { if (is_reply() && is_first_hop()) { set_contact_alias(); } } return; } # URI update for dialog requests route[DLGURI] { if(!isdsturiset()) { handle_ruri_alias(); } return; } # Manage outgoing branches branch_route[MANAGE_BRANCH] { route(NATMANAGE); } # Manage incoming replies onreply_route[MANAGE_REPLY] { remove_hf_re("^[XP]-"); if(status=~"[12][0-9][0-9]") route(NATMANAGE); } # Manage failure routing cases failure_route[MANAGE_FAILURE] { route(NATMANAGE); if (t_is_canceled()) { exit; } } failure_route[RTF_DISPATCH] { if (t_is_canceled()) { exit; } if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) { if(ds_next_dst()) { t_on_failure("RTF_DISPATCH"); route(RELAY); exit; } } } failure_route[RTF_OPTIONS_DISPATCH] { if (t_is_canceled()) { exit; } if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) { xlog("L_ALERT","RTF_OPTIONS_DISPATCH: $rm from $fu (IP:$si:$sp) to $ru $du\n"); ds_mark_dst("ip"); if(ds_next_dst()) { t_on_failure("RTF_OPTIONS_DISPATCH"); route(RELAY); exit; } } }