1. 安装依赖软件:
a) Yum update //更新系统到最新
b) 安装以下所需依赖软件
gcc
bison
flex
make
openssl
libmysqlclient-dev
mysql-server
c) 安装radiusclient:
1. wget http://pkgs.repoforge.org/radiusclient-ng/radiusclient-ng-0.5.6-5.el6.rf.x86_64.rpm
2. rpm -ivfradiusclient-ng-0.5.6-5.el6.rf.x86_64.rpm
3. wget http://pkgs.repoforge.org/radiusclient-ng/radiusclient-ng-devel-0.5.6-5.el6.rf.x86_64.rpm
4. rpm -ivfradiusclient-ng-devel-0.5.6-5.el6.rf.x86_64.rpm
5. wget http://pkgs.repoforge.org/radiusclient-ng/radiusclient-ng-utils-0.5.6-5.el6.rf.x86_64.rpm
6. rpm -ivfradiusclient-ng-utils-0.5.6-5.el6.rf.x86_64.rpm
d) 安装xmlrpc3-
yum –y install *xmlrpc3*
e) 安装perl:
1. yum install *perl*MySQL*
2. yum install *perl*Front*
3. yum install *perl*Read*
f) 安装start-stop-daemon
1. wget http://developer.axis.com/download/distribution/apps-sys-utils-start-stop-daemon-IR1_9_18-2.tar.gz
2. tar zxf apps-sys-utils-start-stop-daemon-IR1_9_18-2.tar.gz
3. mvapps/sys-utils/start-stop-daemon-IR1_9_18-2/ ./
4. rm -rf apps
5. cdstart-stop-daemon-IR1_9_18-2/
6. cc start-stop-daemon.c -ostart-stop-daemon
7. cp start-stop-daemon /usr/bin/start-stop-daemon
2. 安装opensips
a) cd /usr/src
b) 下载opensips源码:
wget http://opensips.org/pub/opensips/1.6.0/src/opensips-1.6.0-tls_src.tar.gz
c) 解压缩源码:
tar -xf opensips-1.6.0-tls_src.tar.gz
d) cd opensips-1.6.0-tls
e) 编译并安装:
make prefix=/ all include_modules="db_mysql aaa_radius"
make prefix=/ install include_modules="db_mysql aaa_radius"
f) 创建运行目录
mkdir /var/run/opensips
3. 配置系统运行环境
a) 添加opensips运行文件到linux启动项
i. cd/usr/src/opensips-1.6.0-tls/packaging/debian
ii. cp opensips.default/etc/default/opensips
iii. cp opensips.init /etc/init.d/opensips
b) 修改/etc/opensips/opensips.cfg
i. vim /etc/opensips/opensips.cfg
ii. 删掉fork=no行,即便有注释也删掉
c) 赋予opensips.init文件正确权限
i. cd /etc/init.d
ii. chmod 755 opensips
d) 编辑/etc/default/opensips
i. vim /etc/default/opensips
ii. 修改如下(红色字体):
# Set to yes to enable opensips, once configured properly.
RUN_OPENSIPS=yes
# User to run as
USER=root
# Group to run as
GROUP=root
# Amount of memory to allocate for the running OpenSIPS server (in Mb)
MEMORY=128
e) 编辑/etc/init.d/opensips,配置正确的opensips路径
i. vim /etc/init.d/opensips
ii. 修改如下(红色字体)
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/sbin/opensips
NAME=opensips
DESC=opensips
HOMEDIR=/var/run/opensips
PIDFILE=$HOMEDIR/$NAME.pid
4. 独立Log文件
a) 修改/etc/rsyslog.conf
i. vim /etc/rsyslog.conf
ii. 在文件最后添加一条:
local0.* /var/log/opensips.log
b) 重启rsyslog服务:
service rsyslog restart
5. 启动opensips
a) 启动opensips服务:
/etc/init.d/opensips start|stop|restart
6. 配置mysql认证支持
a) 确认db_mysql.so正常存在
ls /lib/opensips/modules/db_mysql.so
b) 修改/etc/opensips/opensipsctlrc文件,去掉如下内容的注释:
SIp_DoMAIN=115.28.38.216
DBENGINE=MYSQL
DBHoST=localhost
DBNAME=opensips
DBRWUSER=opensips
DBRWpW="opensipsrw"
DBRoUSER=opensipsro
DBRopW=opensipsro
ALIASES_TYPE="DB"
oSIpS_FIFo="/tmp/opensips_fifo"
c) 创建opensips的数据库
opensipsdbctl create
输入如下(注意红色字,一律选y):
Opensips:~# opensipsdbctl create
MySqL password for root:
INFO: test server charset
INFO: creating database opensips ...
INFO: Core Opensips tables successfully created.
Install presence related tables?(y/n): y
INFO: creatingpresence tables into opensips ...
INFO: Presence tables successfully created.
Install tables for imc cpl siptracedomainpolicy carrierroute? (y/n): y
d) 编辑/etc/opensips/opensips.cfg
修改如下(去掉如下代码的注释)
#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", "")
##if (!(method=="REGISTER") && from_uri==myself) /*nomultidomain version*/
##{
## if (!proxy_authorize("", "subscriber")) {
## proxy_challenge("", "0");
## exit;
## }
## if (!db_check_from()) {
## sl_send_reply("403","Forbidden auth ID");
## exit;
## }
##
## consume_credentials();
## # caller authenticated
##}
#authenticate the REGISTER requests
(uncomment to enable auth)
##if (!www_authorize("", "subscriber"))
##{
## www_challenge("", "0");
## exit;
##}
##
##if (!db_check_to())
##{
## sl_send_reply("403","Forbidden auth ID");
## exit;
##}
e) 重启opensips服务
/etc/init.d/opensips restart
f) 添加两个用户
opensipsctl add 1000 1000
opensipsctl add 1001 1001
g) 客户端可进行登录验证
7. 配置RTPProxy处理NAT
a) 下载并安装RTPProxy
1. cd /usr/src
2. wgethttp://b2bua.org/chrome/site/rtpproxy-1.2.0.tar.gz
3. tar –xzvf rtpproxy-1.2.0.tar.gz
4. cd rtpproxy-1.2.0
5. ./configure
6. make
7. make install
b) 运行RTPProxy
rtpproxy -l 115.28.38.216 -a 10.144.59.80 -s udp:localhost:7890 -F -d INFOLOG_LOCAL1
c) 修改/etc/opensips/opensips.cfg文件
修改如下:
在#loadmodule "presence_xml.so"下面添加
loadmodule "nathelper.so"
在” #modparam("presence", "server_address","sip:192.168.1.2:5060")”下面添加:
modparam("nathelper","rtpproxy_sock", "udp:127.0.0.1:7890")
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 0)
modparam("nathelper", "sipping_bflag", 7)
modparam("nathelper", "sipping_from","sip:[email protected]")
modparam("registrar","received_avp","$avp(i:42)")
modparam("nathelper","received_avp","$avp(i:42)")
在# main request routing logic下面的代码中添加如下红色字:
# main request routing logic
route{
if(!mf_process_maxfwd_header("10")) {
sl_send_reply("483","TooMany Hops");
exit;
}
#---- NAT Detection ----#
force_rport();
if (nat_uac_test("18")) {
if (is_method("REGISTER")) {
fix_nated_register();
}
else {
fix_nated_contact();
}
setflag(5);
}
if (has_totag()) {
# sequentialrequest withing a dialog should
# take thepath 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 {
/*uncomment the following lines if you want to enable presence */
##if(is_method("SUBSCRIBE") && $rd =="your.server.ip.address") {
## # in-dialog subscribe requests
## route(2);
## 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
exit;
}
}
sl_send_reply("404","Nothere");
}
exit;
}
#initial requests
# CANCEL processing
if(is_method("CANCEL"))
{
if(t_check_trans())
t_relay();
exit;
}
t_check_trans();
# authenticate if fromlocal subscriber (uncomment to enable auth)
# authenticate allinitial non-REGISTER request that pretend to be
# generated by localsubscriber (domain from FROM URI is local)
#if(!(method=="REGISTER") && from_uri==myself) /*no multidomainversion*/
##if(!(method=="REGISTER") && is_from_local()) /*multidomain version*/
#{
# if (!proxy_authorize("","subscriber")) {
# proxy_challenge("","0");
# exit;
# }
# if (!db_check_from()) {
# sl_send_reply("403","Forbiddenauth ID");
# exit;
# }
#
# consume_credentials();
# # caller authenticated
#}
# preloaded routechecking
if (loose_route()) {
xlog("L_ERR",
"Attemptto route with preloaded Route's [$fu/$tu/$ru/$ci]");
if(!is_method("ACK"))
sl_send_reply("403","PreloadRoute 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)
## replace withfollowing line if multi-domain support is used
##if(!is_uri_host_local())
{
append_hf("P-hint:outbound\r\n");
# if youhave some interdomain connections via TLS
##if($rd=="tls_domain1.net"){
## t_relay("tls:domain1.net");
## exit;
##} elseif($rd=="tls_domain2.net") {
## t_relay("tls:domain2.net");
## exit;
##}
route(1);
}
# requests for mydomain
## uncomment this ifyou want to enable presence server
## and comment the next 'if' block
## NOTE: uncomment also the definition ofroute[2] from below
##if( is_method("PUBLISH|SUBSCRIBE"))
## route(2);
if(is_method("PUBLISH"))
{
sl_send_reply("503","Service Unavailable");
exit;
}
if(is_method("REGISTER"))
{
#authenticate the REGISTER requests (uncomment to enable auth)
if(!www_authorize("", "subscriber"))
{
www_challenge("","0");
exit;
}
if(!db_check_to())
{
sl_send_reply("403","Forbiddenauth ID");
exit;
}
#--Request is behind NAT(flag5) save with bflag 6 -#
#----Use bflag 7 to start SIP pinging (Options) ---#
if(isflagset(5)) {
setbflag(6);
setbflag(7);
};
if(!save("location"))
sl_reply_error();
exit;
}
if ($rU==NULL) {
# requestwith no Username in RURI
sl_send_reply("484","AddressIncomplete");
exit;
}
# apply DB basedaliases (uncomment to enable)
##alias_db_lookup("dbaliases");
# do lookup withmethod filtering
if(!lookup("location","m")) {
switch($retcode) {
case-1:
case-3:
t_newtran();
t_reply("404","Not Found");
exit;
case -2:
sl_send_reply("405","Method Not Allowed");
exit;
}
}
# when routing viausrloc, log the missed calls also
setflag(2);
route(1);
}
route[1] {
# for INVITEs enablesome additional helper routes
#---- Helper route, if nat=yes in the R-URI setflag 6 ----#
#---- This is used to Process REINVITES ----#
if (subst_uri('/(sip:.*);nat=yes/\1/')){
setbflag(6);
};
#-- If caller(flag 5) or callee(flag 6) are behindNAT --#
#-- Call the route(6) to force the use of the RTPProxy --#
if (isflagset(5)||isbflagset(6)) {
route(6);
};
if (isflagset(5)){
search_append('Contact:.*sip:[^>[:cntrl:]]*',';nat=yes');
}
if(is_method("INVITE")) {
t_on_branch("2");
t_on_reply("2");
t_on_failure("1");
}
if (!t_relay()) {
sl_reply_error();
};
exit;
}
# Presence route
/* uncomment the whole following route for enabling presence
NOTE: do not forget toenable the call of this route from the main
route */
##route[2]
##{
## 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;
##}
route[6] {
#---- RTP Proxy handling ---#
if (is_method("BYE|CANCEL")) {
unforce_rtp_proxy();
}
else if (is_method("INVITE")){
#---- Activates the RTP Proxy for the CALLEE ---#
force_rtp_proxy();
t_on_failure("1");
};
}
branch_route[2] {
xlog("new branchat $ru\n");
}
onreply_route[2] {
xlog("incomingreply\n");
#---- Handling of the SDP for the 200 or 183 reply----#
#---- If behind nat (flags 5 or 6) start RTP Proxy----#
#---- Activates the RTP Proxy for the CALLER ----#
if ((isflagset(5) || isbflagset(6)) && status=~"(183)|(2[0-9][0-9])"){
force_rtp_proxy();
append_hf("P-hint:onreply_route|force_rtp_proxy \r\n");
}
#---- If the CALLEE is behind NAT, fix the CONTACTHF ----#
if (isbflagset(6)) {
#-- Insert nat=yes at the end of the Contactheader --#
#-- This helps with REINVITEs, --#
#- nat=yes will be included in the R-URI forseq.requests-#
search_append('Contact:.*sip:[^>[:cntrl:]]*',';nat=yes');
append_hf("P-hint: Onreply-route - fixcontact\r\n");
fix_nated_contact();
}
exit;
}
failure_route[1] {
#---- If a failure has ocurred, deactivate the RTpproxy ----#
if (isflagset(5) || isbflagset(6)){
unforce_rtp_proxy();
}
if (t_was_cancelled()){
exit;
}
# uncomment thefollowing lines if you want to block client
# redirect based on3xx replies.
##if(t_check_status("3[0-9][0-9]")) {
##t_reply("404","Notfound");
## exit;
##}
# uncomment thefollowing lines if you want to redirect the failed
# calls to a differentnew destination
##if(t_check_status("486|408")) {
## sethostport("192.168.2.100:5060");
## # do not set the missed call flag again
## t_relay();
##}
}
d) 重启opensips服务
/etc/init.d/opensips restart