certnode

0.0.1 • Public • Published

certnode

Generate Let's Encrypt certificates in Node!

Why?

I wanted to see how difficult it is to generate Let's Encrypt certificates in Node without using an external package like greenlock or exec-ing certbot in child processes.

Essentially this boils down to creating keypairs, signing and sending HTTPS requests to Let's Encrypt's API endpoints. Not a huge lift; however, certnode is pretty limited right now. Extending functionality might be a larger effort.

This was primarily a learning exercise but also an effort to create a package that hopefully makes it easy for others to generate certificates for their domains :)

Install

npm i certnode

Usage

The example code can be found here.

Note: you must control the domain + email address you pass to client.generateCertificate(). Also, be sure to allow inbound HTTP traffic (TCP, port 80) in your firewall rules.

Generate account keys

const certnode = require('certnode')
const fs = require('fs')
const https = require('https')

const client = new certnode.Client()

// Generate fresh account keys for Let's Encrypt
await client.generateAccountKeyPair()

Generate certificate for HTTPS server

const { certificate, privateKeyData } = await client.generateCertificate('<domain>', '<email>')
const server = https.createServer({ cert: certificate, key: privateKeyData })

/* register event listeners */

server.listen(443, '0.0.0.0', () => {})

Write account keys to filesytem

// Account private key is encrypted with passphrase, if provided.
await client.exportAccountKeyPair('<directory>', '[passphrase]')

Write certificate + private key to filesystem

// Certificate private key is encrypted with passphrase, if provided.
await Promise.all([
  fs.promises.writeFile('/path/to/certificate', certificate),
  certnode.writeKeyToFile('/path/to/privateKey', privateKeyData, '[passphrase]')
])

Import account keys

const anotherClient = new certnode.Client()

// If you previously exported with passphrase, provide the same passphrase.
await anotherClient.importAccountKeyPair('<directory>', '[passphrase]')

/* generate certificate with `anotherClient` */

Import certificate + private key for HTTPS server

const [certificate, privateKeyData] = await Promise.all([
  fs.promises.readFile('/path/to/certificate', 'utf8'),
  fs.promises.readFile('/path/to/privateKey', 'utf8')
])

// If you previously exported with passphrase, provide the same passphrase.
const server = https.createServer({
  cert: certificate,
  key: privateKeyData,
  passphrase: '[passphrase]'
})

/* register event listeners */

server.listen(443, '0.0.0.0', () => {})

Documentation

To generate the API docs:

npm run docs

Then open ./out/index.html in your browser.

Test

sudo domain=<domain> npm test

The test suite sends HTTPS requests to Let's Encrypt (staging environment) and generates certificates.

Therefore, tests must run from a domain you control, presumably on a VPS. Since certnode attains certificates through HTTP validation, it must run as root so it can listen on port 80. Make sure firewall rules allow inbound HTTP traffic.

Note: if you run tests several times in quick succession, you may be rate-limited by Let's Encrypt.

Linting

npm run lint

Resources

Dependencies (2)

Dev Dependencies (10)

Package Sidebar

Install

npm i certnode

Weekly Downloads

1

Version

0.0.1

License

ISC

Unpacked Size

39.1 kB

Total Files

16

Last publish

Collaborators

  • zbo14