turn off debug mode, add more docs & examples
This commit is contained in:
		
							parent
							
								
									1f1b0d7ebc
								
							
						
					
					
						commit
						b4b3c0497a
					
				
							
								
								
									
										135
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								README.md
									
									
									
									
									
								
							| @ -5,11 +5,11 @@ Automatic [Let's Encrypt](https://lettsencrypt.org) HTTPS Certificates for node. | |||||||
| 
 | 
 | ||||||
|   * Automatic HTTPS with ExpressJS |   * Automatic HTTPS with ExpressJS | ||||||
|   * Automatic live renewal (in-process) |   * Automatic live renewal (in-process) | ||||||
|   * safe for use with node's cluster module |   * On-the-fly HTTPS certificates for Dynamic DNS (in-process, no server restart) | ||||||
|   * configurable for automatic registration (in-process) |   * Works with node cluster out of the box | ||||||
|   * usable via commandline as well |   * usable via commandline as well | ||||||
|   * [90-day certificates](https://letsencrypt.org/2015/11/09/why-90-days.html) |  | ||||||
|   * Free SSL (HTTPS Certificates for TLS) |   * Free SSL (HTTPS Certificates for TLS) | ||||||
|  |   * [90-day certificates](https://letsencrypt.org/2015/11/09/why-90-days.html) | ||||||
| 
 | 
 | ||||||
| Install | Install | ||||||
| ======= | ======= | ||||||
| @ -48,15 +48,142 @@ le.register({ | |||||||
| **However**, due to the nature of what this library does, it has a few more "moving parts" | **However**, due to the nature of what this library does, it has a few more "moving parts" | ||||||
| than what makes sense to show in a minimal snippet. | than what makes sense to show in a minimal snippet. | ||||||
| 
 | 
 | ||||||
|  | ### One Time Registration | ||||||
|  | 
 | ||||||
| * [commandline (standalone with "webroot")](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline.js) | * [commandline (standalone with "webroot")](https://github.com/Daplie/node-letsencrypt/blob/master/examples/commandline.js) | ||||||
| 
 | 
 | ||||||
|  | ```javascript | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var LE = require('letsencrypt'); | ||||||
|  | var config = require('./config-minimal'); | ||||||
|  | 
 | ||||||
|  | // Note: you should make this special dir in your product and leave it empty | ||||||
|  | config.le.webrootPath = __dirname + '/../tests/acme-challenge'; | ||||||
|  | config.le.server = LE.stagingServer; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Manual Registration | ||||||
|  | // | ||||||
|  | var le = LE.create(config.backend, config.le); | ||||||
|  | le.register({ | ||||||
|  |   agreeTos: true | ||||||
|  | , domains: ['example.com']          // CHANGE TO YOUR DOMAIN | ||||||
|  | , email: 'user@email.com'           // CHANGE TO YOUR EMAIL | ||||||
|  | }, function (err) { | ||||||
|  |   if (err) { | ||||||
|  |     console.error('[Error]: node-letsencrypt/examples/standalone'); | ||||||
|  |     console.error(err.stack); | ||||||
|  |   } else { | ||||||
|  |     console.log('success'); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   plainServer.close(); | ||||||
|  |   tlsServer.close(); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Express App | ||||||
|  | // | ||||||
|  | var app = require('express')(); | ||||||
|  | app.use('/', le.middleware()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // HTTP & HTTPS servers | ||||||
|  | // (required for domain validation) | ||||||
|  | // | ||||||
|  | var plainServer = require('http').createServer(app).listen(config.plainPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | var tlsServer = require('https').createServer({ | ||||||
|  |   key: config.tlsKey | ||||||
|  | , cert: config.tlsCert | ||||||
|  | , SNICallback: le.sniCallback | ||||||
|  | }, app).listen(config.tlsPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ```bash | ```bash | ||||||
| # manual standalone registration via commandline | # manual standalone registration via commandline | ||||||
| # (runs against testing server on tls port 5001) | # (runs against testing server on tls port 5001) | ||||||
| node examples/commandline.js example.com,www.example.com user@example.net agree | node examples/commandline.js example.com,www.example.com user@example.net agree | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| * [expressjs (fully automatic https)](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express.js) | ### Express | ||||||
|  | 
 | ||||||
|  | Fully Automatic HTTPS with ExpressJS using Free SSL certificates from Let's Encrypt | ||||||
|  | 
 | ||||||
|  | * [Minimal ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express-minimal.js) | ||||||
|  | 
 | ||||||
|  | ```javascript | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var LE = require('letsencrypt'); | ||||||
|  | var config = require('./config-minimal'); | ||||||
|  | 
 | ||||||
|  | // Note: you should make this special dir in your product and leave it empty | ||||||
|  | config.le.webrootPath = __dirname + '/../tests/acme-challenge'; | ||||||
|  | config.le.server = LE.stagingServer; | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Automatically Register / Renew Domains | ||||||
|  | // | ||||||
|  | var le = LE.create(config.backend, config.le, { | ||||||
|  |   sniRegisterCallback: function (args, expiredCert, cb) { | ||||||
|  |     // Security: check that this is actually a subdomain we allow | ||||||
|  |     // (otherwise an attacker can cause you to rate limit against the LE server) | ||||||
|  | 
 | ||||||
|  |     var hostname = args.domains[0]; | ||||||
|  |     if (!/\.example\.com$/.test(hostname)) { | ||||||
|  |       console.error("bad domain '" + hostname + "', not a subdomain of example.com"); | ||||||
|  |       cb(nul, null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // agree to the LE TOS for this domain | ||||||
|  |     args.agreeTos = true; | ||||||
|  |     args.email = 'user@example.com'; | ||||||
|  | 
 | ||||||
|  |     // use the cert even though it's expired | ||||||
|  |     if (expiredCert) { | ||||||
|  |       cb(null, expiredCert); | ||||||
|  |       cb = function () { /*ignore*/ }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // register / renew the certificate in the background | ||||||
|  |     le.register(args, function () {}); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Express App | ||||||
|  | // | ||||||
|  | var app = require('express')(); | ||||||
|  | app.use('/', le.middleware()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // HTTP & HTTPS servers | ||||||
|  | // | ||||||
|  | require('http').createServer(app).listen(config.plainPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | require('https').createServer({ | ||||||
|  |   key: config.tlsKey | ||||||
|  | , cert: config.tlsCert | ||||||
|  | , SNICallback: le.sniCallback | ||||||
|  | }, app).listen(config.tlsPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | * [Full ExpressJS Example](https://github.com/Daplie/node-letsencrypt/blob/master/examples/express.js) | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| # clear out the certificates | # clear out the certificates | ||||||
|  | |||||||
| @ -3,13 +3,13 @@ | |||||||
| var PromiseA = require('bluebird'); | var PromiseA = require('bluebird'); | ||||||
| var fs = PromiseA.promisifyAll(require('fs')); | var fs = PromiseA.promisifyAll(require('fs')); | ||||||
| 
 | 
 | ||||||
| module.exports.create = function (leBinPath, defaults) { | module.exports.create = function (leBinPath, defaults, opts) { | ||||||
|   defaults.webroot = true;        // standalone should not be set to true
 |   defaults.webroot = true; | ||||||
|   defaults.renewByDefault = true; |   defaults.renewByDefault = true; | ||||||
|   defaults.text = true; |   defaults.text = true; | ||||||
| 
 | 
 | ||||||
|   var LEP = require('letsencrypt-python'); |   var LEP = require('letsencrypt-python'); | ||||||
|   var lep = PromiseA.promisifyAll(LEP.create(leBinPath, { debug: true })); |   var lep = PromiseA.promisifyAll(LEP.create(leBinPath, opts)); | ||||||
|   var wrapped = { |   var wrapped = { | ||||||
|     registerAsync: function (args) { |     registerAsync: function (args) { | ||||||
|       return lep.registerAsync('certonly', args); |       return lep.registerAsync('certonly', args); | ||||||
| @ -28,7 +28,7 @@ module.exports.create = function (leBinPath, defaults) { | |||||||
|         return { |         return { | ||||||
|           key: arr[0]  // privkey.pem
 |           key: arr[0]  // privkey.pem
 | ||||||
|         , cert: arr[1] // fullchain.pem
 |         , cert: arr[1] // fullchain.pem
 | ||||||
|           // TODO parse centificate
 |           // TODO parse centificate for lifetime / expiresAt
 | ||||||
|         , issuedAt: arr[2].mtime.valueOf() |         , issuedAt: arr[2].mtime.valueOf() | ||||||
|         }; |         }; | ||||||
|       }, function () { |       }, function () { | ||||||
| @ -38,4 +38,4 @@ module.exports.create = function (leBinPath, defaults) { | |||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   return wrapped; |   return wrapped; | ||||||
| } | }; | ||||||
|  | |||||||
							
								
								
									
										53
									
								
								examples/commandline-minimal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								examples/commandline-minimal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var LE = require('../'); | ||||||
|  | var config = require('./config-minimal'); | ||||||
|  | 
 | ||||||
|  | // Note: you should make this special dir in your product and leave it empty
 | ||||||
|  | config.le.webrootPath = __dirname + '/../tests/acme-challenge'; | ||||||
|  | config.le.server = LE.stagingServer; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Manual Registration
 | ||||||
|  | //
 | ||||||
|  | var le = LE.create(config.backend, config.le); | ||||||
|  | le.register({ | ||||||
|  |   agreeTos: true | ||||||
|  | , domains: ['example.com']      // CHANGE TO YOUR DOMAIN
 | ||||||
|  | , email: 'user@example.com'     // CHANGE TO YOUR EMAIL
 | ||||||
|  | }, function (err) { | ||||||
|  |   if (err) { | ||||||
|  |     console.error('[Error]: node-letsencrypt/examples/standalone'); | ||||||
|  |     console.error(err.stack); | ||||||
|  |   } else { | ||||||
|  |     console.log('success'); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   plainServer.close(); | ||||||
|  |   tlsServer.close(); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Express App
 | ||||||
|  | //
 | ||||||
|  | var app = require('express')(); | ||||||
|  | app.use('/', le.middleware()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // HTTP & HTTPS servers
 | ||||||
|  | // (required for domain validation)
 | ||||||
|  | //
 | ||||||
|  | var plainServer = require('http').createServer(app).listen(config.plainPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | var tlsServer = require('https').createServer({ | ||||||
|  |   key: config.tlsKey | ||||||
|  | , cert: config.tlsCert | ||||||
|  | , SNICallback: le.sniCallback | ||||||
|  | }, app).listen(config.tlsPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
| @ -29,7 +29,7 @@ var bkDefaults = { | |||||||
| , text: true | , text: true | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| var leBinPath = require('homedir')() + '/.local/share/letsencrypt/bin/letsencrypt'; | var leBinPath = require('os').homedir() + '/.local/share/letsencrypt/bin/letsencrypt'; | ||||||
| var LEB = require('../backends-python'); | var LEB = require('../backends-python'); | ||||||
| var backend = LEB.create(leBinPath, bkDefaults, { debug: true }); | var backend = LEB.create(leBinPath, bkDefaults, { debug: true }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								examples/config-minimal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/config-minimal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var path = require('path'); | ||||||
|  | 
 | ||||||
|  | var binpath = require('os').homedir() + '/.local/share/letsencrypt/bin/letsencrypt'; | ||||||
|  | 
 | ||||||
|  | var config = { | ||||||
|  | 
 | ||||||
|  |   plainPort: 80 | ||||||
|  | , tlsPort: 5001 // 5001 for testing, normally 443
 | ||||||
|  | , tlsKey: require('localhost.daplie.com-certificates').key | ||||||
|  | , tlsCert: require('localhost.daplie.com-certificates').cert | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | , le: { | ||||||
|  |     webrootPath: path.join(__dirname, '..', 'tests', 'acme-challenge') | ||||||
|  |   , fullchainTpl: '/live/:hostname/fullchain.pem' | ||||||
|  |   , privkeyTpl: '/live/:hostname/privkey.pem' | ||||||
|  |   , configDir: path.join(__dirname, '..', 'tests', 'letsencrypt.config') | ||||||
|  | 
 | ||||||
|  |     // these are specific to the python client and won't be needed with the purejs library
 | ||||||
|  |   , logsDir: path.join(__dirname, '..', 'tests', 'letsencrypt.logs') | ||||||
|  |   , workDir: path.join(__dirname, '..', 'tests', 'letsencrypt.work') | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //config.backend = require('letsencrypt/backends-python').create(binpath, config.le);
 | ||||||
|  | config.backend = require('../backends-python').create(binpath, config.le); | ||||||
|  | 
 | ||||||
|  | module.exports = config; | ||||||
							
								
								
									
										57
									
								
								examples/express-minimal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								examples/express-minimal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var LE = require('../'); | ||||||
|  | var config = require('./config-minimal'); | ||||||
|  | 
 | ||||||
|  | // Note: you should make this special dir in your product and leave it empty
 | ||||||
|  | config.le.webrootPath = __dirname + '/../tests/acme-challenge'; | ||||||
|  | config.le.server = LE.stagingServer; | ||||||
|  | 
 | ||||||
|  | var le = LE.create(config.backend, config.le, { | ||||||
|  |   sniRegisterCallback: function (args, expiredCert, cb) { | ||||||
|  |     // In theory you should never get an expired certificate because
 | ||||||
|  |     // the certificates automatically renew in the background starting
 | ||||||
|  |     // about a week before they expire.
 | ||||||
|  |     // (the default behavior is to randomly stagger renewals)
 | ||||||
|  |     // so in this case we'll just return the expired certificate
 | ||||||
|  |     if (expiredCert) { return cb(null, expiredCert); } | ||||||
|  | 
 | ||||||
|  |     // If we get here that means this domain hasn't been registered yet
 | ||||||
|  |     // Security Warning: you should either manually register domains
 | ||||||
|  |     // and return null here or check that the sni header isn't being
 | ||||||
|  |     // spoofed and this is actually a domain you own before registering
 | ||||||
|  |     //
 | ||||||
|  |     //   cb(null, null);
 | ||||||
|  | 
 | ||||||
|  |     var hostname = args.domains[0]; | ||||||
|  |     console.log("[TODO] check that '" + hostname + "' is one I expect"); | ||||||
|  | 
 | ||||||
|  |     args.agreeTos = true; | ||||||
|  |     args.email = 'user@example.com'; | ||||||
|  | 
 | ||||||
|  |     le.register(args, cb); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Express App
 | ||||||
|  | //
 | ||||||
|  | var app = require('express')(); | ||||||
|  | app.use('/', le.middleware()); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // HTTP & HTTPS servers
 | ||||||
|  | //
 | ||||||
|  | require('http').createServer(app).listen(config.plainPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | require('https').createServer({ | ||||||
|  |   key: config.tlsKey | ||||||
|  | , cert: config.tlsCert | ||||||
|  | , SNICallback: le.sniCallback | ||||||
|  | }, app).listen(config.tlsPort, function () { | ||||||
|  |   console.log('Listening http', this.address()); | ||||||
|  | }); | ||||||
| @ -28,7 +28,7 @@ var bkDefaults = { | |||||||
| , server: LE.stagingServer | , server: LE.stagingServer | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| var leBinPath = require('homedir')() + '/.local/share/letsencrypt/bin/letsencrypt'; | var leBinPath = require('os').homedir() + '/.local/share/letsencrypt/bin/letsencrypt'; | ||||||
| var LEB = require('../backends-python'); | var LEB = require('../backends-python'); | ||||||
| var backend = LEB.create(leBinPath, bkDefaults, { debug: true }); | var backend = LEB.create(leBinPath, bkDefaults, { debug: true }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user