Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

node.js - Is it Possible to Dynamically Return an SSL Certificate in NodeJS?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...