greenlock-hapi.js/README.md

3.3 KiB

Join the chat at https://gitter.im/Daplie/letsencrypt-express

| letsencrypt (lib) | letsencrypt-cli | letsencrypt-express | letsencrypt-cluster | letsencrypt-koa | letsencrypt-hapi |

letsencrypt-hapi

Free SSL and Automatic HTTPS for node.js with hapi.js and other middleware systems via Let's Encrypt

  • Automatic Registration via SNI (httpsOptions.SNICallback)
    • registrations require an approval callback in production
  • Automatic Renewal (around 80 days)
    • renewals are fully automatic and happen in the background, with no downtime
  • Automatic vhost / virtual hosting

All you have to do is start the webserver and then visit it at it's domain name.

Install

npm install --save letsencrypt-express@2.x

Pay no attention to the man behind the curtain. (just ignore that the name of the module is letsencrypt-express)

Part 1: Configure LetsEncrypt

'use strict';

var le = require('letsencrypt-express').create({
  server: 'staging' // in production use https://acme-v01.api.letsencrypt.org/directory
  
, configDir: require('os').homedir() + '/letsencrypt/etc'
  
, approveDomains: function (opts, certs, cb) {
    opts.domains = certs && certs.altnames || opts.domains;
    opts.email = 'john.doe@example.com' // CHANGE ME
    opts.agreeTos = true;
    
    cb(null, { options: opts, certs: certs });
  }
  
 , debug: true
});

WARNING: If you don't do any checks and simply complete approveDomains callback, an attacker will spoof SNI packets with bad hostnames and that will cause you to be rate-limited and/or blocked from the ACME server. Alternatively, You can run registration manually:

npm install -g letsencrypt-cli

letsencrypt certonly --standalone \
  --server 'https://acme-v01.api.letsencrypt.org/directory' \
  --config-dir ~/letsencrypt/etc \
  --agree-tos --domains example.com --email user@example.com

# Note: the '--webrootPath' option is also available if you don't want to shut down your webserver to get the cert.

Part 2: Just add Hapi

var hapi = require('hapi');
var https = require('spdy');
var server = new hapi.Server();
var acmeResponder = le.middleware();
var httpsServer = https.createServer(le.httpsOptions).listen(443);

server.connection({ listener: httpsServer, autoListen: false, tls: true });

server.route({
  method: 'GET'
, path: '/.well-known/acme-challenge'
, handler: function (request, reply) {
    var req = request.raw.req;
    var res = request.raw.res;

    reply.close(false);
    acmeResponder(req, res);
  }
});

server.route({
  method: 'GET'
, path: '/'
, handler: function (request, reply) {
    reply("Hello, I'm so Hapi!");
  }
});

Part 3: Redirect http to https

var http = require('http');
var redirectHttps = require('redirect-https')();

http.createServer(le.middleware(redirectHttps)).listen(80, function () {
  console.log('handle ACME http-01 challenge and redirect to https');
});