🔐 Free SSL, Free Wildcard SSL, and Fully Automated HTTPS for node.js, issued by Let's Encrypt v2 via ACME. Issues and PRs on Github.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
9.2 KiB

7 years ago
greenlock (node-letsencrypt)
7 years ago
=========
8 years ago
7 years ago
| **greenlock**
7 years ago
| [greenlock-cli](https://git.coolaj86.com/coolaj86/greenlock-cli.js)
| [greenlock-express](https://git.coolaj86.com/coolaj86/greenlock-express.js)
| [greenlock-cluster](https://git.coolaj86.com/coolaj86/greenlock-cluster.js)
| [greenlock-koa](https://git.coolaj86.com/coolaj86/greenlock-koa.js)
| [greenlock-hapi](https://git.coolaj86.com/coolaj86/greenlock-hapi.js)
6 years ago
| Sponsored by [ppl](https://ppl.family). Created at [Daplie](https://dapliefounder.com).
8 years ago
7 years ago
Automatic [Let's Encrypt](https://letsencrypt.org) (ACME) HTTPS / TLS / SSL Certificates for node.js
9 years ago
Free SSL with [90-day](https://letsencrypt.org/2015/11/09/why-90-days.html) HTTPS / TLS Certificates
9 years ago
8 years ago
Are these the droids you're looking for?
------
8 years ago
This is a **low-level library** for implementing ACME / LetsEncrypt Clients, CLIs,
system tools, and abstracting storage backends (file vs db, etc).
8 years ago
8 years ago
For `express`, raw `https` or `spdy`, or `restify` (same as raw https) see
7 years ago
[**greenlock-express** (previously letsencrypt-express)](https://git.coolaj86.com/coolaj86/greenlock-express.js) and [greenlock-cluster (previously letsencrypt-cluster)](https://git.coolaj86.com/coolaj86/greenlock-cluster.js).
7 years ago
For `hapi` see [greenlock-hapi (previously letsencrypt-hapi)](https://git.coolaj86.com/coolaj86/greenlock-hapi.js).
8 years ago
8 years ago
For `koa` or `rill`
7 years ago
see [greenlock-koa (previously letsencrypt-koa)](https://git.coolaj86.com/coolaj86/greenlock-koa.js).
8 years ago
For `bash`, `fish`, `zsh`, `cmd.exe`, `PowerShell`
7 years ago
see [**greenlock-cli** (previously letsencrypt-cli)](https://git.coolaj86.com/coolaj86/greenlock-cli.js).
8 years ago
9 years ago
Install
8 years ago
=======
9 years ago
`greenlock` requires at least two plugins:
8 years ago
one for managing certificate storage and the other for handling ACME challenges.
7 years ago
The default storage plugin is [`le-store-certbot`](https://git.coolaj86.com/coolaj86/le-store-certbot.js)
and the default challenge is [`le-challenge-fs`](https://git.coolaj86.com/coolaj86/le-challenge-fs.js).
8 years ago
9 years ago
```bash
npm install --save greenlock@2.x
8 years ago
npm install --save le-store-certbot@2.x # default plugin for accounts, certificates, and keypairs
7 years ago
npm install --save le-challenge-fs@2.x # default plugin for http-01 challenge
npm install --save le-challenge-sni@2.x # default plugin for tls-sni-01 and tls-sni-02 challenge
8 years ago
npm install --save le-acme-core@2.x # default plugin for ACME spec
8 years ago
npm install --save le-sni-auto@2.x # default plugin for SNICallback
9 years ago
```
**Important**: Use node v4.5+ or v6.x, node <= v4.4 has a [known bug](https://github.com/nodejs/node/issues/8053) in the `Buffer` implementation.
9 years ago
Usage
8 years ago
=====
9 years ago
8 years ago
It's very simple and easy to use, but also very complete and easy to extend and customize.
9 years ago
8 years ago
### Overly Simplified Example
8 years ago
8 years ago
Against my better judgement I'm providing a terribly oversimplified example
8 years ago
of how to use this library:
8 years ago
9 years ago
```javascript
var le = require('greenlock').create({ server: 'staging' });
8 years ago
var opts = {
8 years ago
domains: ['example.com'], email: 'user@email.com', agreeTos: true
};
le.register(opts).then(function (certs) {
8 years ago
console.log(certs);
// privkey, cert, chain, expiresAt, issuedAt, subject, altnames
}, function (err) {
console.error(err);
});
8 years ago
```
You also need some sort of server to handle the acme challenge:
8 years ago
```javascript
8 years ago
var app = express();
app.use('/', le.middleware());
```
Note: The `webrootPath` string is a template.
Any occurance of `:hostname` will be replaced
with the domain for which we are requested certificates.
9 years ago
8 years ago
### Useful Example
9 years ago
8 years ago
The configuration consists of 3 components:
* Storage Backend (search npm for projects starting with 'le-store-')
* ACME Challenge Handlers (search npm for projects starting with 'le-challenge-')
* Letsencryt Config (this is all you)
9 years ago
9 years ago
```javascript
8 years ago
'use strict';
var LE = require('greenlock');
8 years ago
var le;
9 years ago
9 years ago
8 years ago
// Storage Backend
var leStore = require('le-store-certbot').create({
configDir: '~/acme/etc' // or /etc/letsencrypt or wherever
8 years ago
, debug: false
});
9 years ago
8 years ago
// ACME Challenge Handlers
7 years ago
var leHttpChallenge = require('le-challenge-fs').create({
webrootPath: '~/acme/var/' // or template string such as
8 years ago
, debug: false // '/srv/www/:hostname/.well-known/acme-challenge'
});
7 years ago
var leSniChallenge = require('le-challenge-sni').create({
7 years ago
, debug: false
7 years ago
});
9 years ago
8 years ago
function leAgree(opts, agreeCb) {
// opts = { email, domains, tosUrl }
agreeCb(null, opts.tosUrl);
9 years ago
}
9 years ago
8 years ago
le = LE.create({
server: LE.stagingServerUrl // or LE.productionServerUrl
, store: leStore // handles saving of config, accounts, and certificates
7 years ago
, challenges: {
'http-01': leHttpChallenge // handles /.well-known/acme-challege keys and tokens
, 'tls-sni-01': leSniChallenge // handles generating a certificate with the correct name
, 'tls-sni-02': leSniChallenge
}
, challengeType: 'http-01' // default to this challenge type
8 years ago
, agreeToTerms: leAgree // hook to allow user to view and accept LE TOS
8 years ago
//, sni: require('le-sni-auto').create({}) // handles sni callback
8 years ago
, debug: false
8 years ago
//, log: function (debug) {console.log.apply(console, args);} // handles debug outputs
8 years ago
});
9 years ago
9 years ago
8 years ago
// If using express you should use the middleware
// app.use('/', le.middleware());
//
// Otherwise you should see the test file for usage of this:
// le.challenges['http-01'].get(opts.domain, key, val, done)
9 years ago
8 years ago
// Check in-memory cache of certificates for the named domain
le.check({ domains: [ 'example.com' ] }).then(function (results) {
8 years ago
if (results) {
// we already have certificates
return;
}
9 years ago
8 years ago
8 years ago
// Register Certificate manually
le.register({
8 years ago
domains: ['example.com'] // CHANGE TO YOUR DOMAIN (list for SANS)
, email: 'user@email.com' // CHANGE TO YOUR EMAIL
8 years ago
, agreeTos: '' // set to tosUrl string (or true) to pre-approve (and skip agreeToTerms)
8 years ago
, rsaKeySize: 2048 // 2048 or higher
, challengeType: 'http-01' // http-01, tls-sni-01, or dns-01
}).then(function (results) {
console.log('success');
}, function (err) {
// Note: you must either use le.middleware() with express,
// manually use le.challenges['http-01'].get(opts, domain, key, val, done)
8 years ago
// or have a webserver running and responding
// to /.well-known/acme-challenge at `webrootPath`
console.error('[Error]: node-greenlock/examples/standalone');
8 years ago
console.error(err.stack);
});
9 years ago
8 years ago
});
9 years ago
```
8 years ago
Here's what `results` looks like:
9 years ago
```javascript
8 years ago
{ privkey: '' // PEM encoded private key
, cert: '' // PEM encoded cert
, chain: '' // PEM encoded intermediate cert
, issuedAt: 0 // notBefore date (in ms) parsed from cert
, expiresAt: 0 // notAfter date (in ms) parsed from cert
, subject: '' // example.com
, altnames: [] // example.com,www.example.com
8 years ago
}
9 years ago
```
8 years ago
API
---
9 years ago
8 years ago
The full end-user API is exposed in the example above and includes all relevant options.
9 years ago
8 years ago
```
8 years ago
le.register(opts)
le.check(opts)
8 years ago
```
8 years ago
### Helper Functions
9 years ago
8 years ago
We do expose a few helper functions:
9 years ago
8 years ago
* LE.validDomain(hostname) // returns '' or the hostname string if it's a valid ascii or punycode domain name
9 years ago
8 years ago
TODO fetch domain tld list
9 years ago
### Template Strings
The following variables will be tempalted in any strings passed to the options object:
* `~/` replaced with `os.homedir()` i.e. `/Users/aj`
8 years ago
* `:hostname` replaced with the first domain in the list i.e. `example.com`
8 years ago
Developer API
-------------
9 years ago
8 years ago
If you are developing an `le-store-*` or `le-challenge-*` plugin you need to be aware of
additional internal API expectations.
9 years ago
8 years ago
**IMPORTANT**:
9 years ago
8 years ago
Use `v2.0.0` as your initial version - NOT v0.1.0 and NOT v1.0.0 and NOT v3.0.0.
This is to indicate that your module is compatible with v2.x of node-greenlock.
Since the public API for your module is defined by node-greenlock the major version
8 years ago
should be kept in sync.
8 years ago
### store implementation
9 years ago
7 years ago
See <https://git.coolaj86.com/coolaj86/le-store-SPEC.js>
8 years ago
* getOptions()
* accounts.
* checkKeypair(opts, cb)
* check(opts, cb)
* setKeypair(opts, keypair, cb)
* set(opts, reg, cb)
* certificates.
* checkKeypair(opts, cb)
* check(opts, cb)
* setKeypair(opts, keypair, cb)
* set(opts, reg, cb)
8 years ago
### challenge implementation
9 years ago
7 years ago
See https://git.coolaj86.com/coolaj86/le-challenge-fs.js
9 years ago
8 years ago
* `.set(opts, domain, key, value, cb);` // opts will be saved with domain/key
* `.get(opts, domain, key, cb);` // opts will be retrieved by domain/key
* `.remove(opts, domain, key, cb);` // opts will be retrieved by domain/key
9 years ago
9 years ago
Change History
==============
7 years ago
* v2.1.17 - Nov 5th 2017 migrate back to personal repo
* v2.1.9 - Jan 18th 2017 renamed to greenlock
8 years ago
* v2.0.2 - Aug 9th 2016 update readme
* v2.0.1 - Aug 9th 2016
8 years ago
* major refactor
* simplified API
8 years ago
* modular plugins
8 years ago
* knock out bugs
8 years ago
* v1.5.0 now using letiny-core v2.0.0 and rsa-compat
* v1.4.x I can't remember... but it's better!
9 years ago
* v1.1.0 Added letiny-core, removed node-letsencrypt-python
* v1.0.2 Works with node-letsencrypt-python
* v1.0.0 Thar be dragons
9 years ago
9 years ago
LICENSE
=======
Dual-licensed MIT and Apache-2.0
See LICENSE