2018-05-10 18:51:54 +00: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 18:20:15 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
Features
|
|
|
|
========
|
2016-04-18 17:07:30 +00:00
|
|
|
|
2018-05-10 18:51:54 +00: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 17:07:30 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
This module is just an alias for greenlock-express.js,
|
|
|
|
which works with any middleware system.
|
2016-04-18 17:07:30 +00:00
|
|
|
|
|
|
|
## Install
|
|
|
|
|
|
|
|
```
|
2018-05-10 18:51:54 +00:00
|
|
|
npm install --save greenlock-koa@2.x
|
2016-04-18 17:07:30 +00:00
|
|
|
```
|
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
QuickStart
|
|
|
|
==========
|
2016-04-18 17:07:30 +00:00
|
|
|
|
|
|
|
```javascript
|
|
|
|
'use strict';
|
|
|
|
|
2018-05-10 18:51:54 +00: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 18:51:54 +00:00
|
|
|
, server: 'https://acme-staging-v02.api.letsencrypt.org/directory'
|
2016-08-16 20:58:02 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
, email: 'jon@example.com'
|
|
|
|
, agreeTos: true
|
|
|
|
, approveDomains: [ 'example.com' ]
|
2016-08-16 20:58:02 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
// Join the community to get notified of important updates
|
|
|
|
// and help make greenlock better
|
|
|
|
, communityMember: true
|
2016-08-16 20:58:02 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
, configDir: require('os').homedir() + '/acme/etc'
|
2016-04-18 17:07:30 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
//, debug: true
|
|
|
|
});
|
2016-04-18 17:07:30 +00:00
|
|
|
|
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
//////////////////
|
|
|
|
// Just add Koa //
|
|
|
|
//////////////////
|
2016-04-18 17:07:30 +00:00
|
|
|
|
|
|
|
var http = require('http');
|
2018-05-10 18:51:54 +00:00
|
|
|
var https = require('https');
|
2016-04-18 17:07:30 +00:00
|
|
|
var koa = require('koa');
|
|
|
|
var app = koa();
|
|
|
|
|
|
|
|
app.use(function *() {
|
|
|
|
this.body = 'Hello World';
|
|
|
|
});
|
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
// https server
|
|
|
|
var server = https.createServer(greenlock.tlsOptions, greenlock.middleware(app.callback()));
|
2016-04-18 17:07:30 +00:00
|
|
|
|
|
|
|
server.listen(443, function () {
|
|
|
|
console.log('Listening at https://localhost:' + this.address().port);
|
|
|
|
});
|
|
|
|
|
2016-08-16 20:58:02 +00:00
|
|
|
|
2018-05-10 18:51:54 +00:00
|
|
|
// http redirect to https
|
2016-08-16 20:58:02 +00:00
|
|
|
var http = require('http');
|
|
|
|
var redirectHttps = koa().use(require('koa-sslify')()).callback();
|
2018-05-10 18:51:54 +00: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 17:07:30 +00:00
|
|
|
});
|
|
|
|
```
|
2018-05-10 18:51:54 +00: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>
|