среда, 5 сентября 2012 г.

kamalio+asterisk+realtime mysql


Дружим kamailio и астериск с удаленным mysql server

kamilio в качестве SIP register, sip users хранятся в mysql на удаленном сервере.



на mysql ставим

apt-get install mysql-server
apt-get install libmysqlclient-dev

на aster и kamailio накатываем
apt-get install unixodbc-dev libmyodbc


kamailio собирал из сырцов так
apt-get install bison flex libmysqlclient-dev make gcc
cd /usr/local/src
wget http://www.kamailio.org/pub/kamailio/3.0.1/src/kamailio-3.0.1_src.tar.gz
tar xvfz kamailio-3.0.1_src.tar.gz
cd kamailio-3.0.1
make include_modules="db_mysql" cfg
make all
make install



1) на удаленном mysql настраиваем /etc/mysql/my.cnf
2) рестартуем mysql
service mysql restart


3) настраиваем привилегии
mysql -u root -p
grant all privileges  on *.* to root@'%' identified by 'password' with grant option;
grant all privileges  on *.* to openser@'%' identified by 'openserrw';

4) На kamailio

vim /usr/local/etc/kamailio/kamctlrc

пишем

DBENGINE=MYSQL
DBHOST=xxx.xxx.xxx.xxx
DBNAME=openser
DBRWUSER=openser
DBRWPW="openserrw"

5) Создаем базу на удаленном mysql


на kamailio сервере запускаем
 /usr/local/sbin/kamdbctl create

6) дополняем базу данных данными для астера.

на mysql сервере создаем файл asterisk.sql следующего содержания:

CREATE DATABASE asterisk;

USE asterisk;

GRANT ALL ON asterisk.* TO asterisk@localhost IDENTIFIED BY 'asterisk';
GRANT ALL ON asterisk.* to asterisk@"%" IDENTIFIED BY 'asterisk';

CREATE TABLE `sipusers` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(80) NOT NULL DEFAULT '',
 `host` varchar(31) NOT NULL DEFAULT '',
 `nat` varchar(5) NOT NULL DEFAULT 'no',
 `type` enum('user','peer','friend') NOT NULL DEFAULT 'friend',
 `accountcode` varchar(20) DEFAULT NULL,
 `amaflags` varchar(13) DEFAULT NULL,
 `call-limit` smallint(5) UNSIGNED DEFAULT NULL,
 `callgroup` varchar(10) DEFAULT NULL,
 `callerid` varchar(80) DEFAULT NULL,
 `cancallforward` char(3) DEFAULT 'yes',
 `canreinvite` char(3) DEFAULT 'yes',
 `context` varchar(80) DEFAULT NULL,
 `defaultip` varchar(15) DEFAULT NULL,
 `dtmfmode` varchar(7) DEFAULT NULL,
 `fromuser` varchar(80) DEFAULT NULL,
 `fromdomain` varchar(80) DEFAULT NULL,
 `insecure` varchar(4) DEFAULT NULL,
 `language` char(2) DEFAULT NULL,
 `mailbox` varchar(50) DEFAULT NULL,
 `md5secret` varchar(80) DEFAULT NULL,
 `deny` varchar(95) DEFAULT NULL,
 `permit` varchar(95) DEFAULT NULL,
 `mask` varchar(95) DEFAULT NULL,
 `musiconhold` varchar(100) DEFAULT NULL,
 `pickupgroup` varchar(10) DEFAULT NULL,
 `qualify` char(3) DEFAULT NULL,
 `regexten` varchar(80) DEFAULT NULL,
 `restrictcid` char(3) DEFAULT NULL,
 `rtptimeout` char(3) DEFAULT NULL,
 `rtpholdtimeout` char(3) DEFAULT NULL,
 `secret` varchar(80) DEFAULT NULL,
 `setvar` varchar(100) DEFAULT NULL,
 `disallow` varchar(100) DEFAULT NULL,
 `allow` varchar(100) DEFAULT NULL,
 `fullcontact` varchar(80) NOT NULL DEFAULT '',
 `ipaddr` varchar(15) NOT NULL DEFAULT '',
 `port` mediumint(5) UNSIGNED NOT NULL DEFAULT '0',
 `regserver` varchar(100) DEFAULT NULL,
 `regseconds` int(11) NOT NULL DEFAULT '0',
 `lastms` int(11) NOT NULL DEFAULT '0',
 `username` varchar(80) NOT NULL DEFAULT '',
 `defaultuser` varchar(80) NOT NULL DEFAULT '',
 `subscribecontext` varchar(80) DEFAULT NULL,
 `useragent` varchar(20) DEFAULT NULL,
 `sippasswd` varchar(80) DEFAULT NULL,
 PRIMARY KEY  (`id`),
 UNIQUE KEY `name_uk` (`name`)
);

CREATE TABLE `sipregs` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(80) NOT NULL DEFAULT '',
 `fullcontact` varchar(80) NOT NULL DEFAULT '',
 `ipaddr` varchar(15) NOT NULL DEFAULT '',
 `port` mediumint(5) UNSIGNED NOT NULL DEFAULT '0',
 `username` varchar(80) NOT NULL DEFAULT '',
 `regserver` varchar(100) DEFAULT NULL,
 `regseconds` int(11) NOT NULL DEFAULT '0',
 PRIMARY KEY  (`id`),
 UNIQUE KEY `name` (`name`)
);

CREATE TABLE IF NOT EXISTS `voiceboxes` (
 `uniqueid` int(4) NOT NULL AUTO_INCREMENT,
 `customer_id` varchar(10) DEFAULT NULL,
 `context` varchar(10) NOT NULL,
 `mailbox` varchar(10) NOT NULL,
 `password` varchar(12) NOT NULL,
 `fullname` varchar(150) DEFAULT NULL,
 `email` varchar(50) DEFAULT NULL,
 `pager` varchar(50) DEFAULT NULL,
 `tz` varchar(10) DEFAULT 'central',
 `attach` enum('yes','no') NOT NULL DEFAULT 'yes',
 `saycid` enum('yes','no') NOT NULL DEFAULT 'yes',
 `dialout` varchar(10) DEFAULT NULL,
 `callback` varchar(10) DEFAULT NULL,
 `review` enum('yes','no') NOT NULL DEFAULT 'no',
 `operator` enum('yes','no') NOT NULL DEFAULT 'no',
 `envelope` enum('yes','no') NOT NULL DEFAULT 'no',
 `sayduration` enum('yes','no') NOT NULL DEFAULT 'no',
 `saydurationm` tinyint(4) NOT NULL DEFAULT '1',
 `sendvoicemail` enum('yes','no') NOT NULL DEFAULT 'no',
 `delete` enum('yes','no') NULL DEFAULT 'no',
 `nextaftercmd` enum('yes','no') NOT NULL DEFAULT 'yes',
 `forcename` enum('yes','no') NOT NULL DEFAULT 'no',
 `forcegreetings` enum('yes','no') NOT NULL DEFAULT 'no',
 `hidefromdir` enum('yes','no') NOT NULL DEFAULT 'yes',
 `stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY  (`uniqueid`),
 KEY `mailbox_context` (`mailbox`,`context`)
);

CREATE TABLE `voicemessages` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `msgnum` int(11) NOT NULL DEFAULT '0',
 `dir` varchar(80) DEFAULT '',
 `context` varchar(80) DEFAULT '',
 `macrocontext` varchar(80) DEFAULT '',
 `callerid` varchar(40) DEFAULT '',
 `origtime` varchar(40) DEFAULT '',
 `duration` varchar(20) DEFAULT '',
 `mailboxuser` varchar(80) DEFAULT '',
 `mailboxcontext` varchar(80) DEFAULT '',
 `recording` longblob,
 `flag` varchar(128) DEFAULT '',
 PRIMARY KEY  (`id`),
 KEY `dir` (`dir`)
);


CREATE TABLE version (
    table_name VARCHAR(32) NOT NULL,
    table_version INT UNSIGNED DEFAULT 0 NOT NULL
);
INSERT INTO version (table_name, table_version) VALUES ('sipusers','6');


7) заливаем скрипт командой

 mysql -u root -p <asterisk.sql


проверяем, что создалась база

mysql -u root -p
show databases;


mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| asterisk           |
| mysql              |
| openser            |
| phpmyadmin         |
+--------------------+
5 rows in set (0.01 sec)

8) на kamailio и asterisk настраиваем odbc

UnixODBC Configuration

Edit /etc/odbcinst.ini and add:

[MySQL]
Description = MySQL driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so
CPTimeout =
CPReuse =
UsageCount = 1


Edit /etc/odbc.ini and add:

[MySQL-asterisk]
Description = MySQL Asterisk database
Trace = Off
TraceFile = stderr
Driver = MySQL
SERVER = xxx.xxx.xxx.xxx
USER = asterisk
PASSWORD = asterisk
PORT = 3306
DATABASE = asterisk


На астериске настраиваем:

Asterisk UnixODBC Configuration

Edit /etc/asterisk/res_odbc.conf and set:

[asterisk]
enabled => yes
dsn => MySQL-asterisk
username => asterisk
password => asterisk
pre-connect => yes

Edit /etc/asterisk/extconfig.conf and set:

sipusers => odbc,asterisk,sipusers
sippeers => odbc,asterisk,sipusers
sipregs => odbc,asterisk,sipregs
voicemail => odbc,asterisk,voiceboxes


в /etc/asterisk/modules.conf раскомментариваем:
preload => res_odbc.so
preload => res_config_odbc.so

там же заккоментариваем
;noload => res_config_odbc.so
;noload => res_config_pgsql.so

перезагружаем с cli aster'a модуль

module reload res_odbc.so

также в sip.conf расскомментариваем

 rtcachefriends=yes

это заставляет астериск кэшировать данные . Нужно для того, чтобы работали команды sip show peers и избавляет от части других проблем вызванных динамическим представлением данных


9) Заносим в mysql данные о sip users

use asterisk;

INSERT INTO sipusers (name, username, host, sippasswd, fromuser, fromdomain, mailbox)
  VALUES ('101', '101', 'dynamic', '101', '101', 'yoursip.com', '101');
INSERT INTO sipusers (name, username, host, sippasswd, fromuser, fromdomain, mailbox)
  VALUES ('102', '102', 'dynamic', '102', '102', 'yoursip.com', '102');
INSERT INTO sipusers (name, username, host, sippasswd, fromuser, fromdomain, mailbox)
  VALUES ('103', '103', 'dynamic', '103', '103', 'yoursip.com', '103');

INSERT INTO sipregs(name) VALUES('101');
INSERT INTO sipregs(name) VALUES('102');
INSERT INTO sipregs(name) VALUES('103');

INSERT INTO voiceboxes(customer_id, context, mailbox, password) VALUES ('101', 'default', '101', '1234');
INSERT INTO voiceboxes(customer_id, context, mailbox, password) VALUES ('101', 'default', '102', '1234');
INSERT INTO voiceboxes(customer_id, context, mailbox, password) VALUES ('101', 'default', '103', '1234');

10) заливаем конфиг kamailio. меняем localhost на ip удаленного mysql и правим логин/пароли


#!KAMAILIO
 
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB
#!define WITH_ASTERISK
 
#
# $Id$
#
# Kamailio (OpenSER) SIP Server v3.0 - basic configuration script
#     - web: http://www.kamailio.org
#     - git: http://sip-router.org
#
# Direct your questions about this file to: <users@lists.kamailio.org>
#
# Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
# for an explanation of possible statements, functions and parameters.
#
# Several features can be enabled using '#!define WITH_FEATURE' directives:
#
# *** To run in debug mode: 
#     - define WITH_DEBUG
#
# *** To enable mysql: 
#     - define WITH_MYSQL
#
# *** To enable authentication execute:
#     - enable mysql
#     - define WITH_AUTH
#     - add users using 'kamctl'
#
# *** To enable persistent user location execute:
#     - enable mysql
#     - define WITH_USRLOCDB
#
# *** To enable presence server execute:
#     - enable mysql
#     - define WITH_PRESENCE
#
# *** To enable nat traversal execute:
#     - define WITH_NAT
#     - install RTPProxy: http://www.rtpproxy.org
#     - start RTPProxy:
#        rtpproxy -l _your_public_ip_ -s udp:localhost:7722
#
# *** To enable PSTN gateway routing execute:
#     - define WITH_PSTN
#     - set the value of pstn.gw_ip
#     - check route[PSTN] for regexp routing condition
#
# *** To enhance accounting execute:
#     - enable mysql
#     - define WITH_ACCDB
#     - add following columns to database
#!ifdef ACCDB_COMMENT
  ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
  ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
  ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
  ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
  ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
#!endif
 
 
####### Global Parameters #########
 
#!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
 
/* uncomment the next line to disable TCP (default on) */
#disable_tcp=yes
 
/* uncomment the next line to disable the auto discovery of local aliases
   based on revers DNS on IPs (default on) */
#auto_aliases=no
 
 
/* uncomment and configure the following line if you want Kamailio to 
   bind on a specific interface/port/proto (default bind on all available) */
#listen=udp:10.0.0.10:5060
 
listen=udp:192.168.178.23
port=5060
 
####### Custom Parameters #########
 
# These parameters can be modified runtime via RPC interface
# - see the documentation of 'cfg_rpc' module.
#
# Format: group.id = value 'desc' description
# Access: $sel(cfg_get.group.id) or @cfg_get.group.id
#
 
#!ifdef WITH_PSTN
# PSTN GW Routing
#
# - pstn.gw_ip: valid IP or hostname as string value, example:
# pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
#
# - by default is empty to avoid misrouting
pstn.gw_ip = "" desc "PSTN GW Address"
#!endif
 
#!ifdef WITH_ASTERISK
asterisk.bindip = "192.168.178.23" desc "Asterisk IP Address"
asterisk.bindport = "5080" desc "Asterisk Port"
kamailio.bindip = "192.168.178.23" desc "Kamailio IP Address"
kamailio.bindport = "5060" desc "Kamailio Port"
#!endif
 
####### Modules Section ########
 
#set module path
# mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
mpath="modules_k/:modules/"
 
/* uncomment next line for MySQL DB support */
#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif
loadmodule "mi_fifo.so"
loadmodule "kex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "uri_db.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "mi_rpc.so"
loadmodule "acc.so"
#!ifdef WITH_AUTH
loadmodule "auth.so"
loadmodule "auth_db.so"
#!endif
/* uncomment next line for aliases support
   NOTE: a DB (like db_mysql) module must be also loaded */
#loadmodule "alias_db.so"
/* uncomment next line for multi-domain support
   NOTE: a DB (like db_mysql) module must be also loaded
   NOTE: be sure and enable multi-domain support in all used modules
         (see "multi-module params" section ) */
#loadmodule "domain.so"
#!ifdef WITH_PRESENCE
loadmodule "presence.so"
loadmodule "presence_xml.so"
#!endif
 
#!ifdef WITH_NAT
loadmodule "nathelper.so"
#!endif
 
#!ifdef WITH_ASTERISK
loadmodule "uac.so"
#!endif
 
# ----------------- setting module-specific parameters ---------------
 
 
# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
 
 
# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
#!ifdef WITH_ASTERISK
modparam("rr", "append_fromtag", 1)
#!else
modparam("rr", "append_fromtag", 0)
#!endif
 
 
# ----- rr params -----
modparam("registrar", "method_filtering", 1)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
 
 
# ----- uri_db params -----
/* by default we disable the DB support in the module as we do not need it
   in this configuration */
modparam("uri_db", "use_uri_table", 0)
modparam("uri_db", "db_url", "")
 
 
# ----- acc params -----
/* what sepcial events should be accounted ? */
modparam("acc", "early_media", 1)
modparam("acc", "report_ack", 1)
modparam("acc", "report_cancels", 1)
/* by default ww 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)
/* account triggers (flags) */
modparam("acc", "failed_transaction_flag", 3)
modparam("acc", "log_flag", 1)
modparam("acc", "log_missed_flag", 2)
modparam("acc", "log_extra", 
 "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
/* enhanced DB accounting */
#!ifdef WITH_ACCDB
modparam("acc", "db_flag", 1)
modparam("acc", "db_missed_flag", 2)
modparam("acc", "db_url",
 "mysql://openser:openserrw@localhost/openser")
modparam("acc", "db_extra",
 "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
#!endif
 
# ----- usrloc params -----
/* enable DB persistency for location entries */
#!ifdef WITH_USRLOCDB
modparam("usrloc", "db_mode",   2)
modparam("usrloc", "db_url",
 "mysql://openser:openserrw@localhost/openser")
#!endif
 
# ----- auth_db params -----
/* enable the DB based authentication */
#!ifdef WITH_AUTH
modparam("auth_db", "calculate_ha1", yes)
#!ifdef WITH_ASTERISK
modparam("auth_db", "user_column", "username")
modparam("auth_db", "password_column", "sippasswd")
modparam("auth_db", "db_url",
 "mysql://asterisk:asterisk_password@localhost/asterisk")
#!else
modparam("auth_db", "password_column", "password")
modparam("auth_db", "db_url",
 "mysql://openser:openserrw@localhost/openser")
#!endif
modparam("auth_db", "load_credentials", "")
#!endif
 
# ----- alias_db params -----
/* uncomment the following lines if you want to enable the DB based
   aliases */
#modparam("alias_db", "db_url",
# "mysql://openser:openserrw@localhost/openser")
 
 
# ----- domain params -----
/* uncomment the following lines to enable multi-domain detection
   support */
#modparam("domain", "db_url",
# "mysql://openser:openserrw@localhost/openser")
#modparam("domain", "db_mode", 1)   # Use caching
 
 
# ----- multi-module params -----
/* uncomment the following line if you want to enable multi-domain support
   in the modules (dafault off) */
#modparam("alias_db|auth_db|usrloc|uri_db", "use_domain", 1)
 
 
# ----- presence params -----
/* enable presence server support */
#!ifdef WITH_PRESENCE
modparam("presence|presence_xml", "db_url",
 "mysql://openser:openserrw@localhost/openser")
modparam("presence_xml", "force_active", 1)
modparam("presence", "server_address", "sip:10.0.0.10:5060")
#!endif
 
# ----- nathelper -----
#!ifdef WITH_NAT
modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:7722")
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 7)
modparam("nathelper", "sipping_from", "sip:pinger@kamailio.org")
modparam("registrar|nathelper", "received_avp", "$avp(i:80)")
modparam("usrloc", "nat_bflag", 6)
#!endif
 
 
####### Routing Logic ########
 
 
# main request routing logic
 
route{
 
 if (!mf_process_maxfwd_header("10")) {
  sl_send_reply("483","Too Many Hops");
  exit;
 }
 
 if(!sanity_check("1511", "7"))
 {
  xlog("Malformed SIP message from $si:$sp\n");
  exit;
 }
 
 # NAT detection
 route(NAT);
 
 if (has_totag()) {
  # sequential request withing a dialog should
  # take the path determined by record-routing
  if (loose_route()) {
   if (is_method("BYE")) {
    setflag(1); # do accounting ...
    setflag(3); # ... even if the transaction fails
   }
   route(RELAY);
  } else {
   if (is_method("SUBSCRIBE") && uri == myself) {
    # in-dialog subscribe requests
    route(PRESENCE);
    exit;
   }
   if ( is_method("ACK") ) {
    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.\n");
     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();
 
 # authentication
 route(AUTH);
 
 # record routing for dialog forming requests (in case they are routed)
 # - remove preloaded route headers
 remove_hf("Route");
 if (is_method("INVITE|SUBSCRIBE"))
  record_route();
 
 # account only INVITEs
 if (is_method("INVITE")) {
  setflag(1); # do accounting
 }
 if (!uri==myself)
 /* replace with following line if multi-domain support is used */
 ##if (!is_uri_host_local())
 {
  append_hf("P-hint: outbound\r\n"); 
  route(RELAY);
 }
 
 # requests for my domain
 
 if( is_method("PUBLISH|SUBSCRIBE"))
  route(PRESENCE);
 
 if (is_method("REGISTER"))
 {
  if(isflagset(5))
  {
   setbflag("6");
   # uncomment next line to do SIP NAT pinging 
   ## setbflag("7");
  }
  if (!save("location"))
   sl_reply_error();
 
#!ifdef WITH_ASTERISK
  route(REGFWD);
#!endif
  exit;
 }
 
 if ($rU==$null) {
  # request with no Username in RURI
  sl_send_reply("484","Address Incomplete");
  exit;
 }
 
 route(PSTN);
 
 # apply DB based aliases (uncomment to enable)
 ##alias_db_lookup("dbaliases");
 
#!ifdef WITH_ASTERISK
 if(!is_method("INVITE")) {
  # non-INVITE request are routed directly by Kamailio
#!endif
 if (!lookup("location")) {
  switch ($rc) {
   case -1:
   case -3:
    t_newtran();
    t_reply("404", "Not Found");
    exit;
   case -2:
    sl_send_reply("405", "Method Not Allowed");
    exit;
  }
 }
#!ifdef WITH_ASTERISK
 } /* end non-INVITE test */
 # only INVITE from now on
 if(route(FROMASTERISK))
 {
  # coming from Asterisk - do location lookup
  if (!lookup("location")) {
   switch ($rc) {
    case -1:
    case -3:
     t_newtran();
     t_reply("404", "Not Found");
     exit;
    case -2:
     sl_send_reply("405", "Method Not Allowed");
     exit;
   }
  }
 } else {
  # new call - send to Asterisk
  route(TOASTERISK);
 }
#!endif
 
 # when routing via usrloc, log the missed calls also
 setflag(2);
 
 route(RELAY);
}
 
 
route[RELAY] {
#!ifdef WITH_NAT
 if (check_route_param("nat=yes")) {
  setbflag("6");
 }
 if (isflagset(5) || isbflagset("6")) {
  route(RTPPROXY);
 }
#!endif
 
 /* example how to enable some additional event routes */
 if (is_method("INVITE")) {
  #t_on_branch("BRANCH_ONE");
  t_on_reply("REPLY_ONE");
  t_on_failure("FAIL_ONE");
 }
 
 if (!t_relay()) {
  sl_reply_error();
 }
 exit;
}
 
 
# Presence server route
route[PRESENCE]
{
#!ifdef WITH_PRESENCE
 if (!t_newtran())
 {
  sl_reply_error();
  exit;
 };
 
 if(is_method("PUBLISH"))
 {
  handle_publish();
  t_release();
 }
 else
 if( is_method("SUBSCRIBE"))
 {
  handle_subscribe();
  t_release();
 }
 exit;
#!endif
 
 # if presence enabled, this part will not be executed
 if (is_method("PUBLISH") || $rU==$null)
 {
  sl_send_reply("404", "Not here");
  exit;
 }
 return;
}
 
# Authentication route
route[AUTH] {
#!ifdef WITH_AUTH
 
#!ifdef WITH_ASTERISK
 # do not auth traffic from Asterisk - trusted!
 if(route(FROMASTERISK))
  return;
#!endif
 
 if (is_method("REGISTER"))
 {
  # authenticate the REGISTER requests (uncomment to enable auth)
#!ifdef WITH_ASTERISK
  if (!www_authorize("", "sipusers"))
#!else
  if (!www_authorize("", "subscriber"))
#!endif
  {
   www_challenge("", "0");
   exit;
  }
 
  if ($au!=$tU)
  {
   sl_send_reply("403","Forbidden auth ID");
   exit;
  }
 } else {
  # authenticate if from local subscriber (uncomment to enable auth)
  if (from_uri==myself)
  {
#!ifdef WITH_ASTERISK
   if (!proxy_authorize("", "sipusers")) {
#!else
   if (!proxy_authorize("", "subscriber")) {
#!endif
    proxy_challenge("", "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
  }
 }
#!endif
 return;
}
 
# Caller NAT detection route
route[NAT]{
#!ifdef WITH_NAT
 force_rport();
 if (nat_uac_test("19")) {
  if (method=="REGISTER") {
   fix_nated_register();
  } else {
   fix_nated_contact();
  }
  setflag(5);
 }
#!endif
 return;
}
 
# RTPProxy control
route[RTPPROXY] {
#!ifdef WITH_NAT
 if (is_method("BYE")) {
  unforce_rtp_proxy();
 } else if (is_method("INVITE")){
  force_rtp_proxy();
 }
 if (!has_totag()) add_rr_param(";nat=yes");
#!endif
 return;
}
 
# PSTN GW routing
route[PSTN] {
#!ifdef WITH_PSTN
 # check if PSTN GW IP is defined
 if (strempty($sel(cfg_get.pstn.gw_ip))) {
  xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n");
  return;
 }
 
 # route to PSTN dialed numbers starting with '+' or '00'
 #     (international format)
 # - update the condition to match your dialing rules for PSTN routing
 if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
  return;
 
 # only local users allowed to call
 if(from_uri!=myself) {
  sl_send_reply("403", "Not Allowed");
  exit;
 }
 
 $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
 
 route(RELAY);
 exit;
#!endif
 
 return;
}
 
#!ifdef WITH_ASTERISK
# Test if coming from Asterisk
route[FROMASTERISK] {
 if($si==$sel(cfg_get.asterisk.bindip)
   && $sp==$sel(cfg_get.asterisk.bindport))
  return 1;
 return -1;
}
 
# Send to Asterisk
route[TOASTERISK] {
 $du = "sip:" + $sel(cfg_get.asterisk.bindip) + ":"
   + $sel(cfg_get.asterisk.bindport);
 route(RELAY);
 exit;
}
 
# Forward REGISTER to Asterisk
route[REGFWD] {
 if(!is_method("REGISTER"))
 {
  return;
 }
 $var(rip) = $sel(cfg_get.asterisk.bindip);
 $uac_req(method)="REGISTER";
 $uac_req(ruri)="sip:" + $var(rip) + ":" + $sel(cfg_get.asterisk.bindport);
 $uac_req(furi)="sip:" + $au + "@" + $var(rip);
 $uac_req(turi)="sip:" + $au + "@" + $var(rip);
 $uac_req(hdrs)="Contact: <sip:" + $au + "@"
    + $sel(cfg_get.kamailio.bindip)
    + ":" + $sel(cfg_get.kamailio.bindport) + ">\r\n";
 if($sel(contact.expires) != $null)
  $uac_req(hdrs)= $uac_req(hdrs) + "Expires: " + $sel(contact.expires) + "\r\n";
 else
  $uac_req(hdrs)= $uac_req(hdrs) + "Expires: " + $hdr(Expires) + "\r\n";
 uac_req_send();
}
 
#!endif
 
# Sample branch router
branch_route[BRANCH_ONE] {
 xdbg("new branch at $ru\n");
}
 
# Sample onreply route
onreply_route[REPLY_ONE] {
 xdbg("incoming reply\n");
#!ifdef WITH_NAT
 if ((isflagset(5) || isbflagset("6")) && status=~"(183)|(2[0-9][0-9])") {
  force_rtp_proxy();
 }
 if (isbflagset("6")) {
  fix_nated_contact();
 }
#!endif
}
 
# Sample failure route
failure_route[FAIL_ONE] {
#!ifdef WITH_NAT
 if (is_method("INVITE")
   && (isbflagset("6") || isflagset(5))) {
  unforce_rtp_proxy();
 }
#!endif
 
 if (t_is_canceled()) {
  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;
 ##}
 
 # uncomment the following lines if you want to redirect the failed 
 # calls to a different new destination
 ##if (t_check_status("486|408")) {
 ## sethostport("192.168.2.100:5060");
 ## append_branch();
 ## # do not set the missed call flag again
 ## t_relay();
 ##}
}

11) Стоит проверить, что данные в конфиге kamailio раздела

#!ifdef WITH_ASTERISK
asterisk.bindip = "192.168.178.23" desc "Asterisk IP Address"
asterisk.bindport = "5080" desc "Asterisk Port"

совпадают с настройками sip.conf астериска.

12)  Теперь можно логинится sip клиентом хоть на kamailio, хоть на asterisk.

13) Правим диалпланы и конфиги kamailio и asterisk под свои задачи