Forum Discussion

Patrik_Jonsson's avatar
Mar 10, 2014

Web sockets in 11.4

Hi guys!

 

Been getting more requests regarding Web sockets from our developers. The way I've understood it is that the client will send a request to the LB over HTTP, the lb will choose a server and then the server will reply with a request to start a WS session. This should mean that the F5 can still chose pools with the host header information unless the host changes in mid session, right?

 

I tried to summarize the pros and cons in a list but would like to verify it with you guys (and perhaps get some additions?).

 

Updated pros and cons according to answers (albeit a bit late):

 

Pros:

 

  • Faster
  • Full duplex
  • Minimal overhead

Cons:

 

  • Less secure (anything can be hidden in the session)
  • Lack of headers makes content scanning less reliable via our IPS
  • No profiles in the load balancers means no intelligent iRules in terms of caching, redirects, uri rewriting
  • Less intelligent load distribution

/Patrik

 

6 Replies

  • Interesting topic. I have only just read up on this and corresponding disclaimer :-)

     

    Not sure SSL is an issue - I believe the servers can use WS plaintext so you could still use the F5 to SSL Offload?

     

    Are you sure you can't use a cookie? There is one HTTP request/response pair before WS kicks in, so in theory a cookie could be used to ensure the next TCP connection goes to same server?

     

  • Hi!

    Thanks for your reply! Been reading your replies here on Dev Central and learning alot from you. Your efforts are much appreciated!

    Yeah, it's an interesting topic and feels a bit like fumbling in the dark. 🙂

    Seems like the initial request gets a response with some upgrade headers (taken from here😞

    ET /demo HTTP/1.1
    Upgrade: WebSocket
    Connection: Upgrade
    Host: example.com
    Origin: http://example.com
    WebSocket-Protocol: sample 
    Server to client:
    
    HTTP/1.1 101 Web Socket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://example.com
    WebSocket-Location: ws://example.com/demo
    WebSocket-Protocol: sample 
    

    The initial request is bound to have some headers, but the following requests will go over web sockets (providing that the browser supports it), which does not contain headers. If there is not headers, there is not Set-Cookie, and without Set-Cookie, there is no cookies. You're right in that the initial request could have one, but it would not be there for the following requests?

    In regards to SSL, I was reasoning like this: You need to have an HTTP profile to be able to use an SSL Client profile, and since the HTTP profile on a VS handling web sockets traffic would be there to support the initial request (and a fallback for clients not supporting WS?), I don't think it'd support accelerating WSS (Web Sockets Secure(?)). Check out this solutions article.

    Some more articles from Lori MacVittie. Most likely a bit biased, but they make sense:

    I'm gonna try to nip this one in the bud.

    /Patrik

  • Look at this devcentral post. If you apply an http profile and cookie persist insert (with no oneconnect), the F5 will return a cookie (if none exists) and then persist the rest of that TCP connection to the same server. You can disable HTTP processing in HTTP_RESPONSE. Then the same cookie could be used in subsequent connections from the same browser to persist to the same server.

     

    This might also solve your SSL issue.

     

  • Hi!

     

    I see what you mean, cookie persistence should actually work since WS only uses one connection.

     

    Still not sure about SSL though but I guess there's only one way to find out! :)

     

    /Patrik

     

  • While we're speculating, here's a crazy thought!

    1. Agree with the developers to add a header section of say, a maximum of 100 bytes. Separated by ";".
    2. An example header could be "site.com;/ireallydislikewebsockets.aspx;"

    Then apply an iRule like this

    when CLIENT_ACCEPTED {
        TCP::collect 100
    }
    
    when CLIENT_DATA {
        set host [getfield [TCP::payload 100] ";" 1]
        set uri [getfield [TCP::payload 100] ";" 2]
        Do something with the iRule    
    }
    

    What do you think? I agree that it's less than optimal, but when life gives you lemons... 🙂

    /Patrik