add letsencrypt

This commit is contained in:
AJ ONeal 2016-03-29 15:03:09 -04:00
parent f99ce93430
commit 671753bb94
7 changed files with 144 additions and 15 deletions

View File

@ -1 +0,0 @@
walnut

65
bin/walnut.js Executable file
View File

@ -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);

View File

@ -63,6 +63,7 @@ cluster.on('online', function (worker) {
, 'org.oauth3.consumer': config['org.oauth3.consumer']
, 'org.oauth3.provider': config['org.oauth3.provider']
, keys: config.keys
, letsencrypt: config.letsencrypt
}
};
worker.send(info);

View File

@ -4,9 +4,9 @@ module.exports.create = function (opts) {
var id = '0';
var promiseApp;
function createAndBindInsecure(message, cb) {
function createAndBindInsecure(lex, message, cb) {
// 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');
// 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) {
var lex;
if (message.conf.letsencrypt) {
lex = createLe(message.conf);
}
// 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) {
console.error('[ERROR] worker.js');
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
process.nextTick(function () {
createAndBindInsecure(message, cb);
createAndBindInsecure(lex, message, cb);
});
// we are returning the promise result to the caller

View File

@ -1,6 +1,6 @@
'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 appPromise;
//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/
// 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)) {
return true;
}
@ -103,7 +103,13 @@ module.exports.create = function (securePort, insecurePort, info, serverCallback
appPromise = serverCallback(null, insecureServer);
}
});
if (lex) {
var LEX = require('letsencrypt-express');
insecureServer.on('request', LEX.createAcmeResponder(lex, redirectHttps));
} else {
insecureServer.on('request', redirectHttps);
}
return PromiseA.resolve(insecureServer);
};

View File

@ -2,7 +2,7 @@
// Note the odd use of callbacks (instead of promises) here
// 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) {
var app;
var promiseApp;
@ -29,7 +29,7 @@ module.exports.create = function (certPaths, port, info, serverCallback) {
*/
// 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
if (app) {
app(req, res);
@ -41,11 +41,18 @@ module.exports.create = function (certPaths, port, info, serverCallback) {
app = _app;
app(req, res);
});
});
}
if (lex) {
var LEX = require('letsencrypt-express');
server.on('request', LEX.createAcmeResponder(lex, onRequest));
} else {
server.on('request', onRequest);
}
}
if (certPaths) {
require('./sni-server').create(certPaths, initServer);
require('./sni-server').create(lex, certPaths, initServer);
} else {
initServer(null, require('http').createServer());
}

View File

@ -5,9 +5,10 @@
// require everything as lazily as possible until our server
// is actually listening on the socket. Bluebird is heavy.
// 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
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() {
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://nodejs.org/api/tls.html
// 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
};
@ -43,5 +44,15 @@ module.exports.create = function (certPaths, serverCallback) {
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();
}
};

View File

@ -81,6 +81,7 @@
"json-storage": "2.x",
"jsonwebtoken": "^5.4.0",
"lodash": "2.x",
"letsencrypt-express": "1.1.x",
"masterquest-sqlite3": "git://github.com/coolaj86/masterquest-sqlite3.git",
"media-typer": "^0.3.0",
"methods": "^1.1.1",