Question

This doesn't seem to be working right now. I'm using Faye with NodeJS behind an Amazon ELB. When I switch on HTTPS the connections can no longer be brokered. I found a question here unanswered: https://forums.aws.amazon.com/message.jspa?messageID=283293 . Anyone able to get this working? Are there any work around outside of running my own instance of HAProxy?

Était-ce utile?

La solution

I confirm, based on our own tests, that configuring ELB on TCP/SSL, instead oh HTTP/HTTPS, makes the trick with WebSockets. The drawbacks are two:

1) As already pointed by arturnt, you cannot get stickyness.

2) You will lose the ability to retrieve the identity of the clients. The originating IP seen by your WebSocket server will be always the ELB one and, differently from the HTTP/HTTPS configuration, no X-Forwarded-For header will be added to the requests.

UPDATE July 2013: Amazon has just added support for Proxy Protocol, which solves drawback number 2 above. With the Proxy Protocol, a header containing the client's originating IP is added even when ELB works at TCP level, rather than HTTP. Full details: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html

UPDATE August 2016: Amazon has just announced new AWS Application Load Balancer, which supports WebSocket at Layer 7 (as well as HTTP/2.0 and content-based routing). See https://aws.amazon.com/it/blogs/aws/new-aws-application-load-balancer/

Autres conseils

It won't work, the ELB's HTTP(S) proxy does not understand websocket requests, for now at least, and I don't know when/if it's planned.

I'm not sure HAProxy is completely necessary though. It should be possible to put an SSL terminator, e.g. stud/stunnel, on the same instance as your nodejs servers and pass through that way. You can then keep the ELB, but put it in TCP mode.

Obviously there's the SSL overhead on each instance, but in the long run that probably scales better than offloading the SSL to ELB (particularly based on users' comments on ELB's SSL performance).

After James' answer I did a little bit more research and ended up going to the TCP route, not sure there are any disadvantages of that over using the HTTP tunneling of ELB (considering I don't need stickiness). The good thing is that you don't need to do stud/stunnel since ELB provides that for you. So final ELB setup where NodeJS/Faye are listening on port 8000:

Secure TCP Forward (443) -> Local (8000)
TCP Forward 80 -> Local(8000)

You could use Application LB to support websocket well. I just implemented this idea on our latest project after implemented some tricks on ALB:

  1. open 80 port on all related SGs
  2. make NodeJS running on 80
  3. enable NodeJS responding http-80 request (NodeJS will upgrade http request to websocket in the backend)
  4. make ALB target group check http-80 & correct ping path
  5. create listeners on ALB: http80->http80, https443->http80
  6. create listener rules on ALB: http80->target group, https443->target group
  7. Enable http stickiness in
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top