-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] sails.config.http.createServerFn (originally re: Add Proxy Protocol support) #3506
base: master
Are you sure you want to change the base?
Conversation
In order to pass websocket traffic through Amazon's elastic load balancers (ELBs), you must force the ELB to proxy TCP traffic instead of HTTP traffic. These proxies are application-level and do not forward network packets verbatim. In order to know the source IP, Amazon allows [Proxy Protocol](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html) (as defined in HAProxy's [spec](http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt)) to be enabled on the ELBs, so the source and destination IP + port can be preserved. As mentioned in balderdashy#3505, this requires a change to the http hook (code mentioned in the issue) and the use of [another module](https://github.com/findhit/proxywrap) to unwrap the TCP traffic and pull off the first line of the request, which contains the Proxy Protocol information. Excerpts from that issue are included here. I would suggest using a flag to the configuration object, such as `proxyProtocol = true` or `http.proxyProtocol = true`. When truthy, Proxy Protocol would be enabled and required. When falsy, Proxy Protocol support would be disabled. Comments from the original issue: > It looks like one could easily add support with code in lib/hooks/http/initialize.js, perhaps roughly at line 50. I don't know if this follows the same coding method as you, so I present it here for your review instead of in a pull request. > > if (sails.config.proxyProtocol == true) { > var httpConnectionElement = usingSSL ? require('https') : require('http'); > var proxiedHttp = require('findhit-proxywrap').proxy(httpConnectionElement); > createServer = proxiedHttp.createServer; > } > > For this code to work, I was told that connectSailsClient() in lib/hooks/sockets/lib/initialize.js (about line 130) needed to be commented out, though I don't know the details and can not elaborate on why this is the case.
Interesting, thanks for posting @fidian. There are a few good reasons not to add code that is this specific to the http hook, foremost of which is that it means we have another dependency ( |
That approach would work wonderfully for us. I agree that it is better than adding another dependency. |
@fidian Awesome! (and thanks for detailing your use case) So to expand on @sgress454's suggestion, and take this a step closer to a full proposal, what about something like this: sails.config.http.createServerFnUsageIn // ...
createServerFn: function (sails) {
// This function receives the Sails app instance (`sails`) as the first argument.
// Should return an HTTP server instance.
// (note that this means this function must be synchronous)
return require('http').createServer();
},
// ...
To implement:Tests
Docs
|
@mikermcneil this looks good! I don't think |
Also, to be clear: I'm not suggesting we make
Perhaps, but as we've seen with generators, there's no way to enforce that it would-- and it usually doesn't :/ I'd rather be opinionated and specific about what the other config does rather than leaving room for interpretation (i.e. and consequently issues & incompatibilities). I think our main priority here needs to be "How do we provide a clean, flexibility abstraction to allow complete customizability in this area without adding any more weight to core in this area over the long term?" |
I attempted to use Proxyquire today to install a Proxywrap'ed set of modules in place of HTTP & HTTPS, but ran into a Proxyquire issue. It should hypothetically be pretty simple:
https://github.com/mfowlewebs/sails-proxywrap/blob/master/sails-proxywrap.js#L4 I do have moderate belief that attacking this problem at a Node level (rather than via creating more API surface to expose) has merit, but I also would affirm that this is probably not an expected use for Proxyquire or something most people would think to go do. I was going to try to compare the memory impact & load time of a vanilla sails & this proxyquired proxywrapped Sails as a first pass evaluation, but can't seem to get this proxyquire approach going: thought I'd post the attempt anyways (with source, for your reproducability). |
Update: was doing really boneheaded things when trying to use proxyquire above. So good news! Using Proxyquire lets one monkeypatch in proxywrap-ed, Proxy Protocol friendly versions of HTTP and HTTPS, giving Sails proxy protocol support. And I have code up on git and also posted on npm too: sails-proxyquire. Replace require("sails") with |
In order to pass websocket traffic through Amazon's elastic load balancers (ELBs), you must force the ELB to proxy TCP traffic instead of HTTP traffic. These proxies are application-level and do not forward network packets verbatim. In order to know the source IP, Amazon allows Proxy Protocol (as defined in HAProxy's spec) to be enabled on the ELBs, so the source and destination IP + port can be preserved.
As mentioned in #3505, this requires a change to the http hook (code mentioned in the issue) and the use of another module to unwrap the TCP traffic and pull off the first line of the request, which contains the Proxy Protocol information. Excerpts from that issue are included here.
I would suggest using a flag to the configuration object, such as
proxyProtocol = true
orhttp.proxyProtocol = true
. When truthy, Proxy Protocol would be enabled and required. When falsy, Proxy Protocol support would be disabled.Comments from the original issue: