Merge branch 'master' of github.com:coolaj86/node-ssl-root-cas
This commit is contained in:
commit
fc60d1cd03
181
README.md
181
README.md
|
@ -119,3 +119,184 @@ The same dissolution from the terminal would be
|
||||||
export NODE_TLS_REJECT_UNAUTHORIZED="0"
|
export NODE_TLS_REJECT_UNAUTHORIZED="0"
|
||||||
node my-service.js
|
node my-service.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Index
|
||||||
|
|
||||||
|
Other information you might want to know while you're here.
|
||||||
|
|
||||||
|
## Generating an SSL Cert
|
||||||
|
|
||||||
|
Just in case you didn't know, here's how you do it:
|
||||||
|
|
||||||
|
```
|
||||||
|
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
|
||||||
|
```
|
||||||
|
|
||||||
|
**DO NOT FILL OUT** email address, challenge password, or optional company name
|
||||||
|
|
||||||
|
However, you *should* fill out country name, FULL state name, locality name, organization name.
|
||||||
|
|
||||||
|
*organizational unit* is optional.
|
||||||
|
|
||||||
|
```
|
||||||
|
cat server.csr
|
||||||
|
```
|
||||||
|
|
||||||
|
That creates a sha-1 hash.
|
||||||
|
|
||||||
|
When you submit that to the likes of RapidSSL you'll get back an X.509 that you should call `server.crt` (at least for the purposes of this mini-tutorial).
|
||||||
|
|
||||||
|
You cannot use "bundled" certificates (`.pem`) with node.js.
|
||||||
|
|
||||||
|
### A single HTTPS server
|
||||||
|
|
||||||
|
Here's a complete working example:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var https = require('https')
|
||||||
|
, fs = require('fs')
|
||||||
|
, connect = require('connect')
|
||||||
|
, app = connect()
|
||||||
|
, sslOptions
|
||||||
|
, server
|
||||||
|
, port = 4080
|
||||||
|
;
|
||||||
|
|
||||||
|
require('ssl-root-cas/latest')
|
||||||
|
.inject()
|
||||||
|
.addFile(__dirname + '/ssl/Geotrust Cross Root CA.txt')
|
||||||
|
.addFile(__dirname + '/ssl/Rapid SSL CA.txt')
|
||||||
|
;
|
||||||
|
|
||||||
|
sslOptions = {
|
||||||
|
key: fs.readFileSync('./ssl/server.key')
|
||||||
|
, cert: fs.readFileSync('./ssl/server.crt')
|
||||||
|
};
|
||||||
|
|
||||||
|
app.use('/', function (req, res) {
|
||||||
|
res.end('<html><body><h1>Hello World</h1></body></html>');
|
||||||
|
});
|
||||||
|
|
||||||
|
server = https.createServer(sslOptions, app).listen(port, function(){
|
||||||
|
console.log('Listening on https://' + server.address().address + ':' + server.address().port);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiple HTTPS servers using SNI
|
||||||
|
|
||||||
|
I know this works - because I just bought two SSL certs from RapidSSL (through name.com),
|
||||||
|
a Digital Ocean VPS,
|
||||||
|
and played around for an hour until it did.
|
||||||
|
|
||||||
|
:-)
|
||||||
|
|
||||||
|
File hierarchy:
|
||||||
|
|
||||||
|
```
|
||||||
|
webapps/
|
||||||
|
└── vhosts
|
||||||
|
├── aj.the.dj
|
||||||
|
│ └── ssl
|
||||||
|
│ ├── server.crt
|
||||||
|
│ └── server.key
|
||||||
|
├── ballprovo.com
|
||||||
|
│ └── ssl
|
||||||
|
│ ├── server.crt
|
||||||
|
│ └── server.key
|
||||||
|
├── server.js
|
||||||
|
└── ssl
|
||||||
|
├── Geotrust Cross Root CA.txt
|
||||||
|
└── Rapid SSL CA.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### `server.js`
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var https = require('https')
|
||||||
|
, http = require('http')
|
||||||
|
, fs = require('fs')
|
||||||
|
, crypto = require('crypto')
|
||||||
|
, connect = require('connect')
|
||||||
|
, vhost = require('vhost')
|
||||||
|
|
||||||
|
// connect / express app
|
||||||
|
, app = connect()
|
||||||
|
|
||||||
|
// SSL Server
|
||||||
|
, secureContexts = {}
|
||||||
|
, secureOpts
|
||||||
|
, secureServer
|
||||||
|
, securePort = 4443
|
||||||
|
|
||||||
|
// force SSL upgrade server
|
||||||
|
, server
|
||||||
|
, port = 4080
|
||||||
|
|
||||||
|
// the ssl domains I have
|
||||||
|
, domains = ['aj.the.dj', 'ballprovo.com']
|
||||||
|
;
|
||||||
|
|
||||||
|
require('ssl-root-cas/latest')
|
||||||
|
.inject()
|
||||||
|
.addFile(__dirname + '/ssl/Geotrust Cross Root CA.txt')
|
||||||
|
.addFile(__dirname + '/ssl/Rapid SSL CA.txt')
|
||||||
|
;
|
||||||
|
|
||||||
|
function getAppContext(domain) {
|
||||||
|
// Really you'd want to do this:
|
||||||
|
// return require(__dirname + '/' + domain + '/app.js');
|
||||||
|
|
||||||
|
// But for this demo we'll do this:
|
||||||
|
return connect().use('/', function (req, res) {
|
||||||
|
console.log('req.vhost', JSON.stringify(req.vhost));
|
||||||
|
res.end('<html><body><h1>Welcome to ' + domain + '!</h1></body></html>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
domains.forEach(function (domain) {
|
||||||
|
secureContexts[domain] = crypto.createCredentials({
|
||||||
|
key: fs.readFileSync(__dirname + '/' + domain + '/ssl/server.key')
|
||||||
|
, cert: fs.readFileSync(__dirname + '/' + domain + '/ssl/server.crt')
|
||||||
|
}).context;
|
||||||
|
|
||||||
|
app.use(vhost('*.' + domain, getAppContext(domain)));
|
||||||
|
app.use(vhost(domain, getAppContext(domain)));
|
||||||
|
});
|
||||||
|
|
||||||
|
// fallback / default domain
|
||||||
|
app.use('/', function (req, res) {
|
||||||
|
res.end('<html><body><h1>Hello World</h1></body></html>');
|
||||||
|
});
|
||||||
|
|
||||||
|
//provide a SNICallback when you create the options for the https server
|
||||||
|
secureOpts = {
|
||||||
|
//SNICallback is passed the domain name, see NodeJS docs on TLS
|
||||||
|
SNICallback: function (domain) {
|
||||||
|
console.log('SNI:', domain);
|
||||||
|
return secureContexts[domain];
|
||||||
|
}
|
||||||
|
// fallback / default domain
|
||||||
|
, key: fs.readFileSync(__dirname + '/aj.the.dj/ssl/server.key')
|
||||||
|
, cert: fs.readFileSync(__dirname + '/aj.the.dj/ssl/server.crt')
|
||||||
|
};
|
||||||
|
|
||||||
|
secureServer = https.createServer(secureOpts, app).listen(securePort, function(){
|
||||||
|
console.log("Listening on https://localhost:" + secureServer.address().port);
|
||||||
|
});
|
||||||
|
|
||||||
|
server = http.createServer(function (req, res) {
|
||||||
|
res.setHeader(
|
||||||
|
'Location'
|
||||||
|
, 'https://' + req.headers.host.replace(/:\d+/, ':' + securePort)
|
||||||
|
);
|
||||||
|
res.statusCode = 302;
|
||||||
|
res.end();
|
||||||
|
}).listen(port, function(){
|
||||||
|
console.log("Listening on http://localhost:" + server.address().port);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue