mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
5.8 KiB
294 lines
5.8 KiB
#!KAMAILIO
|
|
#
|
|
# Edge proxy configuration with SIP over WebSocket support
|
|
#
|
|
|
|
#!substdef "!DBURL!sqlite:///etc/kamailio/db.sqlite!g"
|
|
#!substdef "!MY_IP_ADDR!a.b.c.d!g"
|
|
#!substdef "!MY_DOMAIN!example.com!g"
|
|
#!substdef "!MY_WS_PORT!80!g"
|
|
#!substdef "!MY_WSS_PORT!443!g"
|
|
#!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g"
|
|
#!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"
|
|
|
|
#!substdef "!REGISTRAR_IP!e.f.g.h!g"
|
|
#!substdef "!REGISTRAR_PORT!5060!g"
|
|
#!substdef "!FLOW_TIMER!20!g"
|
|
|
|
#!define WITH_TLS
|
|
#!define WITH_WEBSOCKETS
|
|
|
|
|
|
####### Global Parameters #########
|
|
|
|
debug=2
|
|
log_stderror=no
|
|
log_facility=LOG_LOCAL0
|
|
fork=yes
|
|
children=4
|
|
mpath="/usr/lib64/kamailio/modules/"
|
|
force_rport=yes
|
|
|
|
#!ifdef WITH_TLS
|
|
enable_tls=1
|
|
#!endif
|
|
|
|
listen=MY_IP_ADDR
|
|
#!ifdef WITH_WEBSOCKETS
|
|
listen=MY_WS_ADDR
|
|
#!ifdef WITH_TLS
|
|
listen=MY_WSS_ADDR
|
|
#!endif
|
|
#!endif
|
|
|
|
tcp_connection_lifetime=30 # FLOW_TIMER + 10
|
|
tcp_accept_no_cl=yes
|
|
tcp_rd_buf_size=16384
|
|
|
|
|
|
####### Modules Section ########
|
|
|
|
loadmodule "tm.so"
|
|
loadmodule "sl.so"
|
|
loadmodule "outbound.so"
|
|
loadmodule "rr.so"
|
|
loadmodule "path.so"
|
|
loadmodule "pv.so"
|
|
loadmodule "maxfwd.so"
|
|
loadmodule "xlog.so"
|
|
loadmodule "sanity.so"
|
|
loadmodule "ctl.so"
|
|
loadmodule "mi_rpc.so"
|
|
loadmodule "mi_fifo.so"
|
|
loadmodule "textops.so"
|
|
loadmodule "siputils.so"
|
|
loadmodule "stun.so"
|
|
loadmodule "kex.so"
|
|
loadmodule "corex.so"
|
|
#!ifdef WITH_TLS
|
|
loadmodule "tls.so"
|
|
#!endif
|
|
#!ifdef WITH_WEBSOCKETS
|
|
loadmodule "xhttp.so"
|
|
loadmodule "websocket.so"
|
|
#!endif
|
|
|
|
# ----------------- setting module-specific parameters ---------------
|
|
|
|
# ----- mi_fifo params -----
|
|
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
|
|
|
|
# ----- tm params -----
|
|
modparam("tm", "failure_reply_mode", 3)
|
|
|
|
# ----- rr params -----
|
|
modparam("rr", "append_fromtag", 0)
|
|
|
|
# ----- corex params -----
|
|
modparam("corex", "alias_subdomains", "MY_DOMAIN")
|
|
|
|
#!ifdef WITH_TLS
|
|
# ----- tls params -----
|
|
modparam("tls", "tls_method", "SSLv23")
|
|
modparam("tls", "certificate", "/etc/pki/CA/ser1_cert.pem")
|
|
modparam("tls", "private_key", "/etc/pki/CA/privkey.pem")
|
|
modparam("tls", "ca_list", "/etc/pki/CA/calist.pem")
|
|
#!endif
|
|
|
|
#!ifdef WITH_WEBSOCKETS
|
|
# ----- websocket params -----
|
|
modparam("websocket", "keepalive_timeout", 25) # FLOW_TIMER + 5
|
|
#!endif
|
|
|
|
|
|
####### Routing Logic ########
|
|
|
|
request_route {
|
|
if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT)
|
|
&& !(proto == WS || proto == WSS)) {
|
|
xlog("L_WARN", "SIP request received on $Rp\n");
|
|
sl_send_reply("403", "Forbidden");
|
|
exit;
|
|
}
|
|
|
|
route(REQINIT);
|
|
|
|
if (is_method("CANCEL")) {
|
|
if (t_check_trans()) {
|
|
route(RELAY);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
route(WITHINDLG);
|
|
|
|
t_check_trans();
|
|
|
|
if (is_method("REGISTER")) {
|
|
remove_hf("Route");
|
|
add_path();
|
|
$du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
|
|
} else {
|
|
if (is_method("INVITE|SUBSCRIBE"))
|
|
record_route();
|
|
|
|
if (@via[2] == "") {
|
|
# From client so route to registrar...
|
|
|
|
if ($rU == $null) {
|
|
sl_send_reply("484", "Address Incomplete");
|
|
exit;
|
|
}
|
|
remove_hf("Route");
|
|
$du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
|
|
} else {
|
|
# From registrar so route using "Route:" headers...
|
|
|
|
if (!loose_route()) {
|
|
switch($rc) {
|
|
case -2:
|
|
sl_send_reply("403", "Forbidden");
|
|
exit;
|
|
default:
|
|
xlog("L_ERR", "in request_route\n");
|
|
sl_reply_error();
|
|
exit;
|
|
}
|
|
}
|
|
|
|
t_on_failure("FAIL_OUTBOUND");
|
|
}
|
|
}
|
|
|
|
route(RELAY);
|
|
}
|
|
|
|
route[RELAY] {
|
|
if (!t_relay()) {
|
|
sl_reply_error();
|
|
}
|
|
exit;
|
|
}
|
|
|
|
route[REQINIT] {
|
|
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;
|
|
}
|
|
}
|
|
|
|
route[WITHINDLG] {
|
|
if (has_totag()) {
|
|
if (!loose_route()) {
|
|
switch($rc) {
|
|
case -2:
|
|
sl_send_reply("403", "Forbidden");
|
|
exit;
|
|
default:
|
|
if (is_method("ACK")) {
|
|
if ( t_check_trans() ) {
|
|
route(RELAY);
|
|
exit;
|
|
} else {
|
|
exit;
|
|
}
|
|
}
|
|
sl_send_reply("404","Not Found");
|
|
}
|
|
} else {
|
|
if (is_method("NOTIFY")) {
|
|
record_route();
|
|
}
|
|
route(RELAY);
|
|
}
|
|
exit;
|
|
}
|
|
}
|
|
|
|
onreply_route {
|
|
if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT)
|
|
&& !(proto == WS || proto == WSS)) {
|
|
xlog("L_WARN", "SIP response received on $Rp\n");
|
|
drop;
|
|
}
|
|
|
|
if (!t_check_trans()) {
|
|
drop;
|
|
}
|
|
|
|
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) {
|
|
remove_hf("Flow-Timer");
|
|
if ($(hdr(Require)[*])=~"outbound")
|
|
insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID");
|
|
}
|
|
}
|
|
|
|
failure_route[FAIL_OUTBOUND] {
|
|
if (t_branch_timeout() || !t_branch_replied()) {
|
|
send_reply("430", "Flow Failed");
|
|
}
|
|
}
|
|
|
|
event_route[xhttp:request] {
|
|
set_reply_close();
|
|
set_reply_no_connect();
|
|
|
|
if ($Rp != MY_WS_PORT
|
|
#!ifdef WITH_TLS
|
|
&& $Rp != MY_WSS_PORT
|
|
#!endif
|
|
) {
|
|
xlog("L_WARN", "HTTP request received on $Rp\n");
|
|
xhttp_reply("403", "Forbidden", "", "");
|
|
exit;
|
|
}
|
|
|
|
xlog("L_DBG", "HTTP Request Received\n");
|
|
|
|
if ($hdr(Upgrade)=~"websocket"
|
|
&& $hdr(Connection)=~"Upgrade"
|
|
&& $rm=~"GET") {
|
|
|
|
# Validate Host - make sure the client is using the correct
|
|
# alias for WebSockets
|
|
if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) {
|
|
xlog("L_WARN", "Bad host $hdr(Host)\n");
|
|
xhttp_reply("403", "Forbidden", "", "");
|
|
exit;
|
|
}
|
|
|
|
# Optional... validate Origin - make sure the client is from an
|
|
# authorised website. For example,
|
|
#
|
|
# if ($hdr(Origin) != "http://communicator.MY_DOMAIN"
|
|
# && $hdr(Origin) != "https://communicator.MY_DOMAIN") {
|
|
# xlog("L_WARN", "Unauthorised client $hdr(Origin)\n");
|
|
# xhttp_reply("403", "Forbidden", "", "");
|
|
# exit;
|
|
# }
|
|
|
|
# Optional... perform HTTP authentication
|
|
|
|
# ws_handle_handshake() exits (no further configuration file
|
|
# processing of the request) when complete.
|
|
if (ws_handle_handshake())
|
|
{
|
|
# Optional... cache some information about the
|
|
# successful connection
|
|
exit;
|
|
}
|
|
}
|
|
|
|
xhttp_reply("404", "Not Found", "", "");
|
|
}
|
|
|
|
event_route[websocket:closed] {
|
|
xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n");
|
|
}
|