About Daplie: We're taking back the Internet!
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:
jobs@daplie.com | Invest in Daplie on Wefunder | Pre-order Cloud, The World's First Home Server for Everyone
greenlock (node-letsencrypt)

| greenlock
| greenlock-cli
| greenlock-express
| greenlock-cluster
| greenlock-koa
| greenlock-hapi
|
Automatic Let's Encrypt (ACME) HTTPS / TLS / SSL Certificates for node.js
Free SSL with 90-day HTTPS / TLS Certificates
Are these the droids you're looking for?
This is a low-level library for implementing ACME / LetsEncrypt Clients, CLIs,
system tools, and abstracting storage backends (file vs db, etc).
For express, raw https or spdy, or restify (same as raw https) see
letsencrypt-express and letsencrypt-cluster.
For hapi see letsencrypt-hapi.
For koa or rill
see letsencrypt-koa.
For bash, fish, zsh, cmd.exe, PowerShell
see letsencrypt-cli.
Install
greenlock requires at least two plugins:
one for managing certificate storage and the other for handling ACME challenges.
The default storage plugin is le-store-certbot
and the default challenge is le-challenge-fs.
npm install --save greenlock@2.x
npm install --save le-store-certbot@2.x
npm install --save le-challenge-fs@2.x
npm install --save le-acme-core@2.x
npm install --save le-sni-auto@2.x
Important: Use node v4.5+ or v6.x, node <= v4.4 has a known bug in the Buffer implementation.
Usage
It's very simple and easy to use, but also very complete and easy to extend and customize.
Overly Simplified Example
Against my better judgement I'm providing a terribly oversimplified example
of how to use this library:
var le = require('greenlock').create({ server: 'staging' });
var opts = {
domains: ['example.com'], email: 'user@email.com', agreeTos: true
};
le.register(opts).then(function (certs) {
console.log(certs);
}, function (err) {
console.error(err);
});
You also need some sort of server to handle the acme challenge:
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.
Useful Example
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)
'use strict';
var LE = require('greenlock');
var le;
var leStore = require('le-store-certbot').create({
configDir: '~/letsencrypt/etc'
, debug: false
});
var leChallenge = require('le-challenge-fs').create({
webrootPath: '~/letsencrypt/var/'
, debug: false
});
function leAgree(opts, agreeCb) {
agreeCb(null, opts.tosUrl);
}
le = LE.create({
server: LE.stagingServerUrl
, store: leStore
, challenges: { 'http-01': leChallenge }
, challengeType: 'http-01'
, agreeToTerms: leAgree
, debug: false
});
le.check({ domains: [ 'example.com' ] }).then(function (results) {
if (results) {
return;
}
le.register({
domains: ['example.com']
, email: 'user@email.com'
, agreeTos: ''
, rsaKeySize: 2048
, challengeType: 'http-01'
}).then(function (results) {
console.log('success');
}, function (err) {
console.error('[Error]: node-greenlock/examples/standalone');
console.error(err.stack);
});
});
Here's what results looks like:
{ privkey: ''
, cert: ''
, chain: ''
, issuedAt: 0
, expiresAt: 0
, subject: ''
, altnames: []
}
API
The full end-user API is exposed in the example above and includes all relevant options.
le.register(opts)
le.check(opts)
Helper Functions
We do expose a few helper functions:
- LE.validDomain(hostname) // returns '' or the hostname string if it's a valid ascii or punycode domain name
TODO fetch domain tld list
Template Strings
The following variables will be tempalted in any strings passed to the options object:
~/ replaced with os.homedir() i.e. /Users/aj
:hostname replaced with the first domain in the list i.e. example.com
Developer API
If you are developing an le-store-* or le-challenge-* plugin you need to be aware of
additional internal API expectations.
IMPORTANT:
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
should be kept in sync.
store implementation
See https://github.com/Daplie/le-store-SPEC
- 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)
challenge implementation
See https://github.com/Daplie/le-challenge-fs
.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
Change History
- v2.0.2 - Aug 9th 2016 update readme
- v2.0.1 - Aug 9th 2016
- major refactor
- simplified API
- modular plugins
- knock out bugs
- v1.5.0 now using letiny-core v2.0.0 and rsa-compat
- v1.4.x I can't remember... but it's better!
- v1.1.0 Added letiny-core, removed node-letsencrypt-python
- v1.0.2 Works with node-letsencrypt-python
- v1.0.0 Thar be dragons
LICENSE
Dual-licensed MIT and Apache-2.0
See LICENSE