1. OpenSIPS - Open SIP Server

OpenSIPS (www.opensips.org) เป็น open source SIP server ที่พัฒนาต่อเนื่องมาจาก SER project ->

OpenSER project จึงมีความเสถียรและมี features ที่ค่อนข้างสมบูรณ์ (แต่การใช้งานไม่ได้ง่ายสำหรับ user

ทั่วไป) OpenSIPS มี features หลักๆ ดังนี้

  • SIP registrar server
  • SIP router / proxy (lcr, dynamic routing, dialplan features)
  • SIP redirect server
  • SIP presence agent
  • SIP back-to-back User Agent
  • SIP IM server (chat and end-2-end IM)
  • SIP load-balancer or dispatcher
  • SIP front end for gateways/asterisk

บทความของเราในตอนนี้จะเป็นการติดตั้ง OpenSIPS 1.8.5 บน Debian 7.6 หลังจากนั้นบทความใน

ตอนต่อๆ ไป จะกล่าวถึง OpenSIPS GUI, การใช้งานในลักษณะ SIP trunking และ VoIP Service Platform

 

2. ติดตั้ง OpenSIPS

ขั้นแแรกติดตั้ง Debian 7.6 เลือก options - web server, ssh server, standard system utilities

หลังจากติดตั้ง OS เสร็จ ให้ login ด้วย root แล้ว run คำสั่ง ดังนี้

#cd /usr/src

#apt-get install gcc make bison flex make openssl libncurses5-dev

#apt-get install libmysqlclient-dev libradiusclient-ng2 libradiusclient-ng-dev

#apt-get install mysql-server libxmlrpc-c3-dev libdbi-perl libdbd-mysql-perl

#apt-get install libfrontier-rpc-perl libterm-readline-gnu-perl libpcre3-dev  

#wget http://opensips.org/pub/opensips/1.8.5/src/opensips-1.8.5_src.tar.gz

#tar zxvf opensips-1.8.5_src.tar.gz

#cd opensips-1.8.5-tls

#make prefix=/usr/local all include_modules="db_mysql aaa_radius dialplan"

#make prefix=/usr/local install include_modules="db_mysql aaa_radius dialplan"

#mkdir -p /var/run/opensips

#cd packaging/debian

#cp opensips.default /etc/default/opensips

#cp opensips.init /etc/init.d/opensips

#chmod 755 /etc/init.d/opensips

#insserv opensips

#useradd opensips

 

3. คอนฟิก OpenSIPS

คอนฟิก log file

#touch /var/log/opensips.log

แก้ไข file /etc/rsyslog.conf โดยการเพิ่มบรรทัดต่อไปนี้เข้าไป

local0.*          -/var/log/opensips.log

 

แก้ไข file /etc/default/opensips

RUN_OPENSIPS=yes

MEMORY=128

แก้ไข file /etc/init.d/opensips

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin

DAEMON=/usr/local/sbin/opensips

ระบุ config file = /usr/local/etc/opensips/opensips.conf

 

แก้ไข file /usr/local/etc/opensips/opensipsctlrc

SIP_DOMAIN=192.168.1.250 ### เป็น ip address ของ server

DBENGINE=MYSQL

DBHOST=localhost

DBNAME=opensips

DBRWUSER=opensips

DBRWPW=”opensipsrw”

ALIASES_TYPE=”DB”

OSIPS_FIFO=”/tmp/opensips_proxy_fifo”

 

สร้าง  database โดยการ run คำสั่ง

#/usr/local/sbin/opensipsdbctl create

ถ้าไม่มีอะไรผิดพลาดก็ทำขั้นต่อไป

แก้ไข file /usr/local/etc/opensips/opensips.cfg

ให้ได้ตามนี้

####### Global Parameters #######

debug=6

log_stderror=no

log_facility=LOG_LOCAL0

fork=yes

children=4

/* uncomment the following lines to enable debugging */

#debug=6

#fork=no

#log_stderror=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.250:5060   # CUSTOMIZE ME

disable_tcp=yes

disable_tls=yes

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

#set module path

mpath="/usr/local/lib64/opensips/modules/"

#### SIGNALING module

loadmodule "signaling.so"

#### StateLess module

loadmodule "sl.so"

#### Transaction Module

loadmodule "tm.so"

modparam("tm", "fr_timer", 5)

modparam("tm", "fr_inv_timer", 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"

#### SIP MSG OPerationS module

loadmodule "sipmsgops.so"

#### FIFO Management Interface

loadmodule "mi_fifo.so"

modparam("mi_fifo", "fifo_name", "/tmp/opensips_proxy_fifo")

modparam("mi_fifo", "fifo_mode", 0666)

#### URI module

loadmodule "uri.so"

modparam("uri", "use_uri_table", 0)

#### USeR LOCation module

loadmodule "usrloc.so"

modparam("usrloc", "nat_bflag", 10)

modparam("usrloc", "db_mode",   0)

#### REGISTRAR module

loadmodule "registrar.so"

modparam("registrar", "tcp_persistent_flag", 7)

/* uncomment the next line not to allow more than 10 contacts per AOR */

#modparam("registrar", "max_contacts", 10)

#### ACCounting module

loadmodule "acc.so"

/* 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", "failed_transaction_flag", 3)

/* account triggers (flags) */

modparam("acc", "log_flag", 1)

modparam("acc", "log_missed_flag", 2)

### Authenticated by MySQL ###

loadmodule "db_mysql.so"

loadmodule "auth.so"

loadmodule "auth_db.so"

modparam("usrloc", "db_mode", 2)

modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")

modparam("auth_db", "calculate_ha1", yes)

modparam("auth_db", "password_column", "password")

modparam("auth_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")

modparam("auth_db", "load_credentials", "")

### End Authentivated by MySQL ###

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

### main request routing logic ###

route {

if (!mf_process_maxfwd_header("10")) {

sl_send_reply("483","Too Many Hops");

exit;

}

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

} else if (is_method("INVITE")) {

# 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();

}

# route it out to whatever destination was set by loose_route()

# in $du (destination URI).

route(1);

} else {

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

exit;

}

}

sl_send_reply("404","Not here");

}

exit;

}

# CANCEL processing

if (is_method("CANCEL"))

{

if (t_check_trans())

t_relay();

exit;

}

t_check_trans();

if ( !(is_method("REGISTER")  ) ) {

if (from_uri==myself)

{

### Authenticated by MySQL ###

if(!proxy_authorize("", "subscriber")) {

proxy_challenge("", "0");

exit;

}

if (!db_check_from()) {

sl_send_reply("403", "Forbidden auth ID");

exit;

}

consume_credentials();

# caller authenticated

 

### End Autheticated by MySQL ###

} else {

# if caller is not local, then called number must be local

if (!uri==myself) {

send_reply("403","Rely forbidden");

exit;

}

}

}

# preloaded route checking

if (loose_route()) {

xlog("L_ERR",

"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");

if (!is_method("ACK"))

sl_send_reply("403","Preload Route denied");

exit;

}

# record routing

if (!is_method("REGISTER|MESSAGE"))

record_route();

# account only INVITEs

if (is_method("INVITE")) {

setflag(1); # do accounting

}

if (!uri==myself) {

append_hf("P-hint: outbound\r\n");

route(1);

}

# requests for my domain

if (is_method("PUBLISH|SUBSCRIBE"))

{

sl_send_reply("503", "Service Unavailable");

exit;

}

if (is_method("REGISTER"))

{

### Authenticated by MySQL ###

if (!www_authorize("", "subscriber")) {

www_challenge("", "0");

exit;

}

if (!db_check_to()) {

sl_send_reply("403", "Forbidden auth ID");

exit;

}

### End Authenticate by MySQL ###

if (   0 ) setflag(7);

if (!save("location"))

sl_reply_error();

exit;

}

if ($rU==NULL) {

# request with no Username in RURI

sl_send_reply("484","Address Incomplete");

exit;

}

# do lookup with method filtering

if (!lookup("location","m")) {

t_newtran();

t_reply("404", "Not Found");

exit;

}

# when routing via usrloc, log the missed calls also

setflag(2);

route(1);

}

route[1] {

# for INVITEs enable some additional helper routes

if (is_method("INVITE")) {

t_on_branch("2");

t_on_reply("2");

t_on_failure("1");

}

if (!t_relay()) {

send_reply("500","Internal Error");

};

exit;

}

branch_route[2] {

xlog("new branch at $ru\n");

}

onreply_route[2] {

xlog("incoming reply\n");

}

failure_route[1] {

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;

##}

}

 

4. Start OpenSIPS

#/etc/init.d/opensips start

add users

#opensipsctl add 1000 1000     ### user = 1000 password = 1000

#opensipsctl add 1001 1001

 

5. ทดสอบการใช้งาน

ใช้ ip phone หรือ soft phone 2 ตัว register มาที่ OpenSIPS server โดยใช้ user 1000 password 1000 และ

user 1001 password 1001 เมื่อ register เรียบร้อย ลองโทรหากัน ถ้าโทรหากันได้

ก็ถือว่าการติดตั้งคอนฟิกในเบื้องต้นเสร็จเรียบร้อยแล้ว