[SR-Users] Identical Kamailio setup on 2 hosts

Daniel Tryba d.tryba at pocos.nl
Mon Oct 3 11:10:02 CEST 2016


On Fri, Sep 30, 2016 at 10:29:16PM +0530, Infinicalls Infinicalls wrote:
> Hi Daniel,
>  This seems to be ideal setup for my requirement. Would you mind
> sharing the kamailio.cfg file with me (with all the important data
> masked) ?

Not much important stuff to censor.
LBIPADDR is the ipadress of the machine itself.
REGISTRARNET/30 is the net of the backend machines.
The dispatcher.list contains the backend registrars

The backend is essentially the default config (with an always on
rtpengine) with the following additions:
You need to enable path.so and set 
modparam("path", "use_received", 1)

Tell the registrar module to use path (path_mode 1 fixes you 420
problem):
modparam("registrar", "use_path", 1)
modparam("registrar", "path_mode", 1)
modparam("registrar", "path_use_received", 1)

If you want to send keepalives from the registrar to the enduser:
modparam("nathelper", "ping_nated_only", 0)
modparam("nathelper", "udpping_from_path", 1)
the loadbalancer config has a little blurb about relaying the sipping
from the backend manually using the path header. But I'd advice to ping
from the an external process to have better control (eg sipsak)
-------------- next part --------------
#!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 at 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 at 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;
		}
	}
}


More information about the sr-users mailing list