JSPM

certnode

0.0.1
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 212
    • Score
      100M100P100Q78311F
    • License ISC

    Generate Let's Encrypt certificates for your domains

    Package Exports

    • certnode

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (certnode) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    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