Node-http-proxy: How is it possible to have multiple HTTPS proxies

Created on 24 Dec 2016  路  5Comments  路  Source: http-party/node-http-proxy

How is it possible to have multiple HTTPS -> HTTP proxies?

Seems like I can't do something like in this example for HTTP -> HTTP:

http.createServer(function(req, res) {
  proxy.web(req, res, { target: 'http://mytarget.com:8080' });
});

because for each server instance I should provide certificate.

I found SNICallback in https options but I don't know is it right approach and how to use it.

Most helpful comment

@SET001 this technically doesnt have anything to do with node-http-proxy. This has to do with handling multiple SSL certs from a single https server. You are correct in that using SNICallback is the right approach. You should search for more examples and try it out yourself. I found this blog post and improved their example below.

var https = require("https");
var tls = require("tls");
var constants = require("constants");
var fs = require("fs");

var passphrase = "Your password here";
var certificates = {
  "foo.com": { key: fs.readFileSync("fookey.pem"), cert: fs.readFileSync("foocert.pem") },
  "bar.com": { key: fs.readFileSync("barkey.pem"), cert: fs.readFileSync("barcert.pem") }
};
https.createServer({
    key: fs.readFileSync(__dirname + "/yourkey.pem"),
    cert: fs.readFileSync(__dirname + "/yourcert.pem"),
    passphrase: passphrase,
    SNICallback: function(servername, cb) {

        if (certificates[servername]) {
            var ctx = tls.createSecureContext(Object.assign({ passphrase}, certificates[servername]}));
            // Compatibility with old versions of node
            if (cb) {
                cb(null, ctx);
            } else {
                return ctx;
            }
        }
    }
}, function(req, res) {
    res.end("Hello, SSL World!");
}).listen(443, function() {
    console.log("SSL Proxy listening on port 443");
});

All 5 comments

@SET001 this technically doesnt have anything to do with node-http-proxy. This has to do with handling multiple SSL certs from a single https server. You are correct in that using SNICallback is the right approach. You should search for more examples and try it out yourself. I found this blog post and improved their example below.

var https = require("https");
var tls = require("tls");
var constants = require("constants");
var fs = require("fs");

var passphrase = "Your password here";
var certificates = {
  "foo.com": { key: fs.readFileSync("fookey.pem"), cert: fs.readFileSync("foocert.pem") },
  "bar.com": { key: fs.readFileSync("barkey.pem"), cert: fs.readFileSync("barcert.pem") }
};
https.createServer({
    key: fs.readFileSync(__dirname + "/yourkey.pem"),
    cert: fs.readFileSync(__dirname + "/yourcert.pem"),
    passphrase: passphrase,
    SNICallback: function(servername, cb) {

        if (certificates[servername]) {
            var ctx = tls.createSecureContext(Object.assign({ passphrase}, certificates[servername]}));
            // Compatibility with old versions of node
            if (cb) {
                cb(null, ctx);
            } else {
                return ctx;
            }
        }
    }
}, function(req, res) {
    res.end("Hello, SSL World!");
}).listen(443, function() {
    console.log("SSL Proxy listening on port 443");
});

@jcrugzz , thanx for you respond. I think it has to do with node-http-proxy because I need to proxy multiple sub-domain calls to multiple servers running each on different ports. Something like this:

https://a.foo.com -> 127.0.0.1:3000
https://b.foo.com -> 127.0.0.1:3001
https://c.foo.com -> 127.0.0.1:3002

also I have a certificates for each of this domain.

SNICallback will be called each time new connection to any of this sub-domains appears and I don't get how to proxy that connection to appropriate local server.
Also I'm lucking experience with express and node.js so I may miss something obvious here

A * based cert would make this easier ;) but doesnt matter either way. @SET001 check out the documentation as it gives examples of this. The proper cert will be handled by the SNICallback. You need to then proxy to a different target based on the req.headers.host. You can store a them similar to the certs above.

var targets = {
  'a.foo.com': 'http://127.0.0.1:3000'
};

If you have anymore questions please ask on Stackoverflow or somewhere similar. If you find a bug or issue with http-proxy please feel free to open a new issue. Have fun :)

What I still can't understand is that I have few *.key/*.cer files for all subdomains which i get from letsencrypt.org (they are not supporting wildcard certificates atm) and which I will use in SNICallback like in your code. But I also should put one pair to https.createServer. What certificates should it be?

I have also created question on StackOverflow but with no responses. So for now, you are the only one helping me to figure out all this hell, for which I am very grateful to you.

@SET001 Have you figured this out yet? I'm in the same situation right now

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lgzhang picture lgzhang  路  4Comments

damianchojna picture damianchojna  路  5Comments

catamphetamine picture catamphetamine  路  6Comments

jsmylnycky picture jsmylnycky  路  3Comments

mbret picture mbret  路  5Comments