Kamailio SIP proxy — installation and minimal configuration example

When an Asterisk server can’t handle its increased load anymore, more servers must be added. One way to do this is to use a SIP proxy. However, compared to the Asterisk itself, there is much less information available about using SIP proxies. The purpose of this article is to show a simple example of using Kamailio SIP proxy with Asterisk, and thus to help beginners start working with SIP proxies.

For this example we use virtual machines connected to a local network, but the same configuration can work via the Internet without significant adjustments.

Let’s say that there is already one Asterisk server in the organization. The operators process large amounts of calls and the existing Asterisk server cannot handle this load anymore. We will add another server (to be precise, we will clone the existing one), and make our SIP proxy a call dispatcher.

In this example we will use Kamailio with Siremis web-interface, which we will install on CentOS 6.8.

First we need to disable SELinux, update the system and install the necessary dependencies:

yum -y update && yum -y groupinstall core && yum -y groupinstall base && yum -y install epel-release
yum -y install httpd mysql-server php php-mysql php-gd php-curl

We are going to need port 80 for the web interface and udp 5060 for SIP, therefore some IPTables rules are needed:

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -m state --state NEW -m udp -p udp --dport 5060 -j ACCEPT

Next, we create the /etc/yum.repos.d/kamailio.repo file:

[kamailio]
name=RPMs for Kamailio on CentOS 6
type=rpm-md
baseurl=http://rpm.kamailio.org/stable/CentOS_6/
gpgcheck=1
gpgkey=http://rpm.kamailio.org/stable/CentOS_6/repodata/repomd.xml.key
enabled=1

and install Kamailio:

yum install kamailio kamailio-presence kamailio-mysql

We also shouldn’t forget to configure the following services to run at startup:

chkconfig mysqld on
chkconfig httpd on
chkconfig kamailio on

We then need to uncomment one string in the /etc/kamailio/kamctlrc file:

DBENGINE=MYSQL

and specify the SIP_DOMAIN. Since we are setting up the system on the local network, it is sufficient to specify the IP address, which in our case is:

SIP_DOMAIN=192.168.0.237

There are database connection parameters below the SIP_DOMAIN too, but we have no need to change them in this example.

Next, we start MySQL and generate the necessary tables:

service mysqld start
kamdbctl create

answering ‘yes’ to all of the questions.

Now let’s edit the main configuration file: /etc/kamailio/kamailio.cfg. Logically it is divided into several sections: global parameters, modules loading, module parameters and routes. Each Kamailio module performs a specific function; therefore you can only load the libraries that are required for a particular task. The beginning of the file must then be edited to the following:

#!KAMAILIO
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB
#!define WITH_PRESENCE
#!define WITH_ACCDB

These directives turn on the necessary modules. For example, ‘WITH_MYSQL’ enables the loading of mysql.so:

#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif

We can load any module manually, but directives are more convenient. ‘WITH_AUTH’, for example, allows users to register on Kamailio with a username and password.

Next, we will need to make a few adjustments connected with the web interface and statistics.

To do this we add two more strings at the end of the ‘loadmodule’ list:

loadmodule "rtimer.so" 
loadmodule "sqlops.so"

And then we add a module parameter before the routing section, which starts with “####### Routing Logic ########” string:

modparam("rtimer", "timer", "name=cdr;interval=300;mode=1;")
modparam("rtimer", "exec", "timer=cdr;route=CDRS")
modparam("sqlops", "sqlcon", "cb=>mysql://kamailio:kamailiorw@localhost/kamailio")

We also need to add another route after the last string of the route segment (it should be around line #910):

route[CDRS] {
sql_query("cb","call kamailio_cdrs()","rb");
sql_query("cb","call kamailio_rating('default')","rb");
}

It’s now time to start Kamailio and check its status:

service kamailio start
ps aux | grep kamailio

If Kamailio doesn’t start, check /var/log/messages (Kamailio’s default log file) unless any other logging system, like rsyslog, is configured instead.

By default Kamailio uses the MySQL database ‘kamailio’ with user ‘kamailio’ and password ‘kamailiorw’. You can change these parameters in the /etc/kamailio/kamctlrc file before the database is created. If you do this, don’t forget to change them in the kamailio.cfg as well.

If fact, Kamailio can work without a database — you can set all the necessary parameters in the configuration file or in external files, but using a database is more convenient especially in large projects. Additionally, the database is used by the Siremis web-interface, which we are about to install.

First, we need to download and extract the files, copy them to the destination directory and assign the appropriate rights:

cd /usr/src
wget http://siremis.asipto.com/pub/downloads/siremis/siremis-4.3.0.tgz
tar zxvf siremis*
cp -a siremis*/. /var/www/html
cd /var/www/html
make prepare
rm -rf /var/www/html/Makefile
rm -rf /var/www/html/Changelog
rm -rf /var/www/html/README
chown -R apache. /var/www/html

Let’s then add the following code to the ‘VirtualHost’ section of the Apache configuration file:

<Directory "/var/www/html/siremis">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
<FilesMatch "\.xml$">
Order deny,allow
Deny from all
</FilesMatch>
<FilesMatch "\.inc$">
Order deny,allow
Deny from all
</FilesMatch>
</Directory>
<Directory "/var/www/html/openbiz">
AllowOverride All
Order deny,allow
Deny from all
</Directory>
<Directory "/var/www/html/misc">
AllowOverride All
Order deny,allow
Deny from all
</Directory>

Siremis 4.3.0 needs the ‘date.timezone’ parameter from the php.ini, so let’s assign it (Europe/Moscow in this example):

date.timezone = Europe/Moscow

Siremis also requires a separate database. First, we’ll add a user:

mysql -e "GRANT ALL PRIVILEGES ON siremis.* TO siremis@localhost IDENTIFIED BY 'siremisrw';"

You can change the database connection settings, but then do not forget to set these values throughout.

Now we can restart Apache and move to the final stage of the installation of Siremis. Open your-ip/siremis in the browser:

If the system check passed without errors, you can begin installation.

Please note that there are default user passwords for Kamailio and Siremis already entered into the form, and if you haven’t changed them before, you don’t need to enter them manually now.

Be sure to tick all the boxes: ‘Create Siremus DB’, ‘Import Dafault Data’, ‘Update SIP DB’, and ‘Replace DB config’.

Check that you specified the correct data.

The installation is now complete.

Let’s try to make the first call through our brand new Kamailio. We need to add a domain to the ‘Domain List’ in the ‘SIP Admin’ menu. Kamailio will serve only domains (or IP addresses) that are listed there.

When users register with an IP address or the corresponding domain name, both should be in the list. In our example we use only an IP address.

To create a new subscriber we should open ‘Subscriber Services -> Subscribers’ and add two extensions: 101 and 102. We then need to assign their passwords and a grey IP address as a domain (192.168.0.237 in our case).

Using a softphone, such as Zoiper, we can now register on the server and make a call from 101 to 102 (or vice versa) to be sure that we didn’t make any mistakes in the previous steps.

Let’s move to the inbound calls dispatching configuration. We’ve got 2 virtual machines with Asterisk in the local network. Their addresses are 192.168.0.234 and 192.168.0.235. We need to equally distribute the inbound calls between these two machines. In our example we use the ‘dispatcher’ module, which provides all the necessary features.

We can now return to the console and add another library to the module loading section of the kamailio.cfg file:

loadmodule "dispatcher.so"

We also need to add two parameters: 
The connection settings to the database with the Asterisk servers list
The servers checking frequency, which helps avoid sending calls to unavailable servers

modparam("dispatcher", "db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
modparam("dispatcher", "ds_ping_interval", 30)

By the way, you can always find the full list of modules, their parameters and functions at the official website.

Next, we restart Kamailio and check its status. In case of startup problems (modules may have dependencies, require certain parameters for themselves or the modules they depend on) we will be able to find errors in the log.

Now we need to setup routes. The default configuration provides the required minimum. For example, if somebody tries to register with a wrong password, Kamailio will show the 401 error, and if somebody calls a non-existing number — 404. Kamailio routing is difficult to understand because of non-obvious relations between variables and functions on the one hand, and different modules that use them on the other. Fortunately, for our purposes we need a very simple route.

Let’s add the following condition to the start of the main route:

if ( method=="INVITE" ) {
ds_select_dst("1","4");
sl_send_reply("100","Trying");
forward();
exit();
}

When an INVITE request (an invitation to start a conversation) comes, one of the servers from the group ‘1’ is chosen using the strategy ‘4’ (round-robin). Then we send an answer to the caller and transfer the call to its destination. Please note that now every INVITE will be processed in this manner. Thus, we won’t be able to call from 101 to 102 anymore, because such a call will be dispatched to one of the Asterisk servers. Inbound INVITE request will also be sent to the Asterisk servers without any source checking.

To fix this we will add the following ‘peer’ to both Asterisk servers:

[kamailio]
host=192.168.0.237
port=5060
insecure=invite
type=friend
context=from-pstn

Now we can use the web interface to add the Asterisk servers to the Kamailio database:

‘Setid’ sets a group for the server, ‘Priority’ is not used in the «round-robin» strategy, but may be used in other strategies, ‘Flags’ here means that this server is inactive by default, but its state must be checked.

Now that we have added the servers, Kamailio should be restarted. Though, in production use it’s more appropriate to run the kamcmd dispatcher.reload command. You can also always find the full list of modules commands at the official website.

Now we can move to testing. Using a softphone, you can call Kamailio directly without any accounts or registrations. It's enough to type 'sip:1@192.168.0.237' into the dialing field and hit the «Call» button. Kamailio will then send the call to an Asterisk server, which will process this call according to its dialplan. The next call will be sent to the other server.

Generally speaking, we've now solved our task — to distribute inbound calls equally between different servers. However, not every telephony operator is ready to send calls to your IP address directly, without registration, so you will need to send REGISTER-type requests. This feature is implemented by the 'uac' module. Let's add another Asterisk to our scheme, which will play the role of a telephony services provider. We will create an extension number, for example, '200200', which will require registration.

The 'uac' module must be added to the configuration file:

loadmodule "uac.so"

We will also set two parameters which are mandatory in this case:

modparam("uac", "reg_db_url", "mysql://kamailio:kamailiorw@localhost/kamailio")
modparam("uac", "reg_contact_addr", "192.168.0.237")

Additionally, we have to change one parameter in the other module. Find the string:

modparam("rr", "append_fromtag", 0)

and replace it with:

modparam("rr", "append_fromtag", 1)

Now we can configure the registration. In order to load the ‘uac’ module, Kamailio must first be restarted:

Look at the ‘Realm’ field. By default you can enter anything you want, but then the registration will fail with the following message in the log file:

kamailio /usr/sbin/kamailio[26277]: ERROR: uac [uac_reg.c:799]: uac_reg_tm_callback(): realms do not match. requested realm: [asterisk]

Therefore, if you encounter a problem look in the log first.

It only remains to verify that the subscriber ‘200200’ is registered in Asterisk, which plays the role of the provider, and to initiate a call from any extension to ‘200200’.

This concludes our Kamailio setup example. Please note that this article does not discuss important issues such as the work behind NAT, security, outgoing calls routing and many more that you may need in real life, however, I hope that it will make the mastering of Kamailio easier for you.