The article describes how to add the MySQL support for the Kamailio 3.1.0 server. Activities described here are following the basic Kamailio server installation, described in the article Installing Kamailio 3.1 on debian lenny.
Installing Mysql server and mysql module for Kamailio
To use such persistant storage as a database we first need to install DB server, the Mysql here, and kamailio modules which the kamailio will use to connect into database, the kamailio-mysql-modules here.
Installation, thanks to adding kamailio repository for debian, is straightforward
pstest:/home/palo# apt-get install mysql-server kamailio-mysql-modules
During the Mysql server installation we are asked to add root password for mysql server.
Next, we have to specify parameters, which the kamailio server will use for database connection. Therefore we need to edit the /etc/kamailio/kamctlrc file and we need to set up required parameters, which the kamailio server and kamctl cmd will use.
We will add or uncomment following lines:
SIP_DOMAIN=ps.sip.uniza.sk DBENGINE=MYSQL DBHOST=localhost # I changed DBNAME from default named "openser", cause I've already created opernser for other OpenSER process DBNAME=kamailio DBRWUSER=openser DBRWPW="openserrw" DBROUSER=openserro DBROPW=openserro DBROOTUSER="root" ALIASES_TYPE="DB" CTLENGINE="FIFO" # rewrite OSER_FIFO="FIFO", because # it is causing the fifo error OSER_FIFO="/tmp/kamailio_tmp" VERBOSE=1 PID_FILE=/var/run/kamailio.pid
pstest:/etc/kamailio# kamdbctl create MySQL password for root: database engine 'mysql' loaded INFO: test server charset INFO: creating database kamailio ... Creating core table: standard Creating core table: acc Creating core table: lcr Creating core table: domain Creating core table: group Creating core table: permissions Creating core table: registrar Creating core table: usrloc Creating core table: msilo Creating core table: alias_db Creating core table: uri_db Creating core table: speeddial Creating core table: avpops Creating core table: auth_db Creating core table: pdt Creating core table: dialog Creating core table: dispatcher Creating core table: dialplan INFO: Core Kamailio tables succesfully created.
As a final point we will try add a new user into the database
pstest:/etc/kamailio# kamctl add palo palo_password database engine 'MYSQL' loaded Control engine 'FIFO' loaded is_user: user counter=0 check_db_alias: alias counter=0 new user 'palo' added
Correct, everything works!
Configuration of the Kamailio for using of the MySQL
Loading required modules
We need to check, if required kamailio modules for the Mysql usage are loaded. If not, we will uncomment lines with modules that are required to be loaded. So open the /etc/kamailio/kamailio.cfg file. Looking first time in is for me a little surprise comparing to the old fashioned OpenSER configs. Kamailio 3.1.x comes with a new feature called DEFINE zone blocks, mentioned in http://www.kamailio.org/dokuwiki/doku.php/features:new-in-3.1.x?s[]=define
After a few second of familiarization with this feature we should start. As a first step we define zone blocks for mysql support (WITH_MYSQL), database authentication (WITH_AUTH), database aliasing (WITH_ALIASDB), and persistent location storage (WITH_USRLOCDB) (recommended inside of the config file as notes).
At the end of this article we will see, that using of this define blocks make easier our effort, because everything was prepared for us (of course, the configation of the Mysql support is a very simple example of the kamailio usage).
So as a next step define following zone blocks.
#!define WITH_MYSQL #!define WITH_AUTH #!define WITH_ALIASDB #!define WITH_USRLOCDB
Go next throught the cfg file and check lines to find inside of the ####### Defined Values ######### config part DB_URL defien block. Check if your DB URL is configured correctly.
#!define DBURL "mysql://openser:openserrw@localhost/kamailio"
In my case, because I’ve changed table name in /etc/kamailio/kamctlrc file during mysql initiation, my DB_URL is pointing to the "kamailio" DB table, not to the default "openser" DB table.
Next, inside of the module section we find lines:
#!ifdef WITH_MYSQL loadmodule "db_mysql.so" #!endif
because we define #!define WITH_MYSQL support, I’m assuming that it is ok, and db_mysql.so module will be loaded.
Following next we also find lines for DB authentication
#!ifdef WITH_AUTH loadmodule "auth.so" loadmodule "auth_db.so" #!endif
and because we also defined #!define WITH_AUTH block zone, I again supposing, that respective modules will be loaded (as we will see).
Next block zone for DB aliasing is in
#!ifdef WITH_ALIASDB loadmodule "alias_db.so" #!endif
as a last step check if usrloc module is commented out (by, default is yes)
loadmodule "usrloc.so"
That’s all for the module section, all required module should be loaded.
Setting up module parameters
Now we will check and will set up required module parameters to ensure that loaded modules will work properly.
Move to the part of the kamailio.cfg file starting with line
# ----------------- setting module-specific parameters --------------
The module parameters section is starting here.
Going through the config file we first find modparams regarding usrloc module. Because we define block WITH_USRLOCDB previously, the parameters will be setted up.
# ----- usrloc params ----- /* enable DB persistency for location entries */ #!ifdef WITH_USRLOCDB modparam("usrloc", "db_url", DBURL) modparam("usrloc", "db_mode", 2) modparam("usrloc", "use_domain", MULTIDOMAIN) #!endif
All parameters meaning looks clear, just we will check what is db_mode =2. Looking inside of the usrloc module docs for db_mode =2 we will find, that 2 means
2 – Write-Back scheme. This is a combination of previous two schemes. All changes are made to memory and database synchronization is done in the timer. The timer deletes all expired contacts and flushes all modified or new contacts to database. Use this scheme if you encounter high-load peaks and want them to process as fast as possible. The mode will not help at all if the load is high all the time. Also, latency of this mode is much lower than latency of mode 1, but slightly higher than latency of mode 0.
ok, accepted.
Next, check params for auth_db, there are default setting,
# ----- auth_db params ----- #!ifdef WITH_AUTH modparam("auth_db", "db_url", DBURL) modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password") modparam("auth_db", "load_credentials", "") modparam("auth_db", "use_domain", MULTIDOMAIN) #!endif
where it means, that DB table is located at DBURL location, and the server use the password hashed from the DB table column named password.
Ok, accepted.
Next alias_db params
# ----- alias_db params ----- #!ifdef WITH_ALIASDB modparam("alias_db", "db_url", DBURL) modparam("alias_db", "use_domain", MULTIDOMAIN) #!endif
accepted and this is the end of parameters section, next we are going to modify the route logic.
Modifying route logic for using DB
Setting up registrar server
We will use our Kamailio server not only as Proxy but also as Registrar (therefore inside of the config file there is also loaded registrar module "registrar.so" (by default)) to build up a location bindings stored in the DB. The registration process will authenticate users to accept registration. Inside of the main route logic there is a calling into route(AUTH); block zone. Finding this block in cfg file we may see, that this is the part of route logic handling the authentication process. The first part of the route(AUTH) concerns about the handling of the REGISTER message.
#!ifdef WITH_AUTH if (is_method("REGISTER")) { # authenticate the REGISTER requests (uncomment to enable auth) if (!www_authorize("$td", "subscriber")) { www_challenge("$td", "0"); exit; } if ($au!=$tU) { sl_send_reply("403","Forbidden auth ID"); exit; } } else {
by default evrything is commented out, so we do not need to change anything.
next part
# authenticate if from local subscriber if (from_uri==myself) { if (!proxy_authorize("$fd", "subscriber")) { proxy_challenge("$fd", "0"); exit; } if (is_method("PUBLISH")) { if ($au!=$tU) { sl_send_reply("403","Forbidden auth ID"); exit; } } else { if ($au!=$fU) { sl_send_reply("403","Forbidden auth ID"); exit; } } consume_credentials(); # caller authenticated } else { # caller is not local subscriber, then check if it calls # a local destination, otherwise deny, not an open relay here if (!uri==myself) { sl_send_reply("403","Not relaying"); exit; } } } #!endif
and mainly the sub-part
if (from_uri==myself) { if (!proxy_authorize("$fd", "subscriber")) { proxy_challenge("$fd", "0"); exit; }
is doing the INVITE message proxy authentication, by default is not commented, so it should work!
And we are at the end of configuration, next we will do testing of the configuration.
Testing
First we check if the config is syntactically correct and if we did not do some mistypes. We will use the -c paramerter of the kamailio cmd.
pstest:/etc/kamailio# kamailio -c kamailio.cfg loading modules under /usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/ Listening on udp: 158.193.139.51:5060 tcp: 158.193.139.51:5060 Aliases: tcp: pstest:5060 tcp: pstest.ps.sip.uniza.sk:5060 udp: pstest:5060 udp: pstest.ps.sip.uniza.sk:5060 *: ps.sip.uniza.sk:* config file ok, exiting..
Next we will restart the kamailio service to accept cfg changes…
pstest:/etc/kamailio# /etc/init.d/kamailio restart Restarting kamailio: kamailioloading modules under /usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/ Listening on udp: 158.193.139.51:5060 tcp: 158.193.139.51:5060 Aliases: tcp: pstest:5060 tcp: pstest.ps.sip.uniza.sk:5060 udp: pstest:5060 udp: pstest.ps.sip.uniza.sk:5060 *: ps.sip.uniza.sk:*
ok…
Next we will add a new user into the DB
pstest:/etc/kamailio# kamctl add jojo jojo's_password database engine 'MYSQL' loaded Control engine 'FIFO' loaded is_user: user counter=0 check_db_alias: alias counter=0 new user 'jojo' added
and we will use our favorite client to make a registration. To obseve the registration process we start the ngrep as the frontend process and will do registration usign the UA.
ngrep -p -q -W byline port 5060
REGISTER sip:ps.sip.uniza.sk SIP/2.0. Via: SIP/2.0/UDP 192.168.10.108:40468;branch=z9hG4bK-d8754z-f23264153e04534e-1---d8754z-;rport. Max-Forwards: 70. Contact: <sip:jojo@192.168.10.108:40468;rinstance=d5b063d544035d5a>. To: "jojo"<sip:jojo@ps.sip.uniza.sk>. From: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=766b1952. Call-ID: NjA5OGNiZjVhNzdmNmYxODBlNDQ4YTEwMDdmNDAwZWM.. CSeq: 1 REGISTER. Expires: 3600. Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO. User-Agent: eyeBeam release 1102q stamp 51814. Content-Length: 0. . U 158.193.139.51:5060 -> 158.193.152.64:28507 SIP/2.0 401 Unauthorized. Via: SIP/2.0/UDP 192.168.10.108:40468;branch=z9hG4bK-d8754z-f23264153e04534e-1---d8754z-;rport=28507;received=158.193.152.64. To: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=f11c829fa10fd0f1cba4621773c131eb.7aac. From: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=766b1952. Call-ID: NjA5OGNiZjVhNzdmNmYxODBlNDQ4YTEwMDdmNDAwZWM.. CSeq: 1 REGISTER. WWW-Authenticate: Digest realm="ps.sip.uniza.sk", nonce="TOZNH0zmS/PNRBKh6l0jzT2BpN5uANl2". Server: kamailio (3.1.0 (x86_64/linux)). Content-Length: 0. U 158.193.152.64:28507 -> 158.193.139.51:5060 REGISTER sip:ps.sip.uniza.sk SIP/2.0. Via: SIP/2.0/UDP 192.168.10.108:40468;branch=z9hG4bK-d8754z-371ce327c1613374-1---d8754z-;rport. Max-Forwards: 70. Contact: <sip:jojo@192.168.10.108:40468;rinstance=d5b063d544035d5a>. To: "jojo"<sip:jojo@ps.sip.uniza.sk>. From: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=766b1952. Call-ID: NjA5OGNiZjVhNzdmNmYxODBlNDQ4YTEwMDdmNDAwZWM.. CSeq: 2 REGISTER. Expires: 3600. Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO. User-Agent: eyeBeam release 1102q stamp 51814. Authorization: Digest username="jojo",realm="ps.sip.uniza.sk",nonce="TOZNH0zmS/PNRBKh6l0jzT2BpN5uANl2",uri="sip:ps.sip.uniza.sk",response="6a22108222110e5b4df904c08c5e6879",algorithm=MD5. Content-Length: 0. . U 158.193.139.51:5060 -> 158.193.152.64:28507 SIP/2.0 200 OK. Via: SIP/2.0/UDP 192.168.10.108:40468;branch=z9hG4bK-d8754z-371ce327c1613374-1---d8754z-;rport=28507;received=158.193.152.64. To: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=f11c829fa10fd0f1cba4621773c131eb.00fb. From: "jojo"<sip:jojo@ps.sip.uniza.sk>;tag=766b1952. Call-ID: NjA5OGNiZjVhNzdmNmYxODBlNDQ4YTEwMDdmNDAwZWM.. CSeq: 2 REGISTER. Contact: <sip:jojo@192.168.10.108:40468;rinstance=d5b063d544035d5a>;expires=3600. Server: kamailio (3.1.0 (x86_64/linux)). Content-Length: 0. .
Perfect, it was simplier as look likes when I saw the kamailio.cfg file for the firstime after OpenSER 1.3.2. At the page attachment you can find the working cfg file.