Opensips and Asterisk Integeration, Opensips as Load Balancer and Registerar and Asterisk as Media server

The scope of current project is to setup Opensips and Asterisk setup with Opensips role as Registrar as well as Load balancer b/t two asterisk servers . The asterisk servers role will be as Media servers only . It is required that all registrations requests need to be forwarded to opensips server and stored at mysql database and all call related Initial SIP request need to redirected to asterisk servers for further call handling operations .

We used following open source software applications

opensips : OpenSIPS Verision 2.3.2
CentOS : CentOS 6.9
asterisk : Asterisk 11.21
opensips-cp ver : OpenSIPS-CP Version 7.2.3 (compatible with OpenSIPS Server 2.3.x)

Installation Setps of Opensips

Opensips installation

---------------------
# Install opensips repositry

yum install http://yum.opensips.org/2.3/releases/el/6/x86_64/opensips-yum-releases-2... # CentOS 6.X

yum install http://yum.opensips.org/2.3/releases/el/7/x86_64/opensips-yum-releases-2... # Centos 7.x

# Install opensips

yum install opensips

# Database setup
# Please enter your database information in opensipsctlrc

vi /etc/opensips/opensipsctlrc

DBENGINE=
DBHOST=
DBPORT=
DBNAME=
DBRWUSER=
DBRWPW=
DBROOTUSER=

#save it
# now create database with tables
# run this command

opensipsdbctl create

#if facing "ERROR: database engine not loaded - tried 'MYSQL'" error then fisrt install db_mysql pakcge then try again

yum install opensips-db_mysql
opensipsdbctl create

# restart opensips

service opensips restart

Opensips-Control-Panel installation

------------------------------------

# install required packages for web
yum install httpd php php-gd php-mysql php-xmlrpc php-pear mysql mysql-server php-mysql

# Download Opensips-cp
# first check opensips version and then download opensips-cp
http://controlpanel.opensips.org/

# Configure Apache


Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all

Alias /cp /var/www/html/opensips-dir

# Check following extensions are enabled

vi /etc/php.d/ mysql.ini, gd.ini, xmlrpc.in

# If these are not there plese check if you have installed them correctly.
# Do not forget to set in your php.ini (usaully /etc/php.ini ) :

short_open_tag = On ;

# Install MDB2 pear

pear install MDB2
pear install MDB2#mysql //should you choose to go with the mysql database
pear install log

# Restart Apache
service httpd restart

# create database and insert data into database (use already created database)

# install User access and Privileges
# goto opensips folder
cd /var/www/html/opension-dir

# run following commands
mysql -Dopensips -p

# create Admin Privileges
INSERT INTO ocp_admin_privileges (username,password,ha1,available_tools,permissions) values ('admin','admin',md5('admin:admin'),'all','all');

# change config file according to your database setting
vi /var/www/html/opensips-dir/config/db.inc.php

grant all privileges on opensips.* to os_usr@'%' identified by 'gE88&1QK';

# add Statistics Monitor (smonitor) tool into opensips database
mysql -Dopensips -p

# install cron job but first change / correct the path to your opensips control panel folder
cp config/tools/system/smonitor/opensips_stats_cron /etc/cron.d/

# Restart Corn services

# visit your website

http://server-ip/opensips-dir/web
admin / admin

Opensips control panel Configuration Steps

Enable SIP Trace log for GUI / OpenSip control panel

Database layer configuration file
opensips-cp/config/tools/system/siptrace/db.inc.php

Attributes set in thi file:
//database host
//$config->db_host_siptrace = "localhost";

//database port - leave empty for default
//$config->db_port_siptrace = "";

//database connection user
//$config->db_user_siptrace = "root-user";

//database connection password
//$config->db_pass_siptrace = "root-user-password";

Local configuration file
opensips-cp/config/tools/system/siptrace/local.inc.php

Attributes set in this file :

$config->table_trace
the database table name for storing the siptrace data

$config->results_per_page and $config->results_page_range
control over the pagination when displaying the siptrace records

$talk_to_this_assoc_id
As OCP can manage multiple OpenSIPS instances, this is the association ID pointing to the group of servers (system) which needs to be provision with this siptrace status (on or off).

$proxy_list
an array of SIP interfaces (protocol, IP address and port) to be recognized as belonging to your OpenSIPS servers - you must provide at least one entry. This iss very important to be correctly provision, otherwise the tool will not be able to properly graph the SIP flow (as it will not know which entity in the flow is your OpenSIPS).

Opensips control panel modules exists in "/var/www/html/config/tools/system", please change module database configuration file according to our database information

Opensip module installation

Please load module and add module`s parameter in opensip.conf file and restart opensip service. First make sure module installed on your server, if module not installed. Please install it via yum command

All Module exist in following folder (if you are using CentOS 6.x 64 bits)
ls -l /usr/lib64/opensips/modules/*

yum install opensips-db_mysql

#### MYSQL module
loadmodule "db_mysql.so"

#### Registrar module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")

opensips.conf
=============
####### Global Parameters #########

log_level=3
log_stderror=no
log_facility=LOG_LOCAL0
children=4

/* uncomment the following lines to enable debugging */
#debug_mode=yes

/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes

/* comment the next line to enable the auto discovery of local aliases
based on revers DNS on IPs */
auto_aliases=no

listen=udp:192.168.1.111:5060 # CUSTOMIZE WITH OPENSIPS SERVER IP
listen=tcp:192.168.1.111:5060 # CUSTOMIZE WITH OPENSIPS SERVER IP

####### Modules Section ########

#set module path
mpath="/usr/lib64/opensips/modules"

#### SIGNALING module
loadmodule "signaling.so"

#### StateLess module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)

#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)

#### MAX ForWarD module
loadmodule "maxfwd.so"

#### MYSQL module
loadmodule "db_mysql.so"

#### HTTPD module
loadmodule "httpd.so"
modparam("httpd", "port", 8888)

#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE WITH DATABASE INFORMATION

#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)

#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"

#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)

#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)

#### AUTHentication modules
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db|uri", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE WITH DATABASE INFORMATION
modparam("auth_db", "load_credentials", "")

#### SIPTrace
loadmodule "siptrace.so"
modparam("siptrace", "trace_id","[tid]uri=mysql://opensips:opensipsrw@localhost/opensips;table=sip_trace;")
#modparam("siptrace", "trace_flag", "22")
#modparam("siptrace", "traced_user_avp", "$avp(traced_user)")
modparam("siptrace", "trace_local_ip", "192.168.1.111") #CUSTOMIZE WITH OPENSIPS SERVER IP

#### AVPOPS module
loadmodule "avpops.so"
modparam("avpops","db_url","mysql://opensips:opensipsrw@localhost/opensips") #CUSTOMIZE WITH DATABASE INFORMATION

#### Dialog moduel
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600) # 6 hours timeout
modparam("dialog", "rr_param", "cookie") # Default value is “did”
modparam("dialog", "db_mode", 1) # 0 = no-db, 1 = real-time, 2 = delayed, 3 = shutdown
modparam("dialog", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE WITH DATABASE INFORMATION

#### ACCounting module
loadmodule "acc.so"
modparam("acc", "db_table_acc", "acc")
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure the enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
modparam("acc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE WITH DATABASE INFORMATION
modparam("acc", "acc_method_column", "method")

#### DISPATCHER module
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE WITH DATABASE INFORMATION
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_probing_mode", 0)
modparam("dispatcher", "ds_ping_interval", 30)

loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"

#### NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger@192.168.1.111") #CUSTOMIZE WITH OPENSIPS SERVER IP
modparam("nathelper", "received_avp", "$avp(received_nh)")

####### Routing Logic ########

# main request routing logic
route{

force_rport();
if (nat_uac_test("23")) {
if (is_method("REGISTER")) {
fix_nated_register();
setbflag(NAT);
} else {
fix_nated_contact();
setflag(NAT);
}
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}

$avp(s:traceuser)=$fu;
setflag(22);
sip_trace("tid", "m", "sip|rest");
xlog("L_INFO","User $fu being traced");

if (has_totag()) {
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
do_accounting("db","missed","acc");
} else if (is_method("INVITE")) {
do_accounting("db","cdr","acc");
# even if in most of the cases is useless, do RR for
# re-INVITEs alos, as some buggy clients do change route set
# during the dialog.
record_route();
}
if (check_route_param("nat=yes"))
setflag(NAT);

# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(RELAY);
} else {
if ( is_method("ACK") ) {
do_accounting("db","missed","acc");
if ( t_check_trans() ) {
# non loose-route, but stateful ACK; must be an ACK after
# a 487 or e.g. 404 from upstream server
t_relay();
exit;
} else {
# ACK without matching transaction ->
# ignore and discard
exit;
}
}
sl_send_reply("404","Not here");
}
exit;
}

#### INITIAL REQUESTS

# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}

t_check_trans();

# preloaded route checking
if (loose_route()) {
record_route();
route(RELAY);
}

# requests for my domain
if (is_method("REGISTER"))
{
# authenticate the REGISTER requests
if (!www_authorize("", "subscriber"))
{
www_challenge("", "0");
exit;
}
if (!db_check_to())
{
sl_send_reply("403","Forbidden auth ID");
exit;
}
if ( proto==TCP || 0 ) setflag(TCP_PERSISTENT);

if (isflagset(NAT)) {
setbflag(SIP_PING_FLAG);
}
if (!save("location"))
sl_reply_error();
exit;
}

if ($rU==NULL) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}

# record routing
record_route();

do_accounting("log");

if ($rU=~"88888") {
if (!lookup("location","m")) {
if (!db_does_uri_exist()) {
send_reply("420","Bad Extension");
exit;
}
t_newtran();
t_reply("404", "Not Found");
exit;
}
}

if( !((src_ip==192.168.1.222) || (src_ip==192.168.1.333))) { #CUSTOMIZE WITH ASTERISK SERVER IPS
do_accounting("db","missed","acc");
if (!ds_select_dst("1","4") ) {
route(RELAY);
send_reply("500","No Destination available");
exit;
}
} else {
if (uri==myself) {
if (!lookup("location","m")) {
if (!db_does_uri_exist()) {
send_reply("420","Bad Extension");
exit;
}
t_newtran();
t_reply("404", "Not Found");
exit;
}
create_dialog();
create_dialog("Pp");
route(RELAY);
exit;
}
}
if (isbflagset(NAT)) setflag(NAT);
t_on_failure("GW_FAILOVER");
route(RELAY);
}

route[RELAY] {
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");

if (!t_relay()) {
sl_reply_error();
};
exit;
}

route[handle_presence]
{
if (!t_newtran())
{
sl_reply_error();
exit;
}
exit;
}

failure_route[GW_FAILOVER] {
if (t_was_cancelled()) {
exit;
}
# failure detection with redirect to next available trunk
if (t_check_status("(408)|([56][0-9][0-9])")) {
xlog("Failed trunk $rd/$du detected \n");
if ( ds_next_dst() ) {
t_on_failure("GW_FAILOVER");
t_relay();
exit;
}
send_reply("500","All GW are down");
}
}

branch_route[per_branch_ops] {
xlog("new branch at $ru\n");
}

onreply_route[handle_nat] {

xlog("incoming reply\n");
}

failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# uncomment the following lines if you want to block client
# redirect based on 3xx replies.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply("404","Not found");
## exit;
##}
}