2016-12-30 02:39:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<!--  BANNER_TPL_BEGIN  -->  
						 
					
						
							
								
									
										
										
										
											2016-12-30 02:22:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								About Daplie: We're taking back the Internet!
							 
						 
					
						
							
								
									
										
										
										
											2016-11-25 10:41:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								--------------
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-30 02:22:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Down with Google, Apple, and Facebook!
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								We're re-decentralizing the web and making it read-write again - one home cloud system at a time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Tired of serving the Empire? Come join the Rebel Alliance:
							 
						 
					
						
							
								
									
										
										
										
											2016-11-25 10:41:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-30 02:22:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								< a  href = "mailto:jobs @daplie .com" > jobs@daplie .com</ a >  | [Invest in Daplie on Wefunder ](https://daplie.com/invest/ ) | [Pre-order Cloud ](https://daplie.com/preorder/ ), The World's First Home Server for Everyone 
						 
					
						
							
								
									
										
										
										
											2016-11-25 10:41:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-30 02:39:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								<!--  BANNER_TPL_END  -->  
						 
					
						
							
								
									
										
										
										
											2016-11-25 10:41:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 13:39:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								[](https://gitter.im/Daplie/letsencrypt-express?utm_source=badge& utm_medium=badge& utm_campaign=pr-badge& utm_content=badge)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 20:48:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								| [letsencrypt (lib) ](https://git.daplie.com/Daplie/node-greenlock )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| [letsencrypt-cli ](https://git.daplie.com/Daplie/greenlock-cli )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| [letsencrypt-express ](https://git.daplie.com/Daplie/greenlock-express )
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 13:39:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								| **letsencrypt-cluster** 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 20:48:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								| [letsencrypt-koa ](https://git.daplie.com/Daplie/greenlock-koa )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| [letsencrypt-hapi ](https://git.daplie.com/Daplie/greenlock-hapi )
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 13:39:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								|
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 20:48:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								greenlock-cluster (letsencrypt-cluster)
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								===================
							 
						 
					
						
							
								
									
										
										
										
											2016-08-10 01:43:11 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Use automatic letsencrypt with node on multiple cores or even multiple machines.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Take advantage of multi-core computing 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Process certificates in master 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Serve https from multiple workers 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  Can work with any clustering strategy [#1 ](https://github.com/Daplie/letsencrypt-cluster/issues/1 ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Install
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								=======
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```bash
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								npm install --save letsencrypt-cluster@2 .x
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Usage
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								=====
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In a cluster environment you have some main file that boots your app
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								and then conditionally loads certain code based on whether that fork
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								is the master or just a worker.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In such a file you might want to define some of the options that need
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								to be shared between both the master and the worker, like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`boot.js` : 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```javascript
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var cluster = require('cluster');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var path = require('path');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var os = require('os');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var main;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var sharedOptions = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  webrootPath: path.join(os.tmpdir(), 'acme-challenge')			// /tmp/acme-challenge
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                            // used by le-challenge-fs, the default plugin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, renewWithin: 10 * 24 *  60 * 60 *  1000 										// 10 days before expiration
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								, debug: true
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if (cluster.isMaster) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main = require('./master');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main = require('./worker');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								main.init(sharedOptions);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Master
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								------
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								We think it makes the most sense to load letsencrypt in master.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								This can prevent race conditions (see [node-letsencrypt#45 ](https://github.com/Daplie/node-letsencrypt/issues/45 ))
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								as only one process is writing the to file system or database at a time.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The main implementation detail here is `approveDomains(options, certs, cb)`  for new domain certificates
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								and potentially `agreeToTerms(opts, cb)`  for new accounts.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:13:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								The master takes **the same arguments**  as `node-letsencrypt`  (`challenge` , `store` , etc),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								plus a few extra (`approveDomains` ... okay, just one extra):
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`master.js` : 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:06:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```javascript
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var cluster = require('cluster');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module.exports.init = function (sharedOpts) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var cores = require('os').cpus();
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var leMaster = require('letsencrypt-cluster/master').create({
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    debug: sharedOpts.debug
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , server: 'staging'                                                       // CHANGE TO PRODUCTION
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , renewWithin: sharedOpts.renewWithin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , webrootPath: sharedOpts.webrootPath
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , approveDomains: function (masterOptions, certs, cb) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // Do any work that must be done by master to approve this domain
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // (in this example, it's assumed to be done by the worker)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var results = { domain: masterOptions.domain                          // required
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    , options: masterOptions                                // domains, email, agreeTos
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    , certs: certs };                                       // altnames, privkey, cert
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cb(null, results);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cores.forEach(function () {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var worker = cluster.fork();
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    leMaster.addWorker(worker);
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								### API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All options are passed directly to `node-letsencrypt` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								(in other works, `leMaster`  is a `letsencrypt`  instance),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								but a few are only actually used by `letsencrypt-cluster` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:56:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  `leOptions.approveDomains(options, certs, cb)`  is special for `letsencrypt-cluster` , but will probably be included in `node-letsencrypt`  in the future (no API change). 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  `leMaster.addWorker(worker)`  is added by `letsencrypt-cluster`  and **must be called**  for each new worker. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Worker
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								------
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The worker takes *similar*  arguments to `node-letsencrypt` ,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								but only ones that are useful for determining certificate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								renewal and for `le.challenge.get` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If you want to  a non-default `le.challenge` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`worker.js` : 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:06:32 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```javascript
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module.exports.init = function (sharedOpts) {
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var leWorker = require('letsencrypt-cluster/worker').create({
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    debug: sharedOpts.debug
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , renewWithin: sharedOpts.renewWithin
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , webrootPath: sharedOpts.webrootPath
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // , challenge: require('le-challenge-fs').create({ webrootPath: '...', ... })
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  , approveDomains: function (workerOptions, certs, cb) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // opts = { domains, email, agreeTos, tosUrl }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // certs = { subject, altnames, expiresAt, issuedAt }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var results = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        domain: workerOptions.domains[0]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      , options: {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          domains: workerOptions.domains
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      , certs: certs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (certs) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // modify opts.domains to match the original request
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // email is not necessary, because the account already exists
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // this will only fail if the account has become corrupt
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        results.options.domains = certs.altnames;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cb(null, results);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // This is where one would check one's application-specific database:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //   1. Lookup the domain to see which email it belongs to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //   2. Assign a default email if it isn't in the system
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //   3. If the email has no le account, `agreeToTerms`  will fire unless `agreeTos`  is preset
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      results.options.email = 'john.doe@example .com'
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      results.options.agreeTos = true                                 // causes agreeToTerms to be skipped
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cb(null, results);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function app(req, res) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    res.end("Hello, World!");
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var redirectHttps = require('redirect-https')();
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var plainServer = require('http').createServer(leWorker.middleware(redirectHttps));
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  plainServer.listen(80);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:48:21 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var server = require('https').createServer(leWorker.httpsOptions, leWorker.middleware(app));
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  server.listen(443);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:56:19 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								### API
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`node-letsencrypt`  is **not used**  directly by the worker, 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								but certain options are shared because certain logic is duplicated.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  `leOptions.renewWithin`  is shared so that the worker knows how earlier to request a new cert 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  `leOptions.renewBy`  is passed to `le-sni-auto`  so that it staggers renewals between `renewWithin`  (latest) and `renewBy`  (earlier) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  `leWorker.middleware(nextApp)`  uses `letsencrypt/middleware`  for GET-ing `http-01` , hence `sharedOptions.webrootPath`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  `leWorker.httpsOptions`  has a default localhost certificate and the `SNICallback` . 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								There are a few options that aren't shown in these examples, so if you need to change something
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								that isn't shown here, look at the code (it's not that much) or open an issue.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-12 03:02:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Message Passing
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								---------------
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The master and workers will communicate through `process.on('message', fn)` , `process.send({})` ,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`worker.on('message', fn)` and `worker.send({})` . 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All messages have a `type`  property which is a string and begins with `LE_` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All other messages are ignored.