| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | # Greenlock™ for Koa
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | An Automated HTTPS ACME client (Let's Encrypt v2) for Koa | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Greenlock™ for | 
					
						
							|  |  |  | [Browsers](https://git.coolaj86.com/coolaj86/greenlock.html), | 
					
						
							|  |  |  | [Node.js](https://git.coolaj86.com/coolaj86/greenlock.js), | 
					
						
							|  |  |  | [Commandline](https://git.coolaj86.com/coolaj86/greenlock-cli.js), | 
					
						
							|  |  |  | [Express.js](https://git.coolaj86.com/coolaj86/greenlock-express.js), | 
					
						
							|  |  |  | [Node.js Cluster](https://git.coolaj86.com/coolaj86/greenlock-cluster.js), | 
					
						
							|  |  |  | [hapi](https://git.coolaj86.com/coolaj86/greenlock-hapi.js), | 
					
						
							|  |  |  | **Koa**, | 
					
						
							|  |  |  | and [rill](https://git.coolaj86.com/coolaj86/greenlock-rill.js) | 
					
						
							| 
									
										
										
										
											2018-04-20 06:33:56 +00:00
										 |  |  | | Sponsered by [ppl](https://ppl.family) | 
					
						
							| 
									
										
										
										
											2016-04-22 12:20:15 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | Features | 
					
						
							|  |  |  | ======== | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  |   * [x] Automatic Registration via SNI (`httpsOptions.SNICallback`) | 
					
						
							|  |  |  |   * [x] Secure domain approval callback | 
					
						
							|  |  |  |   * [x] Automatic renewal between 10 and 14 days before expiration | 
					
						
							|  |  |  |   * [x] Virtual Hosting (vhost) with Multiple Domains & SAN | 
					
						
							|  |  |  |   * [x] and [more](https://git.coolaj86.com/coolaj86/greenlock-express.js) | 
					
						
							|  |  |  |   * [x] plugins for AWS, redis, and more | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | This module is just an alias for greenlock-express.js, | 
					
						
							|  |  |  | which works with any middleware system. | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Install
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | npm install --save greenlock-koa@2.x | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | QuickStart | 
					
						
							|  |  |  | ========== | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | ////////////////////// | 
					
						
							|  |  |  | // Greenlock Setup  // | 
					
						
							|  |  |  | ////////////////////// | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var greenlock = require('greenlock-koa').create({ | 
					
						
							|  |  |  |   version: 'draft-11' // Let's Encrypt v2 | 
					
						
							| 
									
										
										
										
											2018-04-20 06:27:36 +00:00
										 |  |  |   // You MUST change this to 'https://acme-v02.api.letsencrypt.org/directory' in production | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | , server: 'https://acme-staging-v02.api.letsencrypt.org/directory' | 
					
						
							| 
									
										
										
										
											2016-08-16 14:58:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | , email: 'jon@example.com' | 
					
						
							|  |  |  | , agreeTos: true | 
					
						
							|  |  |  | , approveDomains: [ 'example.com' ] | 
					
						
							| 
									
										
										
										
											2016-08-16 14:58:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  |   // Join the community to get notified of important updates | 
					
						
							|  |  |  |   // and help make greenlock better | 
					
						
							|  |  |  | , communityMember: true | 
					
						
							| 
									
										
										
										
											2016-08-16 14:58:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | , configDir: require('os').homedir() + '/acme/etc' | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | //, debug: true | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | ////////////////// | 
					
						
							|  |  |  | // Just add Koa // | 
					
						
							|  |  |  | ////////////////// | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | var http = require('http'); | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | var https = require('https'); | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | var koa = require('koa'); | 
					
						
							| 
									
										
										
										
											2019-01-09 14:39:11 +00:00
										 |  |  | var app = new koa(); | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | app.use(function *() { | 
					
						
							|  |  |  |   this.body = 'Hello World'; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | // https server | 
					
						
							|  |  |  | var server = https.createServer(greenlock.tlsOptions, greenlock.middleware(app.callback())); | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | server.listen(443, function () { | 
					
						
							|  |  |  |  console.log('Listening at https://localhost:' + this.address().port); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-16 14:58:02 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | // http redirect to https | 
					
						
							| 
									
										
										
										
											2016-08-16 14:58:02 -06:00
										 |  |  | var http = require('http'); | 
					
						
							| 
									
										
										
										
											2019-01-09 14:39:11 +00:00
										 |  |  | var redirectHttps = app.use(require('koa-sslify')()).callback(); | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | http.createServer(greenlock.middleware(redirectHttps)).listen(80, function () { | 
					
						
							|  |  |  |   console.log('Listening on port 80 to handle ACME http-01 challenge and redirect to https'); | 
					
						
							| 
									
										
										
										
											2016-04-18 11:07:30 -06:00
										 |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2018-05-10 12:51:54 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | Handling a dynamic list of domains | 
					
						
							|  |  |  | ======================== | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you handle multiple domains and you dynamically add new ones, | 
					
						
							|  |  |  | you'll want to replace the static list of domains in `approveDomains` | 
					
						
							|  |  |  | with a function like this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | function approveDomains(opts, certs, cb) { | 
					
						
							|  |  |  |   // This is where you check your database and associated | 
					
						
							|  |  |  |   // email addresses with domains and agreements and such | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // The domains being approved for the first time are listed in opts.domains | 
					
						
							|  |  |  |   // Certs being renewed are listed in certs.altnames | 
					
						
							|  |  |  |   if (certs) { | 
					
						
							|  |  |  |     opts.domains = certs.altnames; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     // Do something to | 
					
						
							|  |  |  |     opts.email = 'john.doe@example.com'; | 
					
						
							|  |  |  |     opts.agreeTos = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   opts.communityMember = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // NOTE: you can also change other options such as `challengeType` and `challenge` | 
					
						
							|  |  |  |   // opts.challengeType = 'http-01'; | 
					
						
							|  |  |  |   // opts.challenge = require('le-challenge-fs').create({}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cb(null, { options: opts, certs: certs }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **SECURITY**: Be careful with this. | 
					
						
							|  |  |  | If you don't check that the domains being requested are the domains you | 
					
						
							|  |  |  | allow an attacker can make you hit your rate limit for failed verification | 
					
						
							|  |  |  | attempts. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See the | 
					
						
							|  |  |  | [vhost example](https://git.coolaj86.com/coolaj86/greenlock-express.js/src/branch/master/examples/vhost.js) | 
					
						
							|  |  |  | for an idea of how this is done. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | More Usage & Troubleshooting | 
					
						
							|  |  |  | ============================ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See <https://git.coolaj86.com/coolaj86/greenlock-express.js> |