I want to dynamically return an ssl certificate info in my NodeJS application. I have two domain names linked to the same node application. I only see that the ssl settings can be specified when the server is created. Is it possible to dynamically return ssl certificates based on the requested url?
Otherwise, if I must instead create a second sever instance on another port, will I be able to transparently pipe each request to the original port? Can I make it appear like it's not running on a second port?
Thanks, Jeff
Dynamic routing certificate. The certificate that is presented by the plug-in to the controller when the plug-in tries to connect to the dynamic routing service on a collective controller.
The SSL kicks in immediately when installed. Let's encrypt SSL installations need a few minutes. The Premium SSL certificates are installed within a few hours in most cases.
Our results indicate that 0.2% of the SSL connections analyzed were tampered with forged SSL certificates, most of them related to antivirus software and corporate-scale content filters. We have also identified some SSL connections intercepted by malware.
Yes, it is possible to do it with one server. But the caveat is that it works on clients that support SNI - which is most modern browsers.
This is how you do it:
//function to pick out the key + certs dynamically based on the domain name function getSecureContext (domain) { return crypto.createCredentials({ key: fs.readFileSync('/path/to/domain.key'), cert: fs.readFileSync('/path/to/domain.crt'), ca: [fs.readFileSync('/path/to/CA_cert_1.crt'), fs.readFileSync('/path/to/CA_cert_2.crt'), <include all CA certs that you have to> ... ] }).context; } //read them into memory var secureContext = { 'domain1': getSecureContext('domain1'), 'domain2': getSecureContext('domain2'), . . } //provide a SNICallback when you create the options for the https server var options = { SNICallback: function (domain) { return secureContext[domain]; }, //SNICallback is passed the domain name, see NodeJS docs on TLS cert: fs.readFileSync('/path/to/server.crt'), key: fs.readFileSync('/path/to/server.key'), } } //create your https server var server = require('https').createServer(options, [requestListener]); //using Express var server = require('https').createServer(options, require('express')()); server.listen(<someport>);
This works because the options for https is similar to tls.createServer(). Make sure you include all required CA intermediate and root certificates in the crypto.createCredentials call. Also if you have a CA bundle, split them up into multiple single crt files before using them as 'ca' accepts an array of certificates.
crypto.createCredentials()
is deprecated, so use tls.createSecureContext()
instead.
tls.createServer() must have key
and cert
in the options, because they are required in the manual. Perhaps tls.createServer()
uses these parameters as defaults in case SNICallback
is not supported.
var secureContext = { 'mydomain.com': tls.createSecureContext({ key: fs.readFileSync('../path_to_key1.pem', 'utf8'), cert: fs.readFileSync('../path_to_cert1.crt', 'utf8'), ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle1', 'utf8'), // this ca property is optional }), 'myotherdomain.com': tls.createSecureContext({ key: fs.readFileSync('../path_to_key2.pem', 'utf8'), cert: fs.readFileSync('../path_to_cert2.crt', 'utf8'), ca: fs.readFileSync('../path_to_certificate_authority_bundle.ca-bundle2', 'utf8'), // this ca property is optional }), } try { var options = { SNICallback: function (domain, cb) { if (secureContext[domain]) { if (cb) { cb(null, secureContext[domain]); } else { // compatibility for older versions of node return secureContext[domain]; } } else { throw new Error('No keys/certificates for domain requested'); } }, // must list a default key and cert because required by tls.createServer() key: fs.readFileSync('../path_to_key.pem'), cert: fs.readFileSync('../path_to_cert.crt'), } https.createServer(options, function (req, res) { res.end('Your dynamic SSL server worked!') // Here you can put proxy server routing here to send the request // to the application of your choosing, running on another port. // node-http-proxy is a great npm package for this }).listen(443); } catch (err){ console.error(err.message); console.error(err.stack); }
Inside the server you can use nodejs package http-proxy to route your https request to your various applications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With