123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- #!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");
- }
|