Emmett
Emmett

Reputation: 14327

Serve two https hostnames from single node process & port

Is there a way to serve two https sites on the same port from node alone (i.e. without something like nginx)?

I'm using the https module, for which SSL options (e.g. key/cert/ca) are passed into createServer. I tried creating two https servers, each listening to a different hostname, and each with SSL options specific to that hostname:

require('https').createServer(sslOptsForFoo, expressApp).listen(443, 'foo.com');
require('https').createServer(sslOptsForBar, expressApp).listen(443, 'bar.com');

But this throws an error:

Error: listen EADDRINUSE

Another idea is to create a single server rather than two, and to use different SSL options depending on the request's hostname, but I'm not sure if this is possible.

Upvotes: 2

Views: 1140

Answers (1)

mscdex
mscdex

Reputation: 106726

You can only do this with SNI so you may want to check for SNI support with various browsers first.

Here's one way to do SNI in node:

var https = require('https'),
    fs = require('fs');

// default for non-matching requests
var serverOptions = {
  key: fs.readFileSync('default.pem'),
  cert: fs.readFileSync('default.crt')
};

var SNIContexts = {
  'foo.com': {
    key: fs.readFileSync('foo.com.pem'),
    cert: fs.readFileSync('foo.com.crt')
  },
  'bar.com': {
    key: fs.readFileSync('bar.com.pem'),
    cert: fs.readFileSync('bar.com.crt')
  }
};

var server = https.createServer(serverOptions, function(req, res) {
  res.end('Hello world via ' + req.socket.cleartext.servername);
});

server.addContext('foo.com', SNIContexts['foo.com']);
server.addContext('bar.com', SNIContexts['bar.com']);

server.listen(443, function() {
  console.log('Listening on 443');
});

Upvotes: 6

Related Questions