1. Mã ví dụ
------
2. Mã ví dụ
-------
3. Ví dụ thứ ba
------
Ví dụ 4, Load_balance+NAT
----------------------
5. Mã truyền tải SIP
----------
#
# Script cấu hình nhà dân dụng OpenSIPS
# bởi OpenSIPS Solutions <team@opensips-solutions.com>
#
# Script này được tạo qua "make menuconfig", từ
# kịch bản "Residential".
# Bạn có thể bật / tắt nhiều tính năng / chức năng bằng cách
# tạo lại kịch bản với các tùy chọn khác nhau.#
#
# Vui lòng tham khảo Core CookBook tại:
# http://www.opensips.org/Resources/DocsCookbooks
# để giải thích về các câu lệnh, hàm và tham số khả dĩ.
#
####### Tham số toàn cục #########
log_level=3
log_stderror=no
log_facility=LOG_LOCAL0
children=4
/* bỏ chú thích dòng sau để bật gỡ lỗi */
#debug_mode=yes
/* bỏ chú thích dòng tiếp theo để bật danh sách đen tạm thời tự động cho
các đích không khả dụng (tắt mặc định) */
#disable_dns_blacklist=no
/* bỏ chú thích dòng tiếp theo để bật tra cứu IPv6 sau khi tra cứu DNS IPv4
thất bại (tắt mặc định) */
#dns_try_ipv6=yes
/* bỏ chú thích dòng tiếp theo để bật phát hiện tự động bí danh cục bộ
dựa trên DNS ngược trên IP */
auto_aliases=no
listen=udp:172.16.0.118:6080 as xxx.xx.xx.xx:6080
listen=tcp:172.16.0.118:6080 as xxx.xx.xx.xx:6080
listen=tls:172.16.0.118:6081 as xxx.xx.xx.xx:6081
####### Mô-đun Section ########
# đặt đường dẫn mô-đun
mpath="/usr/local/lib64/opensips/modules/"
#### Mô-đun tín hiệu
loadmodule "signaling.so"
#### Mô-đun vô trạng thái
loadmodule "sl.so"
#### Mô-đun giao dịch
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### cấu hình ngoại tuyến
modparam("tm", "fr_timer", 10 )
modparam("tm", "fr_inv_timer", 15 )
modparam("tm", "wt_timer", 10 )
#### Mô-đun đường dẫn xác định
loadmodule "rr.so"
/* không thêm thẻ từ vào RR (không cần thiết cho script này) */
modparam("rr", "append_fromtag", 0)
#### Mô-đun tối đa chuyển tiếp
loadmodule "maxfwd.so"
#### Mô-đun thao tác tin nhắn SIP
loadmodule "sipmsgops.so"
#### Giao diện quản lý FIFO
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### Mô-đun URI
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)
#### Mô-đun MYSQL
loadmodule "db_mysql.so"
#### Mô-đun HTTPD
#loadmodule "httpd.so"
#modparam("httpd", "port", 8888)
#### Mô-đun vị trí người dùng
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # TÙY CHỈNH
#modparam("usrloc", "db_mode", 2)
#### cấu hình ngoại tuyến
modparam("usrloc", "db_mode", 0)
#### Mô-đun đăng ký
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")
/* bỏ chú thích dòng tiếp theo để không cho phép nhiều hơn 10 liên lạc mỗi AOR */
#modparam("registrar", "max_contacts", 10)
#### cấu hình ngoại tuyến
modparam("registrar", "default_expires", 120)
#### Mô-đun tính toán
loadmodule "acc.so"
/* sự kiện đặc biệt nào nên được tính toán? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* theo mặc định chúng ta không điều chỉnh hướng của các yêu cầu tuần tự.
nếu bạn bật tham số này, hãy chắc chắn bật "append_fromtag"
trong mô-đun "rr" */
modparam("acc", "detect_direction", 0)
modparam("acc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # TÙY CHỈNH
#### Mô-đun xác thực
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db|uri", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # TÙY CHỈNH
modparam("auth_db", "load_credentials", "")
#### Mô-đun Presence
loadmodule "xcap.so"
loadmodule "presence.so"
loadparam("presence_xml", "force_active", 1)
modparam("presence", "server_address", "sip:172.16.0.118:6080") # TÙY CHỈNH
#### Mô-đun hội thoại
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600) # thời gian chờ 6 giờ
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # TÙY CHỈNH
#### Mô-đun NAT
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG")
modparam("nathelper", "sipping_from", "sip:pinger@127.0.0.1") #TÙY CHỈNH
modparam("nathelper", "received_avp", "$avp(received_nh)")
loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:7890") # TÙY CHỈNH
#### Mô-đun kế hoạch gọi
loadmodule "dialplan.so"
modparam("dialplan", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") # TÙY CHỈNH
#### Mô-đun MI_HTTP
#loadmodule "mi_http.so"
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
loadmodule "proto_tls.so"
#### tls
loadmodule "tls_mgm.so"
modparam("tls_mgm","verify_cert", "1")
modparam("tls_mgm","require_cert", "0")
modparam("tls_mgm","tls_method", "TLSv1")
modparam("tls_mgm","certificate", "/usr/local/etc/opensips/tls/user/user-cert.pem")
modparam("tls_mgm","private_key", "/usr/local/etc/opensips/tls/user/user-privkey.pem")
modparam("tls_mgm","ca_list", "/usr/local/etc/opensips/tls/user/user-calist.pem")
#### cấu hình ngoại tuyến
loadmodule "msilo.so"
# tải mô-đun msilo
modparam("msilo", "db_table", "silo")
# cấu hình bảng lưu trữ tin nhắn ngoại tuyến silo
modparam("msilo", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
# cấu hình đường dẫn cơ sở dữ liệu
modparam("msilo", "add_date", 1)
# cấu hình hiển thị [tin nhắn ngoại tuyến + thời gian]
modparam("msilo","content_type_hdr","Content-Type: text/plain\r\n")
modparam("msilo","offline_message","*** Người dùng $rU đang ngoại tuyến!")
modparam("msilo","from_address","sip:registrar@xxx.xx.xx.xx")
modparam("msilo","contact_hdr","Contact: registrar@xxx.xx.xx.xx:6080;msilo=yes\r\n")
####### Logic định tuyến ########
# logic định tuyến yêu cầu chính
route{
force_rport();
if (nat_uac_test("23")) {
if (is_method("REGISTER")) {
fix_nated_register();
setbflag(NAT);
} else {
fix_nated_contact();
setflag(NAT);
}
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Quá nhiều Hops");
exit;
}
if (has_totag()) {
# yêu cầu tuần tự trong một cuộc trò chuyện nên
# đi theo lộ trình được xác định bởi việc ghi lại đường dẫn
if (loose_route()) {
# xác thực yêu cầu tuần tự so với cuộc trò chuyện
if ( $DLG_status!=NULL && !validate_dialog() ) {
xlog("Trong-Đối thoại $rm từ $si (callid=$ci) không hợp lệ theo cuộc trò chuyện\n");
## exit;
}
if (is_method("BYE")) {
# tính toán ngay cả khi giao dịch thất bại
do_accounting("db","failed");
} else if (is_method("INVITE")) {
# ngay cả khi trong hầu hết các trường hợp không hữu ích, làm RR cho
# re-INVITE cũng, vì một số khách hàng lỗi đổi tập đường dẫn
# trong suốt cuộc trò chuyện.
record_route();
}
if (check_route_param("nat=yes"))
setflag(NAT);
# định tuyến ra ngoài bất kỳ đích nào được thiết lập bởi loose_route()
# trong $du (URI đích).
route(relay);
} else {
if (is_method("SUBSCRIBE") && $rd == "172.16.0.118:6080") { # TÙY CHỈNH
# yêu cầu đăng ký trong cuộc trò chuyện
route(handle_presence);
exit;
}
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# ACK không loose-route, nhưng có trạng thái; phải là ACK sau
# 487 hoặc ví dụ 404 từ máy chủ thượng nguồn
t_relay();
exit;
} else {
# ACK không khớp với giao dịch ->
# bỏ qua và loại bỏ
exit;
}
}
sl_send_reply("404","Không tồn tại ở đây");
}
exit;
}
# xử lý HỦY
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
/*
if ( !(is_method("REGISTER") ) ) {
if (from_uri==myself)
{
# xác thực nếu từ người đăng ký cục bộ
# xác thực tất cả yêu cầu ban đầu không-REGISTER giả định là
# được tạo bởi người đăng ký cục bộ (miền từ URI FROM là cục bộ)
if (!proxy_authorize("", "subscriber")) {
proxy_challenge("", "0");
exit;
}
if (!db_check_from()) {
sl_send_reply("403","Cấm ID xác thực");
exit;
}
consume_credentials();
# người gọi đã xác thực
} else {
# nếu người gọi không phải cục bộ, thì số được gọi phải là cục bộ
if (!uri==myself) {
send_reply("403","Rely cấm");
exit;
}
}
}
*/
# kiểm tra đường dẫn được tải trước
if (loose_route()) {
xlog("L_ERR", "Thử định tuyến với Route được tải trước [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
sl_send_reply("403","Route được tải trước bị từ chối");
exit;
}
# ghi lại đường dẫn
if (!is_method("REGISTER|MESSAGE"))
record_route();
# chỉ tính toán INVITEs
if (is_method("INVITE")) {
# tạo cuộc trò chuyện với thời gian chờ
if ( !create_dialog("B") ) {
send_reply("500","Lỗi máy chủ nội bộ");
exit;
}
do_accounting("db");
}
if (!uri==myself) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# yêu cầu cho miền của tôi
if( is_method("PUBLISH|SUBSCRIBE"))
route(handle_presence);
if (is_method("REGISTER"))
{
# xác thực yêu cầu REGISTER
if (!www_authorize("", "subscriber"))
{
www_challenge("", "0");
exit;
}
if (!db_check_to())
{
sl_send_reply("403","Cấm ID xác thực");
exit;
}
if ( proto==TCP || proto==TLS || 0 ) setflag(TCP_PERSISTENT);
if (isflagset(NAT)) {
setbflag(SIP_PING_FLAG);
}
if (!save("location"))
{
sl_reply_error();
}
# phần tăng thêm--bắt đầu
if (m_dump()){
log("MSILO: tin nhắn ngoại tuyến được dump\n");
}else{
log("MSILO: không có tin nhắn ngoại tuyến được dump\n");
}
# phần tăng thêm--kết thúc
exit;
}
if ($rU==NULL) {
# yêu cầu không có Tên người dùng trong RURI
sl_send_reply("484","Địa chỉ Không Đủ");
exit;
}
# áp dụng biến đổi từ bảng kế hoạch gọi
dp_translate("0","$rU/$rU");
# tìm kiếm với lọc phương thức
if (!lookup("location","m")) {
if (!db_does_uri_exist()) {
send_reply("420","SốgetExtension Không Hợp lệ");
exit;
}
#t_newtran();
#t_reply("404", "Không Tìm Thấy");
#exit;
if(!t_newtran()){
sl_reply_error();
exit;
}
if (!method=="MESSAGE")
{
if (!t_reply("404", "Không Tìm Thấy"))
{
sl_reply_error();
};
exit;
};
log("MSILO:Tin nhắn nhận được -> lưu bằng MSILO\n");
if (m_store("$ru")){
log("MSILO: tin nhắn ngoại tuyến được lưu\n");
if (!t_reply("202","Chấp Nhận")){
sl_reply_error();
};
}else{
log("MSILO: tin nhắn ngoại tuyến KHÔNG được lưu\n");
if(!t_reply("503","Dịch vụ Không Khả Dụng")){
sl_reply_error();
};
};
exit;
}
t_on_failure("1");
if (isbflagset(NAT)) setflag(NAT);
# khi định tuyến qua usrloc, ghi lại cả các cuộc gọi bị bỏ lỡ
do_accounting("db","missed");
route(relay);
}
route[relay] {
# cho INVITEs bật một số tuyến đường trợ giúp bổ sung
if (is_method("INVITE")) {
if (isflagset(NAT)) {
rtpproxy_offer("ro");
}
t_on_branch("per_branch_ops");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (isflagset(NAT)) {
add_rr_param(";nat=yes");
}
if (!t_relay()) {
send_reply("500","Lỗi Nội Bộ");
};
exit;
}
# Tuyến đường Presence
route[handle_presence]
{
if (!t_newtran())
{
sl_reply_error();
exit;
}
if(is_method("PUBLISH"))
{
handle_publish();
}
else if( is_method("SUBSCRIBE"))
{
handle_subscribe();
}
exit;
}
branch_route[per_branch_ops] {
xlog("nhánh mới tại $ru\n");
}
onreply_route[handle_nat] {
if (nat_uac_test("1"))
fix_nated_contact();
if ( isflagset(NAT) )
rtpproxy_answer("ro");
xlog("trả lời đến\n");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# bỏ chú thích các dòng sau nếu bạn muốn chặn khách hàng
# chuyển hướng dựa trên phản hồi 3xx.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply("404","Không tìm thấy");
## exit;
##}
# chuyển tiếp thất bại -- kiểm tra nếu yêu cầu là MESSAGE
if (!method=="MESSAGE")
{
exit;
};
log(1,"MSILO:Máy khách phía dưới không hỗ trợ MESSAGEs\n");
# chúng tôi đã thay đổi R-URI với địa chỉ liên lạc, bỏ qua nó bây giờ
if (m_store("$ou"))
{
log("MSILO: tin nhắn ngoại tuyến được lưu\n");
t_reply("202", "Chấp Nhận");
}else{
log("MSILO: tin nhắn ngoại tuyến KHÔNG được lưu\n");
t_reply("503", "Dịch vụ Không Khả Dụng");
};
}
failure_route[1] {
# chuyển tiếp thất bại -- kiểm tra nếu yêu cầu là MESSAGE
if (!method=="MESSAGE")
{
exit;
};
log(1,"MSILO:Máy khách phía dưới không hỗ trợ MESSAGEs\n");
# chúng tôi đã thay đổi R-URI với địa chỉ liên lạc, bỏ qua nó bây giờ
if (m_store("$ou"))
{
log("MSILO: tin nhắn ngoại tuyến được lưu\n");
t_reply("202", "Chấp Nhận");
}else{
log("MSILO: tin nhắn ngoại tuyến KHÔNG được lưu\n");
t_reply("503", "Dịch vụ Không Khả Dụng");
};
}
local_route {
if (is_method("BYE") && $DLG_dir=="UPSTREAM") {
acc_db_request("200 Thời gian chờ Cuộc trò chuyện", "acc");
}
}
# ----------- tham số cấu hình toàn cục ------------------------
debug=3
fork=yes
log_facility=LOG_LOCAL0
log_stderror=no
children=4
port=5060
dns=no
rev_dns=no
#advertised_address="xx.xx.xx.xx"
#alias="xx.xx.xx.xx:5060"
# ------------------ tải mô-đun ----------------------------------
mpath="/usr/lib/opensips/modules/"
loadmodule "db_mysql.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
loadmodule "uri.so"
loadmodule "nathelper.so"
loadmodule "domain.so"
# ----------------- thiết lập tham số cụ thể của mô-đun ---------------
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("usrloc", "db_url",
"mysql://opensipsrw:opensipsrw@localhost/opensips")
modparam("usrloc", "db_mode", 2)
modparam("rr", "enable_full_lr", 1)
modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:50010")
modparam("nathelper", "nortpproxy_str", "")
modparam("domain", "db_url",
"mysql://opensipsrw:opensipsrw@localhost/opensips")
################## NAT ######################
modparam("usrloc", "nat_bflag", 6)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", 8)
modparam("nathelper", "received_avp", "$avp(i:801)")
################## NAT ######################
# logic định tuyến chính
route {
# kiểm tra sơ bộ
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Quá Nhiều Hops");
exit;
};
if (msg:len >= 2048 ) {
sl_send_reply("513", "Tin nhắn quá lớn");
exit;
};
################## NAT ######################
if (nat_uac_test("3")) {
if (is_method("REGISTER") && !is_present_hf("Record-Route")) {
# Viết lại liên lạc với IP nguồn của tín hiệu
fix_nated_contact();
force_rport();
setbflag(6); # Đánh dấu là NATed
# nếu bạn muốn pinging SIP NAT
setbflag(8);
};
};
################## NAT ######################
if (!method=="REGISTER")
record_route();
# tin nhắn tiếp theo trong một cuộc trò chuyện nên đi theo
# lộ trình được xác định bởi ghi lại đường dẫn
if (loose_route()) {
# đánh dấu logic định tuyến trong yêu cầu
append_hf("P-hint: rr-enforced\r\n");
route(1);
};
if (!uri==myself) {
# đánh dấu logic định tuyến trong yêu cầu
append_hf("P-hint: outbound\r\n");
route(1);
};
if (uri==myself) {
if (method=="REGISTER") {
save("location");
exit;
};
}
if (is_method("BYE"))
unforce_rtp_proxy();
if (!lookup("location","m")) {
switch ($retcode) {
case -1:
case -3:
t_newtran();
t_on_failure("1");
t_reply("404", "Không Tìm Thấy");
exit;
case -2:
sl_send_reply("405", "Phương thức Không Được Cho Phép");
exit;
}
};
route(1);
}
route[1] {
################## NAT ######################
if (uri=~"[@:](192\.168\.10\.172\.(1[6-9]2[0-9]3[0-1])\.)" &&
!search("^Route:")) {
sl_send_reply("479", "Chúng tôi không chuyển tiếp đến địa chỉ IP riêng");
exit;
};
# nếu máy khách hoặc máy chủ biết là đằng sau NAT, bật relay
if (isbflagset(6)) {
if (has_body("application/sdp")) {
rtpproxy_offer("o");
};
};
t_on_reply("1");
################## NAT ######################
# gửi ra ngoài ngay bây giờ; sử dụng chuyển tiếp trạng thái để hoạt động
# đáng tin cậy thậm chí cho UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
exit;
}
onreply_route[1] {
################## NAT ######################
if (isbflagset(6) && status =~ "(183)|2[0-9][0-9]") {
fix_nated_contact();
if (has_body("application/sdp")) {
rtpproxy_answer("o");
};
# Là giao dịch đằng sau NAT và chúng tôi không
# biết tại thời điểm xử lý yêu cầu?
} else if (nat_uac_test("1")) {
fix_nated_contact();
};
################## NAT ######################
}
failure_route[1] {
unforce_rtp_proxy();
}
#
# script cấu hình nhanh đơn giản bao gồm hỗ trợ nathelper
# Script mặc định này bao gồm hỗ trợ nathelper. Để làm cho nó hoạt động
# bạn cũng phải cài đặt RTP proxy của Maxim. Proxy được buộc
# nếu một trong hai bên đứng sau NAT.
#
# Nếu bạn có endpoint trong internet công cộng được biết đến
# hỗ trợ RTP đối xứng (gateway PSTN Cisco hoặc thư thoại, ví dụ),
# thì bạn không cần phải buộc RTP proxy. Nếu bạn không muốn buộc
# RTP proxy cho một số đích thì đơn giản sử dụng t_relay() thay vì
# route(1)
#
# Các phần đánh dấu với !! Nathelper chứa các sửa đổi cho nathelper
#
# LƯU Ý !! Cấu hình này là THỬ NGHIỆM !
#
# ----------- tham số cấu hình toàn cục ------------------------
log_level=3 # mức ghi nhật ký (dòng lệnh: -dddddddddd)
log_stderror=no # (dòng lệnh: -E)
/* Bỏ chú thích các dòng này để vào chế độ gỡ lỗi */
#debug_mode=yes
check_via=no # (dòng lệnh: -v)
dns=no # (dòng lệnh: -r)
rev_dns=no # (dòng lệnh: -R)
port=5060
children=4
# ------------------ tải mô-đun ----------------------------------
# đặt đường dẫn mô-đun
mpath="/usr/local/lib/opensips/modules/"
# Bỏ chú thích nếu bạn muốn sử dụng cơ sở dữ liệu SQL
#loadmodule "db_mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "signaling.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
# Bỏ chú thích nếu bạn muốn xác thực mật khẩu
# db_mysql.so phải được tải!
#loadmodule "auth.so"
#loadmodule "auth_db.so"
# !! Nathelper
loadmodule "nathelper.so"
loadmodule "rtpproxy.so"
# ----------------- thiết lập tham số cụ thể của mô-đun ---------------
# -- tham số mi_fifo --
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
# -- tham số usrloc --
modparam("usrloc", "db_mode", 0)
# Bỏ chú thích nếu bạn muốn sử dụng cơ sở dữ liệu SQL
# cho lưu trữ bền vững và bỏ chú thích dòng trước
#modparam("usrloc", "db_mode", 2)
# -- tham số xác thực --
# Bỏ chú thích nếu bạn đang sử dụng mô-đun xác thực
#modparam("auth_db", "calculate_ha1", yes)
#
# Nếu bạn đặt tham số "calculate_ha1" thành yes (đúng trong cấu hình này),
# bỏ chú thích tham số sau
#modparam("auth_db", "password_column", "password")
# !! Nathelper
modparam("usrloc","nat_bflag",6)
modparam("nathelper","sipping_bflag",8)
modparam("nathelper", "ping_nated_only", 1) # Ping chỉ các máy khách đứng sau NAT
# ------------------------- logic định tuyến yêu cầu -------------------
# logic định tuyến chính
route{
# kiểm tra sơ bộ -- tin nhắn với
# max_forwards==0, hoặc yêu cầu quá dài
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Quá Nhiều Hops");
exit;
};
if ($ml >= 2048 ) {
sl_send_reply("513", "Tin nhắn quá lớn");
exit;
};
# !! Nathelper
# Xử lý đặc biệt cho máy khách NATed; đầu tiên, kiểm tra NAT
# được thực hiện: nó tìm kiếm via!=received và địa chỉ RFC1918
# trong Liên lạc (có thể thất bại nếu sử dụng gập dòng); cũng,
# kiểm tra received nên, nếu hoàn thành, nên kiểm tra tất cả
# các vias cho sự hiện diện của received
if (nat_uac_test("3")) {
# Cho phép yêu cầu RR-ed, vì những yêu cầu này có thể chỉ ra rằng
# một proxy hỗ trợ NAT đang xử lý nó; trừ khi đó là
# một REGISTER
if (is_method("REGISTER") || !is_present_hf("Record-Route")) {
log("LOG:Nh someone cố gắng đăng ký từ IP riêng, viết lại\n");
# Điều này sẽ chỉ hoạt động cho các tác nhân người dùng hỗ trợ giao tiếp đối xứng
# Chúng tôi đã thử nghiệm khá nhiều và đa số đủ thông minh để đối xứng. Trong một số điện thoại, cần
# tùy chọn cấu hình. Với Cisco 7960, nó được gọi là
# NAT_Enable=Yes, với kphone nó được gọi là "media đối xứng" và
# "ký hiệu đối xứng".
# Viết lại liên lạc với IP nguồn của tín hiệu
fix_nated_contact();
if ( is_method("INVITE") ) {
fix_nated_sdp("1"); # Thêm direction=active vào SDP
};
force_rport(); # Thêm tham số rport vào Via đầu tiên
setbflag(6); # Đánh dấu là NATed
# nếu bạn muốn pinging SIP NAT
# setbflag(8);
};
};
# tin nhắn tiếp theo trong một cuộc trò chuyện nên đi theo
# lộ trình được xác định bởi ghi lại đường dẫn
if (loose_route()) {
# đánh dấu logic định tuyến trong yêu cầu
append_hf("P-hint: rr-enforced\r\n");
route(1);
exit;
};
# chúng tôi ghi lại đường dẫn tất cả tin nhắn -- để đảm bảo rằng
# tin nhắn tiếp theo sẽ đi qua proxy của chúng tôi; điều này
# đặc biệt tốt nếu các thực thể thượng và hạ nguồn
# sử dụng giao thức truyền khác nhau
if (!is_method("REGISTER"))
record_route();
if (!is_myself("$rd")) {
# đánh dấu logic định tuyến trong yêu cầu
append_hf("P-hint: outbound\r\n");
route(1);
exit;
};
# nếu yêu cầu là cho miền khác sử dụng UsrLoc
# (nếu không hoạt động, sử dụng lệnh sau
# với tên và địa chỉ phù hợp)
if (is_myself("$rd")) {
if (is_method("REGISTER")) {
# Bỏ chú thích nếu bạn muốn sử dụng xác thực mật khẩu
#if (!www_authorize("siphub.org", "subscriber")) {
# www_challenge("siphub.org", "0");
# return;
#};
save("location");
exit;
};
lookup("aliases");
if (!is_myself("$rd")) {
append_hf("P-hint: outbound alias\r\n");
route(1);
exit;
};
# các đích SIP bản địa được xử lý bằng CSDL USRLOC của chúng tôi
if (!lookup("location")) {
sl_send_reply("404", "Không Tìm Thấy");
exit;
};
};
append_hf("P-hint: usrloc applied\r\n");
route(1);
}
route[1]
{
# !! Nathelper
if ($ru=~"[@:](192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" && !search("^Route:")){
sl_send_reply("479", "Chúng tôi không chuyển tiếp đến địa chỉ IP riêng");
exit;
};
# nếu máy khách hoặc máy chủ biết là đứng sau NAT, bật relay
if (isbflagset(6)) {
rtpproxy_offer();
};
# xử lý NAT của trả lời; áp dụng cho tất cả giao dịch (ví dụ,
# re-INVITE từ công cộng đến UA riêng rất khó xác định là
# NATed tại thời điểm xử lý yêu cầu); nhìn vào trả lời
t_on_reply("1");
# gửi ra ngoài ngay bây giờ; sử dụng chuyển tiếp trạng thái vì nó hoạt động đáng tin cậy
# thậm chí cho UDP2TCP
if (!t_relay()) {
sl_reply_error();
};
}
# !! Nathelper
onreply_route[1] {
# giao dịch NATed ?
if (isbflagset(6) && $rs =~ "(183)|2[0-9][0-9]") {
fix_nated_contact();
rtpproxy_answer();
# nếu không, có phải là giao dịch đứng sau NAT mà chúng tôi không
# biết tại thời điểm xử lý yêu cầu? (liên lạc RFC1918)
} else if (nat_uac_test("1")) {
fix_nated_contact();
};
}
####### Tham số toàn cục #########
log_level=3
log_stderror=no
log_facility=LOG_LOCAL0
children=4
/* bỏ chú thích dòng sau để bật gỡ lỗi */
debug_mode=yes
/* bỏ chú thích dòng tiếp theo để bật danh sách đen tạm thời tự động cho
các đích không khả dụng (tắt mặc định) */
#disable_dns_blacklist=no
/* bỏ chú thích dòng tiếp theo để bật tra cứu IPv6 sau khi tra cứu DNS IPv4
thất bại (tắt mặc định) */
#dns_try_ipv6=yes
/* bỏ chú thích dòng tiếp theo để bật phát hiện tự động bí danh cục bộ
dựa trên DNS ngược trên IP */
auto_aliases=yes
listen=udp:10.101.26.22:5060
listen=tcp:10.101.26.22:5060
listen=ws:10.101.26.22:8090
####### Mô-đun Section ########
# đặt đường dẫn mô-đun
mpath="/usr/local/opensips-2.2.3/lib64/opensips/modules"
#### Mô-đun tín hiệu
loadmodule "signaling.so"
#### Mô-đun vô trạng thái
loadmodule "sl.so"
#### Mô-đun giao dịch
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Mô-đun đường dẫn xác định
loadmodule "rr.so"
/* không thêm thẻ từ vào RR (không cần thiết cho script này) */
modparam("rr", "append_fromtag", 0)
#### Mô-đun tối đa chuyển tiếp
loadmodule "maxfwd.so"
#### Mô-đun thao tác tin nhắn SIP
loadmodule "sipmsgops.so"
#### Giao diện quản lý FIFO
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### Mô-đun URI
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
loadmodule "proto_ws.so"
modparam("proto_ws","ws_port",8080)
modparam("proto_ws","ws_send_timeout",20000)
#### Mô-đun MYSQL
loadmodule "db_mysql.so"
#### Mô-đun vị trí người dùng
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "db_url",
"mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
#### Mô-đun đăng ký
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")
/* bỏ chú thích dòng tiếp theo để không cho phép nhiều hơn 10 liên lạc mỗi AOR */
#modparam("registrar", "max_contacts", 10)
#### Mô-đun tính toán
loadmodule "acc.so"
/* sự kiện đặc biệt nào nên được tính toán? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* theo mặc định chúng ta không điều chỉnh hướng của các yêu cầu tuần tự.
nếu bạn bật tham số này, hãy chắc chắn bật "append_fromtag"
trong mô-đun "rr" */
modparam("acc", "detect_direction", 0)
modparam("acc", "db_url",
"mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
#### Mô-đun xác thực
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db|uri", "db_url",
"mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
modparam("auth_db", "load_credentials", "")
#### Mô-đun bí danh
loadmodule "alias_db.so"
modparam("alias_db", "db_url",
"mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
#### Mô-đun hội thoại
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600) # thời gian chờ 6 giờ
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url",
"mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
#### Mô-đun NAT
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "received_avp", "$avp(received_nh)")
######################################################################
## Tham số Mô-đun Đường dẫn
######################################################################
loadmodule "path.so"
modparam("path", "use_received", 1)
loadmodule "dispatcher.so"
modparam("dispatcher", "ds_ping_method", "OPTIONS") # TÙY CHỈNH
modparam("dispatcher", "ds_ping_interval", 3) # TÙY CHỈNH
modparam("dispatcher", "ds_probing_threshhold", 2) # TÙY CHỈNH
modparam("dispatcher", "ds_probing_mode", 1) # TÙY CHỈNH
modparam("dispatcher", "db_url", "mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
loadmodule "load_balancer.so"
modparam("load_balancer", "db_url", "mysql://root:123456789@127.0.0.1/opensips") # TÙY CHỈNH
modparam("load_balancer", "probing_method", "OPTIONS")
modparam("load_balancer", "probing_interval", 3)
#modparam("load_balancer", "fetch_freeswitch_stats", 1)
#modparam("load_balancer", "initial_freeswitch_load", 1000)
#loadmodule "rtpproxy.so"
#modparam("rtpproxy", "rtpproxy_sock", "udp:10.7.10.67:7890") # TÙY CHỈNH
#loadmodule "mediaproxy.so"
#modparam("mediaproxy", "disable", 0)
#modparam("mediaproxy", "mediaproxy_socket", "/var/run/mediaproxy/dispatcher.sock")
#modparam("mediaproxy", "mediaproxy_timeout", 1000)
#modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)")
#modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)")
#modparam("mediaproxy", "ice_candidate", "low-priority")
####### Logic định tuyến ########
# logic định tuyến yêu cầu chính
route{
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Quá Nhiều Hops");
exit;
}
if (has_totag()) {
# yêu cầu tuần tự trong một cuộc trò chuyện nên
# đi theo lộ trình được xác định bởi ghi lại đường dẫn
if (loose_route()) {
if (is_method("INVITE")) {
# ngay cả khi trong hầu hết các trường hợp không hữu ích, làm RR cho
# re-INVITE cũng, vì một số khách hàng lỗi đổi tập đường dẫn
# trong suốt cuộc trò chuyện.
record_route();
}
route(relay);
} else {
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
# ACK không loose-route, nhưng có trạng thái; phải là ACK sau
# 487 hoặc ví dụ 404 từ máy chủ thượng nguồn
t_relay();
exit;
} else {
# ACK không khớp với giao dịch ->
# bỏ qua và loại bỏ
exit;
}
}
sl_send_reply("404","Không tồn tại ở đây");
}
exit;
}
if (ds_is_in_list("$si", "", "1"))
{
route(relay);
exit;
}
# kiểm tra nếu máy khách đang sử dụng WebSockets hoặc WebSocketSecure
if (proto == WS || proto == WSS)
{
fix_nated_contact();
setflag(SRC_WS);
}
# xử lý HỦY
if (is_method("CANCEL"))
{
if (t_check_trans())
t_relay();
exit;
}
t_check_trans();
# Nếu yêu cầu là đăng ký chúng tôi sẽ chuyển tiếp nhưng cần
# thêm tiêu đề đường dẫn (cùng với thông tin IP/port nhận được)
if ( is_method("REGISTER"))
{
if(isflagset(SRC_WS)){
# nếu chúng tôi không thể thêm tiêu đề đường dẫn thì đừng cho phép
# đăng ký vì nó sẽ gây ra vấn đề sau này...
if (!add_path_received())
{
xlog("L_ERR", "$ci|log|không thể thêm đường dẫn");
sl_send_reply("503", "Lỗi đường dẫn nội bộ");
xlog("L_INFO", "$ci|end|đã dọn dẹp ID cuộc gọi khỏi bộ nhớ đệm");
exit;
}
xlog("L_INFO", "$ci|log|đã thêm đường dẫn");
}
if (isflagset(SRC_WS)){
fix_nated_register();
setbflag(DST_WS);
}
}
# kiểm tra đường dẫn được tải trước
if (loose_route()) {
xlog("L_ERR",
"Thử định tuyến với Route được tải trước [$fu/$tu/$ru/$ci]");
if (!is_method("ACK"))
sl_send_reply("403","Route được tải trước bị từ chối");
exit;
}
# ghi lại đường dẫn
if (!is_method("REGISTER|MESSAGE"))
record_route();
if (!uri==myself) {
append_hf("P-hint: outbound\r\n");
route(relay);
}
# yêu cầu cho miền của tôi
if (is_method("PUBLISH|SUBSCRIBE"))
{
sl_send_reply("503", "Dịch vụ Không Khả Dụng");
exit;
}
if (is_method("REGISTER") )
{
if (!ds_select_dst("1", "0")) {
send_reply("503","Dịch vụ Không Khả Dụng");
exit;
}
}
else if (is_method("INVITE")) {
if (src_ip==10.101.26.107) {
log("đây là cuộc gọi nội bộ\n");
if (!load_balance("1","pstn","1")) {
send_reply("503","Dịch vụ Không Khả Dụng");
exit;
}
} else {
log("đây là cuộc gọi bên ngoài\n");
if (!load_balance("2","pstn","1")) {
send_reply("503","Dịch vụ Không Khả Dụng");
exit;
}
}
}
route(relay);
}
route[relay] {
# cho INVITEs bật một số tuyến đường trợ giúp bổ sung
if (is_method("INVITE")) {
#route(media);
t_on_branch("handle_nat");
t_on_reply("handle_nat");
t_on_failure("missed_call");
}
if (!t_relay()) {
send_reply("500","Lỗi Nội Bộ");
};
exit;
}
#route[media] {
# if (is_method("BYE") || is_method("CANCEL")) {
# end_media_session();
# }
# if (is_method("INVITE")) {
# engage_media_proxy();
# use_media_proxy();
# }
#}
branch_route[handle_nat] {
if (!is_method("INVITE") || !has_body("application/sdp"))
return;
if (isflagset(SRC_WS) && isbflagset(DST_WS))
$var(rtpengine_flags) = "ICE=force-relay DTLS=passive";
else if (isflagset(SRC_WS) && !isbflagset(DST_WS))
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
else if (!isflagset(SRC_WS) && isbflagset(DST_WS))
$var(rtpengine_flags) = "UDP/TLS/RTP/SAVPF ICE=force";
else if (!isflagset(SRC_WS) && !isbflagset(DST_WS))
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
#rtpengine_offer("$var(rtpengine_flags)");
}
onreply_route[handle_nat] {
if (!has_body("application/sdp"))
return;
if (isflagset(SRC_WS) && isbflagset(DST_WS))
$var(rtpengine_flags) = "ICE=force-relay DTLS=passive";
else if (isflagset(SRC_WS) && !isbflagset(DST_WS))
$var(rtpengine_flags) = "UDP/TLS/RTP/SAVPF ICE=force";
else if (!isflagset(SRC_WS) && isbflagset(DST_WS))
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
else if (!isflagset(SRC_WS) && !isbflagset(DST_WS))
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
#rtpengine_answer("$var(rtpengine_flags)");
}
failure_route[missed_call] {
if (t_was_cancelled()) {
exit;
}
# bỏ chú thích các dòng sau nếu bạn muốn chặn khách hàng
# chuyển hướng dựa trên phản hồi 3xx.
##if (t_check_status("3[0-9][0-9]")) {
##t_reply("404","Không tìm thấy");
## exit;
##}
}
local_route
{
if (is_method("BYE") )
{
acc_log_request("BYE do nội bộ tạo ra");
}
}
#
# Script cấu hình nhà dân dụng OpenSIPS
# bởi OpenSIPS Solutions <team@opensips-solutions.com>
#
# Script này được tạo qua "make menuconfig", từ
# kịch bản "Residential".
# Bạn có thể bật / tắt nhiều tính năng / chức năng bằng cách
# tạo lại kịch bản với các tùy chọn khác nhau.#
#
# Vui lòng tham khảo Core CookBook tại:
# https://opensips.org/Resources/DocsCookbooks
# để giải thích về các câu lệnh, hàm và tham số khả dĩ.
#
####### Tham số toàn cục #########
log_level=4
log_stderror=no
log_facility=LOG_LOCAL0
children=4
/* bỏ chú thích dòng sau để bật gỡ lỗi */
debug_mode=no
/* bỏ chú thích dòng tiếp theo để bật danh sách đen tạm thời tự động cho
các đích không khả dụng (tắt mặc định) */
#disable_dns_blacklist=no
/* bỏ chú thích dòng tiếp theo để bật tra cứu IPv6 sau khi tra cứu DNS IPv4
thất bại (tắt mặc định) */
dns_try_ipv6=no
/* bỏ chú thích dòng tiếp theo để bật phát hiện tự động bí danh cục bộ
dựa trên DNS ngược trên IP */
auto_aliases=no
listen=udp:192.168.1.100:5060 as 172.29.50.9:5060 # TÙY CHỈNH
####### Mô-đun Section ########
# đặt đường dẫn mô-đun
mpath="/usr/local/lib64/opensips/modules/"
loadmodule "db_mysql.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "uri.so"
loadmodule "dialog.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
loadmodule "dispatcher.so"
loadmodule "load_balancer.so"
loadmodule "sipmsgops.so"
loadmodule "proto_udp.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("dialog", "db_mode", 1)
modparam("dialog", "db_url", "mysql://root:123456@localhost/opensips")
modparam("rr", "enable_double_rr", 1)
modparam("rr", "append_fromtag", 1)
modparam("tm", "fr_timer", 2)
modparam("dispatcher", "db_url", "mysql://root:123456@localhost/opensips")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 1)
modparam("dispatcher", "ds_probing_threshhold", 2)
modparam("dispatcher", "ds_probing_mode", 5)
modparam("load_balancer", "db_url", "mysql://root:123456@localhost/opensips")
modparam("load_balancer", "probing_method", "OPTIONS")
modparam("load_balancer", "probing_interval", 5)
########## Mô-đun vị trí người dùng ########
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_url", "mysql://root:123456@localhost/opensips") # TÙY CHỈNH
########### đăng ký #########
loadmodule "registrar.so"
modparam("registrar", "received_avp", "$avp(received_nh)")
########## NAT ############
loadmodule "nat_traversal.so" # tải mô-đun hỗ trợ
loadmodule "nathelper.so"
modparam("nathelper", "received_avp", "$avp(received_nh)")
# kết nối http mới
####### Logic định tuyến ########
# logic định tuyến yêu cầu chính
route{
if (!mf_process_maxfwd_header("10")) {
send_reply("483","Quá Nhiều Hops");
exit;
}
if (!has_totag()) {
# xử lý ACK hop-by-hop (không cần định tuyến)
record_route();
}else{
loose_route();
t_relay();
exit;
}
# xử lý HỦY
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
if (is_method("INVITE")) {
if (!load_balance("1","pstn")) {
send_reply("503","Dịch vụ Không Khả Dụng");
exit;
}
loose_route();
t_relay();
exit;
}
else if (is_method("REGISTER")) {
if (!ds_select_dst("1", "0")) {
send_reply("503","Dịch vụ Không Khả Dụng");
exit;
}
} else {
send_reply("405","Phương thức Không Được Cho Phép");
exit;
}
if (!t_relay()) {
sl_reply_error();
}
}