說明,因?yàn)楸疚闹攸c(diǎn)是介紹opensips中ACL配置,所以忽略了Asterisk和網(wǎng)關(guān)配置的流程。在本文章中,筆者已經(jīng)假設(shè)用戶安裝好了opensips,其控制界面,asterisk和網(wǎng)關(guān)設(shè)備。如果讀者沒有安裝此環(huán)境,請按照歷史文檔中的介紹安裝OpenSIPS,控制界面和asterisk以及網(wǎng)關(guān)配置。
1opensips cfg文件配置
如果用戶要實(shí)現(xiàn)opensips呼叫媒體服務(wù)器進(jìn)行落地處理的話,需要添加配置文件,修改必要的設(shè)置。首先,添加權(quán)限模塊:
loadmodule "permissions.so"
modparam("permissions", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
loadmodule "group.so"
modparam("group", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips")
添加了權(quán)限模塊和組模塊的處理以后,用戶需要在撥號規(guī)則中對呼出號碼進(jìn)行判斷來決定媒體服務(wù)器的動作或者是否有權(quán)限呼出的規(guī)則設(shè)置。注意,這里的通配符是一個示例的通配符,用戶需要根據(jù)自己本地號碼和國際長途的設(shè)置來進(jìn)行處理,包括前綴號碼設(shè)置等。在這里處理了這些流程以后,此呼叫抵達(dá)媒體服務(wù)器以后就無需再進(jìn)行判斷驗(yàn)證。當(dāng)然,如果用戶仍然想在媒體服務(wù)器做號碼處理,也可以根據(jù)自己的業(yè)務(wù)邏輯在媒體服務(wù)器進(jìn)行處理。這里,在主路由邏輯中添加一個簽權(quán)認(rèn)證的流程:
## authenticate and authorize
if (check_source_address(0)) {
# caller is a gateway
} else
if (is_from_local()) {
# caller is local
# authenticate if from local subscriber
# authenticate all initial non-REGISTER request that pretend to be
# generated by local subscriber (domain from FROM URI is local)
if (!proxy_authorize("", "subscriber")) {
proxy_challenge("", "auth");
exit;
}
if (!$au==$fU) {
send_reply(403,"Forbidden auth ID");
exit;
}
consume_credentials();
# caller authenticated
} else {
# if caller is not local, then called number must be local
if (!is_uri_host_local()) {
send_reply(403,"Rely forbidden");
exit;
}
}
然后分別添加local 呼叫,國際長途呼叫和號碼格式的判斷:
if ($rU=~"^[5-9][0-9]{6}$") { // 是否是本地號碼,用戶根據(jù)本地號碼位數(shù)做調(diào)整。
if (db_is_user_in("credentials","local")) {
prefix("0075"); // 前綴是0755 或者其他的號碼前綴
route(to_pstn);
} else {
send_reply(403, "No permissions for local calls");
exit;
}
}
國內(nèi)長途的判斷,通過區(qū)號加號碼位數(shù)判斷:
# 長途電話區(qū)號+號碼位數(shù),具體位數(shù)修改通配符設(shè)置
if ($rU=~"^[0-9][0-9][0-9][2-9][0-9]{6}$") {
if (db_is_user_in("credentials","ld")) {
prefix("1");
route(to_pstn);
} else {
send_reply(403, "No permissions for long distance");
exit;
}
國際長途呼叫是否符合E164的號碼格式的判斷,例如呼叫日本長途電話,或者其他的國家號碼,具體號碼位數(shù)需要自己修改。
if ($rU=~"^081[0-9]*$") {
if (db_is_user_in("credentials","int")) {
strip(3);
route(to_pstn);
} else {
send_reply(403, "No permissions for international calls");
exit;
}
}
在路由到PSTN的模塊中添加一個呼叫媒體服務(wù)器的路由規(guī)則。保存配置文件以后,然后重新啟動OpenSIPS服務(wù)器。
route[to_pstn] {
# routing to the pstn (Use the IP address of the gateway)
# Please use as the IP address one of the gateways provided
sethostport("sip.freesbc.cn:5600"); // 這里也可以是媒體服務(wù)器的IP地址。
t_relay();
exit;
}
2通過opensips 操作界面添加媒體服務(wù)器
完成了cfg文件的配置以后,在opensips的控制界面添加一個路由規(guī)則。
3修改opensips 操作界面的配置
因?yàn)镺penSIPS作為一個運(yùn)營級的軟交換,它要實(shí)時(shí)處理幾千或者上萬次的呼叫,每一個呼叫都要經(jīng)過呼叫簽權(quán)認(rèn)證。為了控制呼叫的認(rèn)證流程,OpenSIPS使用ACL來對呼叫認(rèn)證進(jìn)行管理。ACL本身可以支持非?焖俚膶(shí)時(shí)處理流程。在ACL管理的模塊中修改配置文件,支持grp表的配置設(shè)置。用戶然后修改control panel的PHP代碼,增加本地呼叫,長途呼叫和國際長途的規(guī)則設(shè)置。
讀者使用ACL時(shí)要注意,前面筆者已經(jīng)說明。OpenSIPS作為一個運(yùn)營級的平臺,它可以支持上千或者上萬的呼叫并發(fā)。而且一個SIP用戶如果需要執(zhí)行ACL的話,賬號本身可能涉及多個SQL 查詢流程。因此,ACL可能會引起數(shù)據(jù)庫查詢帶來的效率問題,ACL頻繁訪問會使得數(shù)據(jù)庫負(fù)載增加,從而會一致影響OpenSIPS的性能。為了提高ACL的執(zhí)行性能,ACL模塊引入了group的概念,通過ACL grp來提高查詢用戶的速度和優(yōu)化ACL的查詢性能。具體語法如下:
4添加ACL 控制組
通過控制界面,修改ACL的呼叫權(quán)限控制。針對不同的SIP 賬號做不同的處理設(shè)置。ld表示僅支持長途呼叫,local表示僅支持本地呼叫,int表示僅支持國際長途呼叫。
這里,1000 用戶可以呼叫本地用戶,呼叫長途;1001用戶可以呼叫本地和國際長途電話。對用戶ACL設(shè)置中,ACL支持了多種用戶驗(yàn)證的查詢方式,cfg腳本可以通過這幾種方式實(shí)現(xiàn)快速查詢,無需通過數(shù)據(jù)庫訪問來實(shí)現(xiàn)查詢,所以,這些查詢方式可能更加高效。它們都可以通過avpops,aaa_radius, 和ldap模塊實(shí)現(xiàn)支持。首先,ACL支持了binary code方式,使用一個bit就可以表示用戶的認(rèn)證權(quán)限,通過bitmask支持多種呼叫權(quán)限的設(shè)置。第一個bit表示賬號停用,第二個bit表示允許voip呼叫,第三個bit表示允許PSTN國內(nèi)呼叫,第四個bit表示允許國際呼叫。在cfg中對avp操作實(shí)現(xiàn)ACL流程的處理:
相當(dāng)于binary code來說,使用access level coding方式,用戶可能更加容易明白。ACL支持了Level encoding(0,1,2,3),這里0表示賬號停用,1表示使用VOIP呼叫,2表示允許國內(nèi)PSTN呼叫,3表示允許國際呼叫等。
但是,如果使用binary code或者access level設(shè)置呼叫權(quán)限的話,它仍然對用戶來說不是非常友好,畢竟,binary code 相對比較難以理解。具有一定含義的字符串對于大部分用戶來說是非常易懂的,而且也可以支持腳本執(zhí)行檢測。使用字符串的ACL 方式中,d表示SIP用戶停用,v表示允許voip呼叫,n表示允許國內(nèi)PSTN呼叫,i表示允許用戶執(zhí)行國際呼叫。
5媒體服務(wù)器設(shè)置以及呼叫測試
這里的媒體服務(wù)器是一個Asterisk服務(wù)器,通過IP呼叫到Asterisk以后,Asterisk做路由處理,然后呼叫鼎信的FXO語音網(wǎng)關(guān),最后語音網(wǎng)關(guān)呼叫落地運(yùn)營商的PSTN線路,直到最終用戶終端。如果用戶安裝FreePBX作為一個IPPBX的話,用戶可以通過界面直接配置一個pjsip的IP呼叫 trunk,直接對接到鼎信網(wǎng)關(guān)地址。然后再通過呼出路由規(guī)則做一個呼出路由就可以實(shí)現(xiàn)完整的通過OpenSIPS網(wǎng)關(guān)媒體服務(wù)器落地的流程。注意,Asterisk服務(wù)器也可以不經(jīng)過PSTN落地,呼叫真實(shí)運(yùn)營商的線路,也可以播放一個語音提示來做不同呼叫路由的測試。
OpenSIPS的SIP賬號可以首先注冊(使用1000用戶/1001用戶分別測試不同號碼)到OpenSIPS服務(wù)器,然后通過呼叫本地號碼,長途號碼和國際長途來實(shí)現(xiàn)測試流程。如果asterisk媒體服務(wù)器設(shè)置為一個偽落地環(huán)境,對SIP 賬號播放語音的話,成功的呼叫就會聽到不同的語音提示音。如果媒體服務(wù)器對接了語音網(wǎng)關(guān)的話,根據(jù)號碼位數(shù)和格式,運(yùn)營商會呼叫到本地,國內(nèi)或者國際用戶終端。
6總結(jié)
OpenSIPS作為一個運(yùn)營級的軟交換,它本身需要一個ACL模塊對用戶呼叫進(jìn)行認(rèn)證設(shè)置。根據(jù)不同的用戶路由到不同的媒體服務(wù)器和落地網(wǎng)關(guān)。本文章通過OpenSIPS對接Asterisk和網(wǎng)關(guān)的方式說明如何在OpenSIPS平臺通過ACL來對用戶進(jìn)行認(rèn)證流程。其中,ACL通過界面,組設(shè)置和ACL設(shè)置實(shí)現(xiàn)SIP賬號呼叫的驗(yàn)證。在本文章中,筆者介紹了如何修改cfg文件對呼叫做不同的判斷,同時(shí)介紹了通過OpenSIPS界面做路由和ACL設(shè)置。另外,針對ACL策略的設(shè)置方式,筆者做了一些深入的分析,包括各種設(shè)置方式的優(yōu)缺點(diǎn)。
OpenSIPS用戶通過物理終端可以對ACL設(shè)置進(jìn)行呼叫測試。通過撥打不同的號碼來檢測ACL的正確性。
參考資料:
www.opensips.org
www.freesbc.cn
www.freepbx.org.cn
- 融合通信/IPPBX/FreePBX商業(yè)解決方案:www.hiastar.com
- 最新Asterisk完整中文用戶手冊詳解:www.asterisk.org.cn
- Freepbx/FreeSBC技術(shù)文檔: www.freepbx.org.cn
- 如何使用免費(fèi)會話邊界控制器-FreeSBC,qq技術(shù)分享群:334023047
- 關(guān)注微信公眾號:asterisk-cn,獲得有價(jià)值的通信行業(yè)技術(shù)分享