README
PiACME: Simple ACME/LetsEncrypt HTTP/SSL Certificate Management
Why
Because out of all of the existing modules, I couldn't find one that does what I needed and doesn't carry large number of unnecessary dependencies.
This module is written in pure JavaScript ECMAScript 6 (ES6) and requires only several low-level crypto management dependencies.
Usage
Initialize PiACME by passing a configuration object:
const config = {
// website or application signature, can be any string
application: 'example/0.0.1',
// list of domains for which we're getting a certificate for
/// same certificate can be used for multiple domain
// must be resolvable and reachable over internet for validation
// before certificate can be issued.
domains: ['example1.com', 'example2.com'],
// email of the person responsible for the site for which we're getting certificate for
maintainer: 'maintainer@example.com',
// email of the person that will be registered with LetsEncrypt, can be the same as maintainer
subscriber: 'subscriber@example.com',
// file where account info will be stored once account is created
accountFile: './cert/account.json',
// file where account secret will be stored once account is created
accountKeyFile: './cert/account.pem',
// file where server private key will be stored
ServerKeyFile: './cert//private.pem',
// file where server certificate will be stored
fullChain: './cert/fullchain.pem',
// attempt renewal how many days before expiration, default: 10 days
renewDays: 14,
// how often to check certificate validity in minutes, default: 720 (12 hours)
monitorInterval: 60 * 12,
// increase verbosity, default: false
debug: false,
};
const piacme = require('piacme');
piacme.init(config);
const { Key, Crt } = await piacme.getCert();
That's it!
Account registration, server key creation, certificate issuance, taget validation, and certificate renwal - are all handled automatically.
Now you can use server key and certificate.
For example to start a secure http2 server:
const http2 = require('http2');
const fs = require('fs');
const options = {
key = fs.readFileSync(Key);
cert = fs.readFileSync(Crt);
};
const server = http2.createSecureServer(options);
server.listen(443);
Or https server:
const http2 = require('https');
const fs = require('fs');
const options = {
key = fs.readFileSync(Key);
cert = fs.readFileSync(Crt);
};
const server = https.createServer(options);
server.listen(443);
Internal workflow
All functions use same object passed during init()
call.
Core function is getCert()
and it will either return existing valid certificate, issue a new one or trigger a certificate renewal.
Internally, it calls checkCert()
to verify if server key and certificate specified in config object already exists and are valid.
If yes, it will just return those objects: config.ServerKeyFile
and config.fullChain
.
If not, if calls:
createKeys()
Which is used only once per server lifetime.
It initialize LetsEncrypt account using maintainer info and generate server private key.createCert()
Which is used to genrates new certificate if one doesn't exist or is about to expire.
Interally it temporarily starts a http server on port 80 to listen for LetsEncrypt validation callbacks and then shuts down the server.
Next, it calls parseCert()
and parses cetificate details for validity before returning server key and certificate.
Optional
To monitor certificate, call monitorCert()
which updates object initially passed using init()
call by triggering getCert()
every 12 hours.
Usefull for certfificates with short lifespan that require freqent renewals.
piacme.monitorCert();`
or with a provided callback function that monitorCert()
will call if certificate changes.
function f() { /* do something here */ };
piacme.monitorCert(f)
To get certificate details, call parseCert()
and it will parse certificate from the initial object used during init()
call.
contact
andsubject
are values provided during certificate creationerror
in all cases is optional property and will be set if case of an error.issuer
will always be LetsEncrypt authority.createdAt
,notBefore
andnotAfter
are date objects specifying certificate issue date and validity (start and end date).
const ssl = await piacme.parseCert();
ssl: {
account: { error?, contact, createdAt },
serverKey: { error? },
accountKey: { error? },
fullChain: { error?, subject, issuer, notBefore, notAfter }
}