add letsencrypt
This commit is contained in:
parent
f99ce93430
commit
671753bb94
|
@ -1 +0,0 @@
|
||||||
walnut
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('../walnut.js');
|
||||||
|
/*
|
||||||
|
var c = require('console-plus');
|
||||||
|
console.log = c.log;
|
||||||
|
console.error = c.error;
|
||||||
|
*/
|
||||||
|
|
||||||
|
function eagerLoad() {
|
||||||
|
var PromiseA = require('bluebird').Promise;
|
||||||
|
var promise = PromiseA.resolve();
|
||||||
|
|
||||||
|
[ 'express'
|
||||||
|
, 'request'
|
||||||
|
, 'sqlite3'
|
||||||
|
, 'body-parser'
|
||||||
|
, 'urlrouter'
|
||||||
|
, 'express-lazy'
|
||||||
|
, 'connect-send-error'
|
||||||
|
, 'underscore.string'
|
||||||
|
, 'secret-utils'
|
||||||
|
, 'connect-cors'
|
||||||
|
, 'uuid'
|
||||||
|
, 'connect-recase'
|
||||||
|
, 'escape-string-regexp'
|
||||||
|
, 'connect-query'
|
||||||
|
, 'recase'
|
||||||
|
].forEach(function (name/*, i*/) {
|
||||||
|
promise = promise.then(function () {
|
||||||
|
return new PromiseA(function (resolve/*, reject*/) {
|
||||||
|
setTimeout(function () {
|
||||||
|
require(name);
|
||||||
|
resolve();
|
||||||
|
}, 4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
[ function () {
|
||||||
|
require('body-parser').json();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// do not use urlencoded as it enables csrf
|
||||||
|
, function () {
|
||||||
|
require('body-parser').urlencoded();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
].forEach(function (fn) {
|
||||||
|
promise = promise.then(function (thing) {
|
||||||
|
return new PromiseA(function (resolve) {
|
||||||
|
setTimeout(function () {
|
||||||
|
resolve(fn(thing));
|
||||||
|
}, 4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(function () {
|
||||||
|
console.log('Eager Loading Complete');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(eagerLoad, 100);
|
|
@ -63,6 +63,7 @@ cluster.on('online', function (worker) {
|
||||||
, 'org.oauth3.consumer': config['org.oauth3.consumer']
|
, 'org.oauth3.consumer': config['org.oauth3.consumer']
|
||||||
, 'org.oauth3.provider': config['org.oauth3.provider']
|
, 'org.oauth3.provider': config['org.oauth3.provider']
|
||||||
, keys: config.keys
|
, keys: config.keys
|
||||||
|
, letsencrypt: config.letsencrypt
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
worker.send(info);
|
worker.send(info);
|
||||||
|
|
|
@ -4,9 +4,9 @@ module.exports.create = function (opts) {
|
||||||
var id = '0';
|
var id = '0';
|
||||||
var promiseApp;
|
var promiseApp;
|
||||||
|
|
||||||
function createAndBindInsecure(message, cb) {
|
function createAndBindInsecure(lex, message, cb) {
|
||||||
// TODO conditional if 80 is being served by caddy
|
// TODO conditional if 80 is being served by caddy
|
||||||
require('../lib/insecure-server').create(message.conf.externalPort, message.conf.insecurePort, message, function (err, webserver) {
|
require('../lib/insecure-server').create(lex, message.conf.externalPort, message.conf.insecurePort, message, function (err, webserver) {
|
||||||
console.info("#" + id + " Listening on http://" + webserver.address().address + ":" + webserver.address().port, '\n');
|
console.info("#" + id + " Listening on http://" + webserver.address().address + ":" + webserver.address().port, '\n');
|
||||||
|
|
||||||
// we are returning the promise result to the caller
|
// we are returning the promise result to the caller
|
||||||
|
@ -14,9 +14,48 @@ module.exports.create = function (opts) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createLe(conf) {
|
||||||
|
var LEX = require('letsencrypt-express');
|
||||||
|
var lex = LEX.create({
|
||||||
|
configDir: conf.letsencrypt.configDir // i.e. __dirname + '/letsencrypt.config'
|
||||||
|
, approveRegistration: function (hostname, cb) {
|
||||||
|
cb(null, {
|
||||||
|
domains: [hostname] // TODO handle www and bare on the same cert
|
||||||
|
, email: conf.letsencrypt.email
|
||||||
|
, agreeTos: conf.letsencrypt.agreeTos
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
letsencrypt.getConfig({ domains: [domain] }, function (err, config) {
|
||||||
|
if (!(config && config.checkpoints >= 0)) {
|
||||||
|
cb(err, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(null, {
|
||||||
|
email: config.email
|
||||||
|
// can't remember which it is, but the pyconf is different that the regular variable
|
||||||
|
, agreeTos: config.tos || config.agree || config.agreeTos
|
||||||
|
, server: config.server || LE.productionServerUrl
|
||||||
|
, domains: config.domains || [domain]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//var letsencrypt = lex.letsencrypt;
|
||||||
|
|
||||||
|
return lex;
|
||||||
|
}
|
||||||
|
|
||||||
function createAndBindServers(message, cb) {
|
function createAndBindServers(message, cb) {
|
||||||
|
var lex;
|
||||||
|
|
||||||
|
if (message.conf.letsencrypt) {
|
||||||
|
lex = createLe(message.conf);
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE that message.conf[x] will be overwritten when the next message comes in
|
// NOTE that message.conf[x] will be overwritten when the next message comes in
|
||||||
require('../lib/local-server').create(message.conf.certPaths, message.conf.localPort, message, function (err, webserver) {
|
require('../lib/local-server').create(lex, message.conf.certPaths, message.conf.localPort, message, function (err, webserver) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('[ERROR] worker.js');
|
console.error('[ERROR] worker.js');
|
||||||
console.error(err.stack);
|
console.error(err.stack);
|
||||||
|
@ -27,7 +66,7 @@ module.exports.create = function (opts) {
|
||||||
|
|
||||||
// we don't need time to pass, just to be able to return
|
// we don't need time to pass, just to be able to return
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
createAndBindInsecure(message, cb);
|
createAndBindInsecure(lex, message, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
// we are returning the promise result to the caller
|
// we are returning the promise result to the caller
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports.create = function (securePort, insecurePort, info, serverCallback) {
|
module.exports.create = function (lex, securePort, insecurePort, info, serverCallback) {
|
||||||
var PromiseA = require('bluebird').Promise;
|
var PromiseA = require('bluebird').Promise;
|
||||||
var appPromise;
|
var appPromise;
|
||||||
//var app;
|
//var app;
|
||||||
|
@ -42,7 +42,7 @@ module.exports.create = function (securePort, insecurePort, info, serverCallback
|
||||||
// http://evothings.com/is-it-possible-to-secure-micro-controllers-used-within-iot/
|
// http://evothings.com/is-it-possible-to-secure-micro-controllers-used-within-iot/
|
||||||
// needs ECDSA?
|
// needs ECDSA?
|
||||||
|
|
||||||
console.warn('HARD-CODED HTTPS EXCEPTION in insecure-server.js');
|
console.warn('HARD-CODED HTTPS EXCEPTION in insecure-server.js for redirect-www.org');
|
||||||
if (/redirect-www.org$/.test(host) && useAppInsecurely(req, res)) {
|
if (/redirect-www.org$/.test(host) && useAppInsecurely(req, res)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,13 @@ module.exports.create = function (securePort, insecurePort, info, serverCallback
|
||||||
appPromise = serverCallback(null, insecureServer);
|
appPromise = serverCallback(null, insecureServer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (lex) {
|
||||||
|
var LEX = require('letsencrypt-express');
|
||||||
|
insecureServer.on('request', LEX.createAcmeResponder(lex, redirectHttps));
|
||||||
|
} else {
|
||||||
insecureServer.on('request', redirectHttps);
|
insecureServer.on('request', redirectHttps);
|
||||||
|
}
|
||||||
|
|
||||||
return PromiseA.resolve(insecureServer);
|
return PromiseA.resolve(insecureServer);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// Note the odd use of callbacks (instead of promises) here
|
// Note the odd use of callbacks (instead of promises) here
|
||||||
// It's to avoid loading bluebird yet (see sni-server.js for explanation)
|
// It's to avoid loading bluebird yet (see sni-server.js for explanation)
|
||||||
module.exports.create = function (certPaths, port, info, serverCallback) {
|
module.exports.create = function (lex, certPaths, port, info, serverCallback) {
|
||||||
function initServer(err, server) {
|
function initServer(err, server) {
|
||||||
var app;
|
var app;
|
||||||
var promiseApp;
|
var promiseApp;
|
||||||
|
@ -29,7 +29,7 @@ module.exports.create = function (certPaths, port, info, serverCallback) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Get up and listening as absolutely quickly as possible
|
// Get up and listening as absolutely quickly as possible
|
||||||
server.on('request', function (req, res) {
|
function onRequest(req, res) {
|
||||||
// this is a hot piece of code, so we cache the result
|
// this is a hot piece of code, so we cache the result
|
||||||
if (app) {
|
if (app) {
|
||||||
app(req, res);
|
app(req, res);
|
||||||
|
@ -41,11 +41,18 @@ module.exports.create = function (certPaths, port, info, serverCallback) {
|
||||||
app = _app;
|
app = _app;
|
||||||
app(req, res);
|
app(req, res);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (lex) {
|
||||||
|
var LEX = require('letsencrypt-express');
|
||||||
|
server.on('request', LEX.createAcmeResponder(lex, onRequest));
|
||||||
|
} else {
|
||||||
|
server.on('request', onRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (certPaths) {
|
if (certPaths) {
|
||||||
require('./sni-server').create(certPaths, initServer);
|
require('./sni-server').create(lex, certPaths, initServer);
|
||||||
} else {
|
} else {
|
||||||
initServer(null, require('http').createServer());
|
initServer(null, require('http').createServer());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
// require everything as lazily as possible until our server
|
// require everything as lazily as possible until our server
|
||||||
// is actually listening on the socket. Bluebird is heavy.
|
// is actually listening on the socket. Bluebird is heavy.
|
||||||
// Even the built-in modules can take dozens of milliseconds to require
|
// Even the built-in modules can take dozens of milliseconds to require
|
||||||
module.exports.create = function (certPaths, serverCallback) {
|
module.exports.create = function (lex, certPaths, serverCallback) {
|
||||||
// Recognize that this secureContexts cache is local to this CPU core
|
// Recognize that this secureContexts cache is local to this CPU core
|
||||||
var secureContexts = {};
|
var secureContexts = {};
|
||||||
|
var ciphers = 'ECDH+AESGCM:DH+AESGCM:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256';
|
||||||
|
|
||||||
function createSecureServer() {
|
function createSecureServer() {
|
||||||
var domainname = 'www.example.com';
|
var domainname = 'www.example.com';
|
||||||
|
@ -21,7 +22,7 @@ module.exports.create = function (certPaths, serverCallback) {
|
||||||
// https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
|
// https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
|
||||||
// https://nodejs.org/api/tls.html
|
// https://nodejs.org/api/tls.html
|
||||||
// removed :ECDH+AES256:DH+AES256 and added :!AES256 because AES-256 wastes CPU
|
// removed :ECDH+AES256:DH+AES256 and added :!AES256 because AES-256 wastes CPU
|
||||||
, ciphers: 'ECDH+AESGCM:DH+AESGCM:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS:!AES256'
|
, ciphers: ciphers
|
||||||
, honorCipherOrder: true
|
, honorCipherOrder: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,5 +44,15 @@ module.exports.create = function (certPaths, serverCallback) {
|
||||||
serverCallback(null, require('https').createServer(secureOpts));
|
serverCallback(null, require('https').createServer(secureOpts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createLeServer() {
|
||||||
|
lex.httpsOptions.ciphers = ciphers;
|
||||||
|
lex.httpsOptions.honorCipherOrder = true;
|
||||||
|
serverCallback(null, require('https').createServer(lex.httpsOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lex) {
|
||||||
|
createLeServer();
|
||||||
|
} else {
|
||||||
createSecureServer();
|
createSecureServer();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
"json-storage": "2.x",
|
"json-storage": "2.x",
|
||||||
"jsonwebtoken": "^5.4.0",
|
"jsonwebtoken": "^5.4.0",
|
||||||
"lodash": "2.x",
|
"lodash": "2.x",
|
||||||
|
"letsencrypt-express": "1.1.x",
|
||||||
"masterquest-sqlite3": "git://github.com/coolaj86/masterquest-sqlite3.git",
|
"masterquest-sqlite3": "git://github.com/coolaj86/masterquest-sqlite3.git",
|
||||||
"media-typer": "^0.3.0",
|
"media-typer": "^0.3.0",
|
||||||
"methods": "^1.1.1",
|
"methods": "^1.1.1",
|
||||||
|
|
Loading…
Reference in New Issue