AJ ONeal
5 years ago
11 changed files with 540 additions and 395 deletions
@ -0,0 +1,7 @@ |
|||
{ |
|||
"bracketSpacing": true, |
|||
"printWidth": 120, |
|||
"tabWidth": 4, |
|||
"trailingComma": "none", |
|||
"useTabs": false |
|||
} |
@ -1,35 +1,29 @@ |
|||
'use strict'; |
|||
|
|||
var cluster = require('cluster'); |
|||
|
|||
module.exports.init = function (sharedOpts) { |
|||
var numCores = 2; // // Math.max(2, require('os').cpus().length)
|
|||
var i; |
|||
var master = require('../master').create({ |
|||
debug: true |
|||
|
|||
|
|||
|
|||
, server: 'staging' |
|||
, webrootPath: sharedOpts.webrootPath |
|||
|
|||
|
|||
|
|||
, approveDomains: function (masterOptions, certs, cb) { |
|||
// Depending on your setup it may be more efficient
|
|||
// for you to implement the approveDomains function
|
|||
// in your master or in your workers.
|
|||
//
|
|||
// Since we implement it in the worker (below) in this example
|
|||
// we'll give it an immediate approval here in the master
|
|||
var results = { domain: masterOptions.domain, options: masterOptions, certs: certs }; |
|||
cb(null, results); |
|||
"use strict"; |
|||
|
|||
var cluster = require("cluster"); |
|||
|
|||
module.exports.init = function(sharedOpts) { |
|||
var numCores = 2; // // Math.max(2, require('os').cpus().length)
|
|||
var i; |
|||
var master = require("../master").create({ |
|||
debug: true, |
|||
|
|||
server: "staging", |
|||
webrootPath: sharedOpts.webrootPath, |
|||
|
|||
approveDomains: function(masterOptions, certs, cb) { |
|||
// Depending on your setup it may be more efficient
|
|||
// for you to implement the approveDomains function
|
|||
// in your master or in your workers.
|
|||
//
|
|||
// Since we implement it in the worker (below) in this example
|
|||
// we'll give it an immediate approval here in the master
|
|||
var results = { domain: masterOptions.domain, options: masterOptions, certs: certs }; |
|||
cb(null, results); |
|||
} |
|||
}); |
|||
|
|||
for (i = 0; i < numCores; i += 1) { |
|||
master.addWorker(cluster.fork()); |
|||
} |
|||
}); |
|||
|
|||
|
|||
|
|||
for (i = 0; i < numCores; i += 1) { |
|||
master.addWorker(cluster.fork()); |
|||
} |
|||
}; |
|||
|
@ -1,33 +1,27 @@ |
|||
'use strict'; |
|||
"use strict"; |
|||
|
|||
var cluster = require('cluster'); |
|||
var cluster = require("cluster"); |
|||
var main; |
|||
|
|||
|
|||
|
|||
// You'll often see examples where people use cluster
|
|||
// master and worker all in the same file, which is fine,
|
|||
// but in order to conserve memory and especially to be
|
|||
// less confusing, I'm splitting the code into two files
|
|||
if (cluster.isMaster) { |
|||
main = require('./master'); |
|||
} |
|||
else { |
|||
main = require('./worker'); |
|||
main = require("./master"); |
|||
} else { |
|||
main = require("./worker"); |
|||
} |
|||
|
|||
|
|||
|
|||
// this is nothing greenlock-cluster specific
|
|||
// I'm just arbitrarily choosing to share some configuration
|
|||
// that I know I'm going to use in both places
|
|||
main.init({ |
|||
// Depending on the strategy, the whole le-challenge-<<strategy>>
|
|||
// could be shared between worker and server, but since I'm just
|
|||
// using using le-challenge-fs (as you'll see), I'm only sharing the webrootPath
|
|||
webrootPath: require("os").tmpdir() + require("path").sep + "acme-challenge", |
|||
|
|||
// Depending on the strategy, the whole le-challenge-<<strategy>>
|
|||
// could be shared between worker and server, but since I'm just
|
|||
// using using le-challenge-fs (as you'll see), I'm only sharing the webrootPath
|
|||
webrootPath: require('os').tmpdir() + require('path').sep + 'acme-challenge' |
|||
|
|||
// this is used both by node-greenlock (master) and le-sni-auto (worker)
|
|||
, renewWithin: 15 * 24 * 60 * 60 * 1000 |
|||
// this is used both by node-greenlock (master) and le-sni-auto (worker)
|
|||
renewWithin: 15 * 24 * 60 * 60 * 1000 |
|||
}); |
|||
|
@ -1,12 +1,3 @@ |
|||
'use strict'; |
|||
"use strict"; |
|||
|
|||
console.error(""); |
|||
console.error("One does not simply require('greenlock-cluster');"); |
|||
console.error(""); |
|||
console.error("Usage:"); |
|||
console.error("\trequire('greenlock-cluster/master').create({ ... });"); |
|||
console.error("\trequire('greenlock-cluster/worker').create({ ... });"); |
|||
console.error(""); |
|||
console.error(""); |
|||
|
|||
process.exit(1); |
|||
module.exports = require("@root/greenlock-express"); |
|||
|
@ -0,0 +1,149 @@ |
|||
{ |
|||
"name": "greenlock-cluster", |
|||
"version": "3.0.0", |
|||
"lockfileVersion": 1, |
|||
"requires": true, |
|||
"dependencies": { |
|||
"@root/acme": { |
|||
"version": "3.0.8", |
|||
"resolved": "https://registry.npmjs.org/@root/acme/-/acme-3.0.8.tgz", |
|||
"integrity": "sha512-VmBvLvWdCDkolkanI9Dzm1ouSWPaAa2eCCwcDZcVQbWoNiUIOqbbd57fcMA/gZxLyuJPStD2WXFuEuSMPDxcww==", |
|||
"requires": { |
|||
"@root/encoding": "^1.0.1", |
|||
"@root/keypairs": "^0.9.0", |
|||
"@root/pem": "^1.0.4", |
|||
"@root/request": "^1.3.11", |
|||
"@root/x509": "^0.7.2" |
|||
} |
|||
}, |
|||
"@root/asn1": { |
|||
"version": "1.0.0", |
|||
"resolved": "https://registry.npmjs.org/@root/asn1/-/asn1-1.0.0.tgz", |
|||
"integrity": "sha512-0lfZNuOULKJDJmdIkP8V9RnbV3XaK6PAHD3swnFy4tZwtlMDzLKoM/dfNad7ut8Hu3r91wy9uK0WA/9zym5mig==", |
|||
"requires": { |
|||
"@root/encoding": "^1.0.1" |
|||
} |
|||
}, |
|||
"@root/csr": { |
|||
"version": "0.8.1", |
|||
"resolved": "https://registry.npmjs.org/@root/csr/-/csr-0.8.1.tgz", |
|||
"integrity": "sha512-hKl0VuE549TK6SnS2Yn9nRvKbFZXn/oAg+dZJU/tlKl/f/0yRXeuUzf8akg3JjtJq+9E592zDqeXZ7yyrg8fSQ==", |
|||
"requires": { |
|||
"@root/asn1": "^1.0.0", |
|||
"@root/pem": "^1.0.4", |
|||
"@root/x509": "^0.7.2" |
|||
} |
|||
}, |
|||
"@root/encoding": { |
|||
"version": "1.0.1", |
|||
"resolved": "https://registry.npmjs.org/@root/encoding/-/encoding-1.0.1.tgz", |
|||
"integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" |
|||
}, |
|||
"@root/greenlock": { |
|||
"version": "3.0.25", |
|||
"resolved": "https://registry.npmjs.org/@root/greenlock/-/greenlock-3.0.25.tgz", |
|||
"integrity": "sha512-VC8H9MTkbqxlB2LGntmcq5cstkE0TdZLvxm25SO5i7c6abJBVMQafhTD415OXwoGimnmWTn6SZ93Fj73d9QX/w==", |
|||
"requires": { |
|||
"@root/acme": "^3.0.8", |
|||
"@root/csr": "^0.8.1", |
|||
"@root/keypairs": "^0.9.0", |
|||
"@root/mkdirp": "^1.0.0", |
|||
"@root/request": "^1.3.10", |
|||
"acme-http-01-standalone": "^3.0.5", |
|||
"cert-info": "^1.5.1", |
|||
"greenlock-manager-fs": "^3.0.1", |
|||
"greenlock-store-fs": "^3.2.0", |
|||
"safe-replace": "^1.1.0" |
|||
} |
|||
}, |
|||
"@root/greenlock-express": { |
|||
"version": "3.0.13", |
|||
"resolved": "https://registry.npmjs.org/@root/greenlock-express/-/greenlock-express-3.0.13.tgz", |
|||
"integrity": "sha512-SgFsP4rBDPRBp52yqb8kONw7ZCkgyYrBFJLg4xhfIMbsMct4dfqB+N5eJbeF/exJh4+BHM7tppvf31Xuz6EO2Q==", |
|||
"requires": { |
|||
"@root/greenlock": "^3.0.25", |
|||
"redirect-https": "^1.1.5" |
|||
} |
|||
}, |
|||
"@root/keypairs": { |
|||
"version": "0.9.0", |
|||
"resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz", |
|||
"integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==", |
|||
"requires": { |
|||
"@root/encoding": "^1.0.1", |
|||
"@root/pem": "^1.0.4", |
|||
"@root/x509": "^0.7.2" |
|||
} |
|||
}, |
|||
"@root/mkdirp": { |
|||
"version": "1.0.0", |
|||
"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz", |
|||
"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA==" |
|||
}, |
|||
"@root/pem": { |
|||
"version": "1.0.4", |
|||
"resolved": "https://registry.npmjs.org/@root/pem/-/pem-1.0.4.tgz", |
|||
"integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" |
|||
}, |
|||
"@root/request": { |
|||
"version": "1.4.2", |
|||
"resolved": "https://registry.npmjs.org/@root/request/-/request-1.4.2.tgz", |
|||
"integrity": "sha512-J8FM4+SJuc7WRC+Jz17m+VT2lgI7HtatHhxN1F2ck5aIKUAxJEaR4u/gLBsgT60mVHevKCjKN0O8115UtJjwLw==" |
|||
}, |
|||
"@root/x509": { |
|||
"version": "0.7.2", |
|||
"resolved": "https://registry.npmjs.org/@root/x509/-/x509-0.7.2.tgz", |
|||
"integrity": "sha512-ENq3LGYORK5NiMFHEVeNMt+fTXaC7DTS6sQXoqV+dFdfT0vmiL5cDLjaXQhaklJQq0NiwicZegzJRl1ZOTp3WQ==", |
|||
"requires": { |
|||
"@root/asn1": "^1.0.0", |
|||
"@root/encoding": "^1.0.1" |
|||
} |
|||
}, |
|||
"acme-http-01-standalone": { |
|||
"version": "3.0.5", |
|||
"resolved": "https://registry.npmjs.org/acme-http-01-standalone/-/acme-http-01-standalone-3.0.5.tgz", |
|||
"integrity": "sha512-W4GfK+39GZ+u0mvxRVUcVFCG6gposfzEnSBF20T/NUwWAKG59wQT1dUbS1NixRIAsRuhpGc4Jx659cErFQH0Pg==" |
|||
}, |
|||
"cert-info": { |
|||
"version": "1.5.1", |
|||
"resolved": "https://registry.npmjs.org/cert-info/-/cert-info-1.5.1.tgz", |
|||
"integrity": "sha512-eoQC/yAgW3gKTKxjzyClvi+UzuY97YCjcl+lSqbsGIy7HeGaWxCPOQFivhUYm27hgsBMhsJJFya3kGvK6PMIcQ==" |
|||
}, |
|||
"escape-html": { |
|||
"version": "1.0.3", |
|||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", |
|||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" |
|||
}, |
|||
"greenlock-manager-fs": { |
|||
"version": "3.0.1", |
|||
"resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.0.1.tgz", |
|||
"integrity": "sha512-vZfGFq1TTKxaAqdGDUwNservrNzXx0xCwT/ovG/N378GrhS+U5S8B8LUlNtQU7Fdw6RToMiBcm22OOxSrvZ2zw==", |
|||
"requires": { |
|||
"@root/mkdirp": "^1.0.0", |
|||
"safe-replace": "^1.1.0" |
|||
} |
|||
}, |
|||
"greenlock-store-fs": { |
|||
"version": "3.2.0", |
|||
"resolved": "https://registry.npmjs.org/greenlock-store-fs/-/greenlock-store-fs-3.2.0.tgz", |
|||
"integrity": "sha512-zqcPnF+173oYq5qU7FoGtuqeG8dmmvAiSnz98kEHAHyvgRF9pE1T0MM0AuqDdj45I3kXlCj2gZBwutnRi37J3g==", |
|||
"requires": { |
|||
"@root/mkdirp": "^1.0.0", |
|||
"safe-replace": "^1.1.0" |
|||
} |
|||
}, |
|||
"redirect-https": { |
|||
"version": "1.3.0", |
|||
"resolved": "https://registry.npmjs.org/redirect-https/-/redirect-https-1.3.0.tgz", |
|||
"integrity": "sha512-9GzwI/+Cqw3jlSg0CW6TgBQbhiVhkHSDvW8wjgRQ9IK34wtxS71YJiQeazSCSEqbvowHCJuQZgmQFl1xUHKEgg==", |
|||
"requires": { |
|||
"escape-html": "^1.0.3" |
|||
} |
|||
}, |
|||
"safe-replace": { |
|||
"version": "1.1.0", |
|||
"resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz", |
|||
"integrity": "sha512-9/V2E0CDsKs9DWOOwJH7jYpSl9S3N05uyevNjvsnDauBqRowBPOyot1fIvV5N2IuZAbYyvrTXrYFVG0RZInfFw==" |
|||
} |
|||
} |
|||
} |
@ -1,44 +1,40 @@ |
|||
{ |
|||
"name": "greenlock-cluster", |
|||
"version": "2.1.0", |
|||
"description": "Use automatic letsencrypt (free ssl certs) on multiple cores or even multiple machines", |
|||
"main": "index.js", |
|||
"directories": { |
|||
"example": "examples" |
|||
}, |
|||
"dependencies": { |
|||
"le-sni-auto": "^2.0.1", |
|||
"greenlock": "^2.0.4", |
|||
"redirect-https": "^1.1.0" |
|||
}, |
|||
"devDependencies": {}, |
|||
"scripts": { |
|||
"test": "node examples/serve.js" |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js.git" |
|||
}, |
|||
"keywords": [ |
|||
"cluster", |
|||
"acme", |
|||
"le", |
|||
"multi-core", |
|||
"cloud", |
|||
"scale", |
|||
"free", |
|||
"ssl", |
|||
"https", |
|||
"tls", |
|||
"letsencrypt", |
|||
"node", |
|||
"greenlock", |
|||
"node.js" |
|||
], |
|||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |
|||
"license": "(MIT OR Apache-2.0)", |
|||
"bugs": { |
|||
"url": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js/issues" |
|||
}, |
|||
"homepage": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js" |
|||
"name": "greenlock-cluster", |
|||
"version": "3.0.0", |
|||
"description": "Use automatic letsencrypt (free ssl certs) on multiple cores or even multiple machines", |
|||
"main": "index.js", |
|||
"directories": { |
|||
"example": "examples" |
|||
}, |
|||
"dependencies": { |
|||
"@root/greenlock-express": "^3.0.13" |
|||
}, |
|||
"devDependencies": {}, |
|||
"scripts": {}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js.git" |
|||
}, |
|||
"keywords": [ |
|||
"cluster", |
|||
"acme", |
|||
"le", |
|||
"multi-core", |
|||
"cloud", |
|||
"scale", |
|||
"free", |
|||
"ssl", |
|||
"https", |
|||
"tls", |
|||
"letsencrypt", |
|||
"node", |
|||
"greenlock", |
|||
"node.js" |
|||
], |
|||
"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", |
|||
"license": "MPL-2.0", |
|||
"bugs": { |
|||
"url": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js/issues" |
|||
}, |
|||
"homepage": "https://git.coolaj86.com/coolaj86/greenlock-cluster.js" |
|||
} |
|||
|
@ -1,88 +1,78 @@ |
|||
'use strict'; |
|||
"use strict"; |
|||
|
|||
function log(debug) { |
|||
if (!debug) { |
|||
return; |
|||
} |
|||
if (!debug) { |
|||
return; |
|||
} |
|||
|
|||
var args = Array.prototype.slice.call(arguments); |
|||
args.shift(); |
|||
args.unshift("[le/lib/core.js]"); |
|||
console.log.apply(console, args); |
|||
var args = Array.prototype.slice.call(arguments); |
|||
args.shift(); |
|||
args.unshift("[le/lib/core.js]"); |
|||
console.log.apply(console, args); |
|||
} |
|||
|
|||
|
|||
|
|||
module.exports.create = function (opts) { |
|||
|
|||
// if another worker updates the certs,
|
|||
// receive a copy from master here as well
|
|||
// and update the sni cache manually
|
|||
process.on('message', function (msg) { |
|||
if ('LE_RESPONSE' === msg.type && msg.certs) { |
|||
opts.sni.cacheCerts(msg.certs); |
|||
} |
|||
}); |
|||
|
|||
opts.sni = require('le-sni-auto').create({ |
|||
renewWithin: opts.renewWithin || (10 * 24 * 60 * 60 * 1000) |
|||
, renewBy: opts.renewBy || (5 * 24 * 60 * 60 * 1000) |
|||
, getCertificates: function (domain, certs, cb) { |
|||
var workerOptions = { domains: [ domain ] }; |
|||
opts.approveDomains(workerOptions, certs, function (_err, results) { |
|||
if (_err) { |
|||
cb(_err); |
|||
return; |
|||
module.exports.create = function(opts) { |
|||
// if another worker updates the certs,
|
|||
// receive a copy from master here as well
|
|||
// and update the sni cache manually
|
|||
process.on("message", function(msg) { |
|||
if ("LE_RESPONSE" === msg.type && msg.certs) { |
|||
opts.sni.cacheCerts(msg.certs); |
|||
} |
|||
}); |
|||
|
|||
opts.sni = require("le-sni-auto").create({ |
|||
renewWithin: opts.renewWithin || 10 * 24 * 60 * 60 * 1000, |
|||
renewBy: opts.renewBy || 5 * 24 * 60 * 60 * 1000, |
|||
getCertificates: function(domain, certs, cb) { |
|||
var workerOptions = { domains: [domain] }; |
|||
opts.approveDomains(workerOptions, certs, function(_err, results) { |
|||
if (_err) { |
|||
cb(_err); |
|||
return; |
|||
} |
|||
|
|||
process.send({ type: "LE_REQUEST", domain: domain, options: results.options, certs: results.certs }); |
|||
|
|||
process.on("message", function(msg) { |
|||
var err = new Error("___MESSAGE___"); |
|||
|
|||
log(opts.debug, "Message from master"); |
|||
log(opts.debug, msg); |
|||
|
|||
if (msg.domain !== domain) { |
|||
return; |
|||
} |
|||
|
|||
if (msg.error) { |
|||
err.message = msg.error.message || "unknown error sent from cluster master to worker"; |
|||
err.stack.replace("___MESSAGE___", err.message); |
|||
err = { |
|||
message: err.message, |
|||
stack: err.stack, |
|||
data: { options: workerOptions, certs: certs } |
|||
}; |
|||
} else { |
|||
err = null; |
|||
} |
|||
|
|||
cb(err, msg.certs); |
|||
}); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
process.send({ type: 'LE_REQUEST', domain: domain, options: results.options, certs: results.certs }); |
|||
|
|||
process.on('message', function (msg) { |
|||
var err = new Error("___MESSAGE___"); |
|||
|
|||
log(opts.debug, 'Message from master'); |
|||
log(opts.debug, msg); |
|||
|
|||
if (msg.domain !== domain) { |
|||
return; |
|||
} |
|||
|
|||
if (msg.error) { |
|||
err.message = msg.error.message || "unknown error sent from cluster master to worker"; |
|||
err.stack.replace("___MESSAGE___", err.message); |
|||
err = { |
|||
message: err.message |
|||
, stack: err.stack |
|||
, data: { options: workerOptions, certs: certs } |
|||
}; |
|||
} else { |
|||
err = null; |
|||
} |
|||
|
|||
cb(err, msg.certs); |
|||
}); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
|
|||
|
|||
opts.httpsOptions = { SNICallback: opts.sni.sniCallback }; |
|||
|
|||
|
|||
|
|||
opts.challenge = { |
|||
get: opts.getChallenge |
|||
|| (opts.challenge && opts.challenge.get) |
|||
|| require('le-challenge-fs').create({ webrootPath: opts.webrootPath }).get |
|||
}; |
|||
|
|||
|
|||
|
|||
// opts.challenge.get, opts.acmeChallengePrefix
|
|||
opts.middleware = require('greenlock/lib/middleware').create(opts); |
|||
opts.httpsOptions = { SNICallback: opts.sni.sniCallback }; |
|||
|
|||
opts.challenge = { |
|||
get: |
|||
opts.getChallenge || |
|||
(opts.challenge && opts.challenge.get) || |
|||
require("le-challenge-fs").create({ webrootPath: opts.webrootPath }).get |
|||
}; |
|||
|
|||
// opts.challenge.get, opts.acmeChallengePrefix
|
|||
opts.middleware = require("greenlock/lib/middleware").create(opts); |
|||
|
|||
return opts; |
|||
return opts; |
|||
}; |
|||
|
Loading…
Reference in new issue