|
@@ -1,32 +1,52 @@
|
|
|
#!KAMAILIO
|
|
|
+#
|
|
|
+# Simple/sample kamailio.cfg for running a proxy/registrar with TLS and
|
|
|
+# WebSockets support.
|
|
|
+
|
|
|
+#!substdef "!DBURL!sqlite:///db.sqlite!g"
|
|
|
+#!substdef "!MY_IP_ADDR!192.168.111.136!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"
|
|
|
+
|
|
|
+#!define LOCAL_TEST_RUN
|
|
|
+#!define WITH_TLS
|
|
|
+#!define WITH_WEBSOCKETS
|
|
|
|
|
|
-#!define DBURL "sqlite:////etc/kamailio/db.sqlite"
|
|
|
|
|
|
####### Global Parameters #########
|
|
|
|
|
|
-debug=2
|
|
|
fork=yes
|
|
|
children=4
|
|
|
|
|
|
-enable_tls=1
|
|
|
-
|
|
|
alias="example.com"
|
|
|
|
|
|
-listen=192.168.111.2:5060
|
|
|
-listen=tcp:192.168.111.2:80
|
|
|
+#!ifdef WITH_TLS
|
|
|
+enable_tls=1
|
|
|
+#!endif
|
|
|
|
|
|
-listen=tls:192.168.111.2:5061
|
|
|
-listen=tls:192.168.111.2:443
|
|
|
+listen=MY_IP_ADDR
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+listen=MY_WS_ADDR
|
|
|
+#!ifdef WITH_TLS
|
|
|
+listen=MY_WSS_ADDR
|
|
|
+#!endif
|
|
|
+#!endif
|
|
|
|
|
|
tcp_connection_lifetime=3604
|
|
|
tcp_accept_no_cl=yes
|
|
|
-
|
|
|
-enable_tls=1
|
|
|
+tcp_rd_buf_size=16384
|
|
|
|
|
|
syn_branch=0
|
|
|
|
|
|
-#mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/"
|
|
|
+#!ifdef LOCAL_TEST_RUN
|
|
|
+debug=2
|
|
|
mpath="modules_k:modules"
|
|
|
+#!else
|
|
|
+debug=0
|
|
|
+mpath="/usr/lib64/kamailio/modules_k/:/usr/lib64/kamailio/modules/"
|
|
|
+#!endif
|
|
|
|
|
|
loadmodule "db_sqlite.so"
|
|
|
loadmodule "tm.so"
|
|
@@ -43,11 +63,16 @@ loadmodule "sanity.so"
|
|
|
loadmodule "ctl.so"
|
|
|
loadmodule "auth.so"
|
|
|
loadmodule "auth_db.so"
|
|
|
-loadmodule "xhttp.so"
|
|
|
loadmodule "kex.so"
|
|
|
-loadmodule "websocket.so"
|
|
|
loadmodule "mi_rpc.so"
|
|
|
+#!ifdef WITH_TLS
|
|
|
loadmodule "tls.so"
|
|
|
+#!endif
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+loadmodule "xhttp.so"
|
|
|
+loadmodule "websocket.so"
|
|
|
+loadmodule "nathelper.so"
|
|
|
+#!endif
|
|
|
|
|
|
# ----------------- setting module-specific parameters ---------------
|
|
|
|
|
@@ -71,51 +96,72 @@ modparam("registrar", "max_expires", 3600)
|
|
|
modparam("registrar", "gruu_enabled", 0)
|
|
|
|
|
|
# ----- usrloc params -----
|
|
|
-modparam("usrloc", "db_url", DBURL)
|
|
|
+modparam("usrloc", "db_url", "DBURL")
|
|
|
modparam("usrloc", "db_mode", 0)
|
|
|
|
|
|
# ----- auth_db params -----
|
|
|
-modparam("auth_db", "db_url", DBURL)
|
|
|
+modparam("auth_db", "db_url", "DBURL")
|
|
|
modparam("auth_db", "calculate_ha1", yes)
|
|
|
modparam("auth_db", "password_column", "password")
|
|
|
modparam("auth_db", "load_credentials", "")
|
|
|
|
|
|
-# ----- websocket params -----
|
|
|
-modparam("websocket", "keepalive_timeout", 30)
|
|
|
-
|
|
|
+#!ifdef WITH_TLS
|
|
|
# ----- tls params -----
|
|
|
modparam("tls", "tls_method", "SSLv23")
|
|
|
modparam("tls", "certificate", "CA/ser1_cert.pem")
|
|
|
modparam("tls", "private_key", "CA/privkey.pem")
|
|
|
modparam("tls", "ca_list", "CA/calist.pem")
|
|
|
+#!endif
|
|
|
|
|
|
-####### Routing Logic ########
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+# ----- websocket params -----
|
|
|
+modparam("websocket", "keepalive_timeout", 30)
|
|
|
|
|
|
+# ----- nathelper params -----
|
|
|
+modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
|
|
|
+# Note: leaving NAT pings turned off here as nathelper is _only_ being used for
|
|
|
+# WebSocket connections. NAT pings are not needed as WebSockets have
|
|
|
+# their own keep-alives.
|
|
|
+#!endif
|
|
|
+
|
|
|
+
|
|
|
+####### Routing Logic ########
|
|
|
|
|
|
# Main SIP request routing logic
|
|
|
# - processing of any incoming SIP request starts with this route
|
|
|
# - note: this is the same as route { ... }
|
|
|
request_route {
|
|
|
|
|
|
- if ($rm == "OPTIONS")
|
|
|
- {
|
|
|
- force_rport();
|
|
|
- $du = "sip:192.168.111.2:5080;transport=udp";
|
|
|
- forward();
|
|
|
- exit;
|
|
|
- }
|
|
|
-
|
|
|
# per request initial checks
|
|
|
route(REQINIT);
|
|
|
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+ if (nat_uac_test(64)) {
|
|
|
+ # Do NAT traversal stuff for requests from a WebSocket
|
|
|
+ # connection - even if it is not behind a NAT!
|
|
|
+ # This won't be needed in the future if Kamailio and the
|
|
|
+ # WebSocket client support outbound.
|
|
|
+ force_rport();
|
|
|
+ if (is_method("REGISTER"))
|
|
|
+ fix_nated_register();
|
|
|
+ else {
|
|
|
+ if (!add_contact_alias()) {
|
|
|
+ xlog("L_ERR", "Error aliasing contact <$ct>\n");
|
|
|
+ sl_send_reply("400", "Bad Request");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ t_on_reply("WS_REPLY");
|
|
|
+ }
|
|
|
+ }
|
|
|
+#!endif
|
|
|
+
|
|
|
# handle requests within SIP dialogs
|
|
|
route(WITHINDLG);
|
|
|
|
|
|
### only initial requests (no To tag)
|
|
|
|
|
|
# CANCEL processing
|
|
|
- if (is_method("CANCEL"))
|
|
|
- {
|
|
|
+ if (is_method("CANCEL")) {
|
|
|
if (t_check_trans())
|
|
|
t_relay();
|
|
|
exit;
|
|
@@ -129,14 +175,13 @@ request_route {
|
|
|
# record routing for dialog forming requests (in case they are routed)
|
|
|
# - remove preloaded route headers
|
|
|
remove_hf("Route");
|
|
|
- if (is_method("INVITE|SUBSCRIBE"))
|
|
|
+ if (is_method("INVITE"))
|
|
|
record_route();
|
|
|
|
|
|
# handle registrations
|
|
|
route(REGISTRAR);
|
|
|
|
|
|
- if ($rU==$null)
|
|
|
- {
|
|
|
+ if ($rU==$null) {
|
|
|
# request with no Username in RURI
|
|
|
sl_send_reply("484","Address Incomplete");
|
|
|
exit;
|
|
@@ -162,8 +207,7 @@ route[REQINIT] {
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
- if(!sanity_check("1511", "7"))
|
|
|
- {
|
|
|
+ if(!sanity_check("1511", "7")) {
|
|
|
xlog("Malformed SIP message from $si:$sp\n");
|
|
|
exit;
|
|
|
}
|
|
@@ -175,6 +219,15 @@ route[WITHINDLG] {
|
|
|
# sequential request withing a dialog should
|
|
|
# take the path determined by record-routing
|
|
|
if (loose_route()) {
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+ if ($du == "") {
|
|
|
+ if (!handle_ruri_alias()) {
|
|
|
+ xlog("L_ERR", "Bad alias <$ru>\n");
|
|
|
+ sl_send_reply("400", "Bad Request");
|
|
|
+ exit;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#!endif
|
|
|
route(RELAY);
|
|
|
} else {
|
|
|
if ( is_method("ACK") ) {
|
|
@@ -198,8 +251,7 @@ route[WITHINDLG] {
|
|
|
|
|
|
# Handle SIP registrations
|
|
|
route[REGISTRAR] {
|
|
|
- if (is_method("REGISTER"))
|
|
|
- {
|
|
|
+ if (is_method("REGISTER")) {
|
|
|
if (!save("location"))
|
|
|
sl_reply_error();
|
|
|
|
|
@@ -226,28 +278,35 @@ route[LOCATION] {
|
|
|
|
|
|
# Authentication route
|
|
|
route[AUTH] {
|
|
|
- if (is_method("REGISTER") || from_uri==myself)
|
|
|
- {
|
|
|
+ if (is_method("REGISTER") || from_uri==myself) {
|
|
|
# authenticate requests
|
|
|
if (!auth_check("$fd", "subscriber", "1")) {
|
|
|
auth_challenge("$fd", "0");
|
|
|
exit;
|
|
|
}
|
|
|
# user authenticated - remove auth header
|
|
|
- if(!is_method("REGISTER|PUBLISH"))
|
|
|
+ if(!is_method("REGISTER"))
|
|
|
consume_credentials();
|
|
|
}
|
|
|
# if caller is not local subscriber, then check if it calls
|
|
|
# a local destination, otherwise deny, not an open relay here
|
|
|
- if (from_uri!=myself && uri!=myself)
|
|
|
- {
|
|
|
+ if (from_uri!=myself && uri!=myself) {
|
|
|
sl_send_reply("403","Not relaying");
|
|
|
exit;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#!ifdef WITH_WEBSOCKETS
|
|
|
+onreply_route[WS_REPLY] {
|
|
|
+ # Do NAT traversal stuff for replies to a WebSocket connection - even
|
|
|
+ # if it is not behind a NAT!
|
|
|
+ # This won't be needed in the future if Kamailio and the WebSocket
|
|
|
+ # client support outbound.
|
|
|
+ add_contact_alias();
|
|
|
+}
|
|
|
+
|
|
|
event_route[xhttp:request] {
|
|
|
- if ($Rp != "80" && $Rp != "443") {
|
|
|
+ if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT) {
|
|
|
xlog("L_WARN", "HTTP request received on $Rp\n");
|
|
|
xhttp_reply("403", "Forbidden", "", "");
|
|
|
exit;
|
|
@@ -276,3 +335,4 @@ event_route[xhttp:request] {
|
|
|
|
|
|
xhttp_reply("404", "Not found", "", "");
|
|
|
}
|
|
|
+#!endif
|