edge_websocket.cfg 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #!KAMAILIO
  2. #
  3. # Edge proxy configuration with SIP over WebSocket support
  4. #
  5. #!substdef "!DBURL!sqlite:///etc/kamailio/db.sqlite!g"
  6. #!substdef "!MY_IP_ADDR!a.b.c.d!g"
  7. #!substdef "!MY_DOMAIN!example.com!g"
  8. #!substdef "!MY_WS_PORT!80!g"
  9. #!substdef "!MY_WSS_PORT!443!g"
  10. #!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g"
  11. #!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"
  12. #!substdef "!REGISTRAR_IP!e.f.g.h!g"
  13. #!substdef "!REGISTRAR_PORT!5060!g"
  14. #!substdef "!FLOW_TIMER!20!g"
  15. #!define WITH_TLS
  16. #!define WITH_WEBSOCKETS
  17. ####### Global Parameters #########
  18. debug=2
  19. log_stderror=no
  20. log_facility=LOG_LOCAL0
  21. fork=yes
  22. children=4
  23. mpath="/usr/lib64/kamailio/modules/"
  24. force_rport=yes
  25. #!ifdef WITH_TLS
  26. enable_tls=1
  27. #!endif
  28. listen=MY_IP_ADDR
  29. #!ifdef WITH_WEBSOCKETS
  30. listen=MY_WS_ADDR
  31. #!ifdef WITH_TLS
  32. listen=MY_WSS_ADDR
  33. #!endif
  34. #!endif
  35. tcp_connection_lifetime=30 # FLOW_TIMER + 10
  36. tcp_accept_no_cl=yes
  37. tcp_rd_buf_size=16384
  38. ####### Modules Section ########
  39. loadmodule "tm.so"
  40. loadmodule "sl.so"
  41. loadmodule "outbound.so"
  42. loadmodule "rr.so"
  43. loadmodule "path.so"
  44. loadmodule "pv.so"
  45. loadmodule "maxfwd.so"
  46. loadmodule "xlog.so"
  47. loadmodule "sanity.so"
  48. loadmodule "ctl.so"
  49. loadmodule "mi_rpc.so"
  50. loadmodule "mi_fifo.so"
  51. loadmodule "textops.so"
  52. loadmodule "siputils.so"
  53. loadmodule "stun.so"
  54. loadmodule "kex.so"
  55. loadmodule "corex.so"
  56. #!ifdef WITH_TLS
  57. loadmodule "tls.so"
  58. #!endif
  59. #!ifdef WITH_WEBSOCKETS
  60. loadmodule "xhttp.so"
  61. loadmodule "websocket.so"
  62. #!endif
  63. # ----------------- setting module-specific parameters ---------------
  64. # ----- mi_fifo params -----
  65. modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
  66. # ----- tm params -----
  67. modparam("tm", "failure_reply_mode", 3)
  68. # ----- rr params -----
  69. modparam("rr", "append_fromtag", 0)
  70. # ----- corex params -----
  71. modparam("corex", "alias_subdomains", "MY_DOMAIN")
  72. #!ifdef WITH_TLS
  73. # ----- tls params -----
  74. modparam("tls", "tls_method", "SSLv23")
  75. modparam("tls", "certificate", "/etc/pki/CA/ser1_cert.pem")
  76. modparam("tls", "private_key", "/etc/pki/CA/privkey.pem")
  77. modparam("tls", "ca_list", "/etc/pki/CA/calist.pem")
  78. #!endif
  79. #!ifdef WITH_WEBSOCKETS
  80. # ----- websocket params -----
  81. modparam("websocket", "keepalive_timeout", 25) # FLOW_TIMER + 5
  82. #!endif
  83. ####### Routing Logic ########
  84. request_route {
  85. if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT)
  86. && !(proto == WS || proto == WSS)) {
  87. xlog("L_WARN", "SIP request received on $Rp\n");
  88. sl_send_reply("403", "Forbidden");
  89. exit;
  90. }
  91. route(REQINIT);
  92. if (is_method("CANCEL")) {
  93. if (t_check_trans()) {
  94. route(RELAY);
  95. }
  96. exit;
  97. }
  98. route(WITHINDLG);
  99. t_check_trans();
  100. if (is_method("REGISTER")) {
  101. remove_hf("Route");
  102. add_path();
  103. $du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
  104. } else {
  105. if (is_method("INVITE|SUBSCRIBE"))
  106. record_route();
  107. if (@via[2] == "") {
  108. # From client so route to registrar...
  109. if ($rU == $null) {
  110. sl_send_reply("484", "Address Incomplete");
  111. exit;
  112. }
  113. remove_hf("Route");
  114. $du = "sip:REGISTRAR_IP:REGISTRAR_PORT";
  115. } else {
  116. # From registrar so route using "Route:" headers...
  117. if (!loose_route()) {
  118. switch($rc) {
  119. case -2:
  120. sl_send_reply("403", "Forbidden");
  121. exit;
  122. default:
  123. xlog("L_ERR", "in request_route\n");
  124. sl_reply_error();
  125. exit;
  126. }
  127. }
  128. t_on_failure("FAIL_OUTBOUND");
  129. }
  130. }
  131. route(RELAY);
  132. }
  133. route[RELAY] {
  134. if (!t_relay()) {
  135. sl_reply_error();
  136. }
  137. exit;
  138. }
  139. route[REQINIT] {
  140. if (!mf_process_maxfwd_header("10")) {
  141. sl_send_reply("483","Too Many Hops");
  142. exit;
  143. }
  144. if(!sanity_check("1511", "7"))
  145. {
  146. xlog("Malformed SIP message from $si:$sp\n");
  147. exit;
  148. }
  149. }
  150. route[WITHINDLG] {
  151. if (has_totag()) {
  152. if (!loose_route()) {
  153. switch($rc) {
  154. case -2:
  155. sl_send_reply("403", "Forbidden");
  156. exit;
  157. default:
  158. if (is_method("ACK")) {
  159. if ( t_check_trans() ) {
  160. route(RELAY);
  161. exit;
  162. } else {
  163. exit;
  164. }
  165. }
  166. sl_send_reply("404","Not Found");
  167. }
  168. } else {
  169. if (is_method("NOTIFY")) {
  170. record_route();
  171. }
  172. route(RELAY);
  173. }
  174. exit;
  175. }
  176. }
  177. onreply_route {
  178. if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT)
  179. && !(proto == WS || proto == WSS)) {
  180. xlog("L_WARN", "SIP response received on $Rp\n");
  181. drop;
  182. }
  183. if (!t_check_trans()) {
  184. drop;
  185. }
  186. if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) {
  187. remove_hf("Flow-Timer");
  188. if ($(hdr(Require)[*])=~"outbound")
  189. insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID");
  190. }
  191. }
  192. failure_route[FAIL_OUTBOUND] {
  193. if (t_branch_timeout() || !t_branch_replied()) {
  194. send_reply("430", "Flow Failed");
  195. }
  196. }
  197. event_route[xhttp:request] {
  198. set_reply_close();
  199. set_reply_no_connect();
  200. if ($Rp != MY_WS_PORT
  201. #!ifdef WITH_TLS
  202. && $Rp != MY_WSS_PORT
  203. #!endif
  204. ) {
  205. xlog("L_WARN", "HTTP request received on $Rp\n");
  206. xhttp_reply("403", "Forbidden", "", "");
  207. exit;
  208. }
  209. xlog("L_DBG", "HTTP Request Received\n");
  210. if ($hdr(Upgrade)=~"websocket"
  211. && $hdr(Connection)=~"Upgrade"
  212. && $rm=~"GET") {
  213. # Validate Host - make sure the client is using the correct
  214. # alias for WebSockets
  215. if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) {
  216. xlog("L_WARN", "Bad host $hdr(Host)\n");
  217. xhttp_reply("403", "Forbidden", "", "");
  218. exit;
  219. }
  220. # Optional... validate Origin - make sure the client is from an
  221. # authorised website. For example,
  222. #
  223. # if ($hdr(Origin) != "http://communicator.MY_DOMAIN"
  224. # && $hdr(Origin) != "https://communicator.MY_DOMAIN") {
  225. # xlog("L_WARN", "Unauthorised client $hdr(Origin)\n");
  226. # xhttp_reply("403", "Forbidden", "", "");
  227. # exit;
  228. # }
  229. # Optional... perform HTTP authentication
  230. # ws_handle_handshake() exits (no further configuration file
  231. # processing of the request) when complete.
  232. if (ws_handle_handshake())
  233. {
  234. # Optional... cache some information about the
  235. # successful connection
  236. exit;
  237. }
  238. }
  239. xhttp_reply("404", "Not Found", "", "");
  240. }
  241. event_route[websocket:closed] {
  242. xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n");
  243. }