[sr-dev] Websocket testing

Peter Dunkley peter.dunkley at crocodile-rcs.com
Wed Sep 19 11:18:47 CEST 2012


Hello,

I found an issue with checking the Host: header when you are using a
non-default port (that is not 80 or 443) for WebSockets.

I have updated the WebSockets example kamailio.cfg in git master with a
fix.

Regards,

Peter

On Fri, 2012-09-14 at 11:55 +0200, Jesús Pérez Rubio wrote:

> Hi, I had the same problem and I solve it changing this line on my
> kamailio.cfg:
> 
> # DIRTY WORKARROUND :P    
> #if ($hdr(Host) == $null || !is_myself($hdr(Host))) {    
> if ($hdr(Host) == $null) {
>       xlog("L_WARN", "Bad host $hdr(Host)\n");
>       xhttp_reply("403", "Forbidden", "", "");
>       exit;
> }
> 
> Could anybode confirm me if this solution is correct (and secure)
> please?
> 
> Thanks in advance :).
> 
> 
> 2012/8/8 Carlos Ruiz Díaz <carlos.ruizdiaz at gmail.com>
> 
>         Thank you for your time Peter. 
>         
>         
>         
>         I'll setup a VM with Windows to continue with my tests and
>         I'll come back later with more feedback.
>         
>         
>         Regards.
>         
>         
>         Carlos.
>         
>         
>         
>         
>         On Wed, Aug 8, 2012 at 12:22 PM, Peter Dunkley
>         <peter.dunkley at crocodile-rcs.com> wrote:
>         
>                 Hi,
>                 
>                 I have added some comments in-line below.
>                 
>                 Regards,
>                 
>                 Peter
>                 
>                 
>                 > 1. After setting up the proxy ip:port in the
>                 call.htm file (of sipml5) to
>                 
>                 
>                 > *
>                 > 127.0.0.1:5060* the client started to work but
>                 kamailio script refused to
>                 
>                 > establish my connection because the following
>                 condition was not satisfied:
>                 >
>                 >
>                 
>                 
>                 > *if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT) {*
>                 > *                xlog("L_WARN", "HTTP request
>                 received on $Rp\n");*
>                 > *                xhttp_reply("403", "Forbidden", "",
>                 "");*
>                 > *                exit;*
>                 > *}*
>                 >
>                 > *MY_WS_PORT* and *MY_WSS_PORT *are set to 80 and 443
>                 respectively, as the
>                 
>                 > default config example of websocket module says so.
>                 >
>                 
>                 
>                 > Then, I decided to change the ip:port to
>                 *127.0.0.1:80*, always in the
>                 
>                 > call.htm file and afterwards the condition was
>                 satisfied but sipml5 dies
>                 > with
>                 >
>                 >  SIP stack start: proxy='127.0.0.1:80',
>                 realm='<sip:127.0.0.1>',
>                 > impi='2000', impu='<sip:2000 at 127.0.0.1>'
>                 
>                 
>                 >
>                 tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>                 
>                 >  Connecting to 'ws://127.0.0.1:80'
>                 
>                 
>                 >
>                 tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>                 >  Stack starting
>                 >
>                 tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>                 >  Unexpected response code: 200 :1
>                 <http://127.0.0.1/>
>                 >  __tsip_transport_ws_onerror
>                 >
>                 tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>                 >  __tsip_transport_ws_onclose
>                 >
>                 tsk_utils.js:97<http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5>
>                 
>                 >  Failed to connet to the server
>                 >
>                 > Finally, I ended up commenting the condition block
>                 and restored the
>                 
>                 
>                 > original values of ip:port to *127.0.0.1:5060* .
>                 
>                 >
>                 > Having done that, I tried again and another error
>                 was thrown but this
>                 > time,
>                 
>                 
>                 > in the next condition block: * if ($hdr(Host) ==
>                 $null ||
>                 > !is_myself($hdr(Host))) *
>                 
>                 >
>                 > <script>: WebSocket
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <script>:
>                 > Host:
>                 > 127.0.0.1:5060
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <script>:
>                 >  Origin: http://127.0.0.1
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==9 && [
>                 > 127.0.0.1:5060] == [127.0.0.1]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==9 && [
>                 > 127.0.0.1:5060] == [127.0.0.2]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==13 && [
>                 > 127.0.0.1:5060] == [192.168.10.95]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==13 && [
>                 > 127.0.0.1:5060] == [192.168.10.55]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==9 && [
>                 > 127.0.0.1:5060] == [127.0.0.1]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==9 && [
>                 > 127.0.0.1:5060] == [127.0.0.2]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==13 && [
>                 > 127.0.0.1:5060] == [192.168.10.95]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 > [socket_info.c:589]: grep_sock_info - checking if
>                 host==us: 14==13 && [
>                 > 127.0.0.1:5060] == [192.168.10.55]
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 DEBUG: <core>
>                 
>                 
>                 > [forward.c:462]: *check_self: host != me*
>                 
>                 > Aug  8 11:30:53 carlosrdcnx-laptop kamailio[16238]:
>                 WARNING: <script>: Bad
>                 > host 127.0.0.1:5060
>                 >
>                 > I commented the block too and only then sipml5 was
>                 able to register
>                 > itself.
>                 >
>                 > What am I doing wrong here?
>                 >
>                 
>                 
>                 
>                 When I tested this I was hosting sipml5 on a
>                 web-server on a separate
>                 machine from Kamailio, and my web-browser was on a
>                 separate machine from
>                 both Kamailio and the web-server.  The example
>                 configuration works for
>                 that scenario (which is likely to be the way it would
>                 be deployed in a
>                 real system).  I suspect that the Kamailio listen
>                 directives (or something
>                 else related) aren't set-up quite right for your
>                 environment.
>                 
>                 Host: is a required header when establishing a
>                 WebSocket connection.  The
>                 Host: header added by the client should indicate the
>                 name of the server
>                 the client is trying to connect to as indicated in the
>                 WebSocket URI (so
>                 if you put an IP address in the URI that will be in
>                 the Host: header, if
>                 you put a hostname in the URI then it will be in the
>                 Host: header).  The
>                 WebSocket server (in this case Kamailio) should check
>                 that this header
>                 matches what it believes it's externally visible name
>                 is before accepting
>                 the connection.
>                 
>                 This check needs to be performed in kamailio.cfg
>                 instead of the WebSocket
>                 module in order for the check to be flexible.  The
>                 check in the example
>                 kamailio.cfg is:
>                 - Making sure the Host: header is present
>                 - Making sure the name in the Host: header is an IP
>                 address (as defined in
>                 the listen directives) or alias (for example a domain
>                 name) that the
>                 Kamailio instance believes it is authoritative for.
>                 
>                 As the WebSocket stack in a web-browser will add the
>                 Host: header
>                 automatically, any problem with this suggests that the
>                 WebSocket URI set
>                 in sipml5 and the listen/alias directives in
>                 kamailio.cfg don't match -
>                 which would be consistent with the first part your
>                 connection
>                 establishment problem too.
>                 
>                 I would suggest that you should re-instate these lines
>                 as, by commenting
>                 them out (rather than fixing the underlying problems
>                 in the test set-up),
>                 you may be moving the issues down-stream.
>                 
>                 
>                 > 2. I registered a legacy softphone (twinkle) to
>                 attempt to initiate a call
>                 > in both ways, but the was something wrong with the
>                 signaling, probably
>                 > some
>                 > frame decoding garbage in the buffer of the SIP
>                 message. Perhaps these
>                 > bytes are part of the frame control header but since
>                 I haven't read the
>                 > RFC
>                 > (yet) I am mentioning it anyway.
>                 >
>                 
>                 
>                 > tcp_send: buf=*#012�~#003�*INVITE
>                 
>                 > sip:2000 at df7jal23ls0d.invalid;transport=ws
>                 > SIP/2.0#015#012Record-Route:
>                 >
>                 <sip:127.0.0.1;transport=ws;r2=on;lr=on>#015#012Record-Route:
>                 > <sip:127.0.0.1;r2=on;lr=on>#015#012Via: SIP/2.0/WS
>                 >
>                  127.0.0.1;branch=z9hG4bK90a8.b1a7035e13ed19880dd12a1f4c86adbb.0#015#012Via:
>                 > SIP/2.0/UDP
>                 >
>                 127.0.0.1:5062;rport=5062;branch=z9hG4bKimixlbyp#015#012Max-Forwards:
>                 > 69#015#012To: <sip:2000 at 127.0.0.1>#015#012From:
>                 "1000"
>                 > <sip:1000 at 127.0.0.1>;tag=lrtfz#015#012Call-ID:
>                 > gxsqobolphfchfq at carlosrdcnx-laptop.site#015#012CSeq:
>                 654
>                 > INVITE#015#012Contact:
>                 <sip:1000 at 127.0.0.1:5062>#015#012Content-Type:
>                 > application/sdp#015#012Allow:
>                 >
>                 INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE#015#012Supported:
>                 > replaces,norefersub,100rel#015#012User-Agent:
>                 > Twinkle/1.4.2#015#012Content-Length:
>                 > 302#015#012#015#012v=0#015#012o=twinkle 391470222
>                 1383232165 IN IP4
>                 > 127.0.0.1#015#012s=-#015#012c=IN IP4
>                 127.0.0.1#015#012t=0 0#015#012m=audio
>                 > 8008 RTP/AVP 98 97 8 0 3 101#015#012a=rtpmap:98
>                 > speex/16000#015#012a=rtpmap:97
>                 speex/8000#015#012a=rtpmap:8
>                 > PCMA/8000#015#012a=rtpmap:0
>                 PCMU/8000#015#012a=rtpmap:3
>                 > GSM/8000#015#012a=rtpmap:101
>                 telephone-event/8000#015#012a=fmtp:101
>                 > 0-15#015#012a=ptime:20#015#012
>                 >
>                 
>                 
>                 
>                 That INVITE is for a call towards sipml5 on a
>                 WebSocket connection.  So
>                 this isn't a SIP message over TCP, it is a SIP message
>                 over WebSockets
>                 over TCP - and those are not the same thing.  The
>                 stuff at the start of
>                 the TCP buffer is the WebSocket framing and it is
>                 meant to be there.
>                 
>                 The WebSocket framing will not be present on the
>                 connection to Twinkle.
>                 
>                 
>                 > 3. Does Twinkle support the minimum media
>                 requirements for testing? If
>                 > not,
>                 > what (Linux) softphone is suitable for this purpose?
>                 >
>                 
>                 
>                 
>                 When using an up-to-date Google Chrome you need to use
>                 a client that
>                 supports RTP/SAVPF.  Boghe (from Doubango) is a
>                 Windows client that
>                 supports this.  I don't know which (if any) Linux
>                 clients support this
>                 feature.
>                 
>                 --
>                 Peter Dunkley
>                 Technical Director
>                 Crocodile RCS Ltd
>                 
>                 
>                 _______________________________________________
>                 sr-dev mailing list
>                 sr-dev at lists.sip-router.org
>                 http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
>         
>         
>         
>         
>         
>         _______________________________________________
>         sr-dev mailing list
>         sr-dev at lists.sip-router.org
>         http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
>         
> 
> 
> 
> 
> -- 
> Jesús Pérez
> VoIP Engineer at Quobis
> 
> Fixed: +34 902 999 465
> Site: http://www.quobis.com
> 
> 
> _______________________________________________
> sr-dev mailing list
> sr-dev at lists.sip-router.org
> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev


-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sip-router.org/pipermail/sr-dev/attachments/20120919/a41aa3e7/attachment-0001.htm>


More information about the sr-dev mailing list