Updated (14/June/2019)

Updated (22/June/2018): Support for Let’s Encrypt v2

I have updated the code snippet below to include the support for Let’s Encrypt v2 in the snippet below:

/** * Setting up https */ var lex = require('greenlock-express').create({ server: 'https://acme-v02.api.letsencrypt.org/directory', // Let's Encrypt v2 is ACME draft 11 version: 'draft-11', challenges: { 'http-01': require('le-challenge-fs').create({ webrootPath: '/tmp/acme-challenges' }) }, store: require('le-store-certbot').create({ webrootPath: '/tmp/acme-challenges' }), approveDomains: function(opts, certs, cb) { if(certs) { opts.domains = ['domain1.com', 'domain2.com'] } else { opts.email = 'youremail@example.com', opts.agreeTos = true; } cb(null, { options: opts, certs: certs }); } }); //Optional: Add this line if you want to redirect all your traffic to https require('http').createServer(lex.middleware(require('redirect-https')())).listen(80, function () { console.log("Listening for ACME http-01 challenges on", this.address()); }); // handles your app var server = require('https').createServer(lex.httpsOptions, lex.middleware(app)) server.listen(443, function () { console.log("Listening for ACME tls-sni-01 challenges and serve app on", this.address()); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /** * Setting up https */ var lex = require ( 'greenlock-express' ) . create ( { server : 'https://acme-v02.api.letsencrypt.org/directory' , // Let's Encrypt v2 is ACME draft 11 version : 'draft-11' , challenges : { 'http-01' : require ( 'le-challenge-fs' ) . create ( { webrootPath : '/tmp/acme-challenges' } ) } , store : require ( 'le-store-certbot' ) . create ( { webrootPath : '/tmp/acme-challenges' } ) , approveDomains : function ( opts , certs , cb ) { if ( certs ) { opts . domains = [ 'domain1.com' , 'domain2.com' ] } else { opts . email = 'youremail@example.com' , opts . agreeTos = true ; } cb ( null , { options : opts , certs : certs } ) ; } } ) ; //Optional: Add this line if you want to redirect all your traffic to https require ( 'http' ) . createServer ( lex . middleware ( require ( 'redirect-https' ) ( ) ) ) . listen ( 80 , function ( ) { console . log ( "Listening for ACME http-01 challenges on" , this . address ( ) ) ; } ) ; // handles your app var server = require ( 'https' ) . createServer ( lex . httpsOptions , lex . middleware ( app ) ) server . listen ( 443 , function ( ) { console . log ( "Listening for ACME tls-sni-01 challenges and serve app on" , this . address ( ) ) ; } ) ;

I wanted to set-up a multi-domain SSL certificate using LetsEncrypt for my app “Dead Simple Screen Sharing” because people complained about the long meeting URL, so I bought a short domain mnow.io and edited the code to generate short 6 digit meeting ids, so the new meeting URL became much cleaner e.g https://mnow.io/345686 instead of the original https://app.deadsimplescreensharing.com/meeting/bgasGca-1

But I needed a new SSL certificate for the domain mnow.io, and as this domain will also be pointed to the same server, I required a multi-domain SSL certificate.

I had already configured greenlock-express (letsencrypt-express is now called as greenlock-express) on my server so just had to make some changes in the configuration and add my domain, but simply adding the domain in the domains array didn’t work, so after some trial and error I finally figured it out.

Here is the final code snippet, that you can use, add this in your app.js or server.js:

/** * Setting up https */ var lex = require('greenlock-express').create({ server: 'production', challenges: { 'http-01': require('le-challenge-fs').create({ webrootPath: '/tmp/acme-challenges' }) }, store: require('le-store-certbot').create({ webrootPath: '/tmp/acme-challenges' }), approveDomains: function(opts, certs, cb) { if(certs) { opts.domains = ['domain1.com', 'domain2.com'] } else { opts.email = 'youremail@example.com', opts.agreeTos = true; } cb(null, { options: opts, certs: certs }); } }); //Optional: Add this line if you want to redirect all your traffic to https require('http').createServer(lex.middleware(require('redirect-https')())).listen(80, function () { console.log("Listening for ACME http-01 challenges on", this.address()); }); // handles your app var server = require('https').createServer(lex.httpsOptions, lex.middleware(app)) server.listen(443, function () { console.log("Listening for ACME tls-sni-01 challenges and serve app on", this.address()); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 /** * Setting up https */ var lex = require ( 'greenlock-express' ) . create ( { server : 'production' , challenges : { 'http-01' : require ( 'le-challenge-fs' ) . create ( { webrootPath : '/tmp/acme-challenges' } ) } , store : require ( 'le-store-certbot' ) . create ( { webrootPath : '/tmp/acme-challenges' } ) , approveDomains : function ( opts , certs , cb ) { if ( certs ) { opts . domains = [ 'domain1.com' , 'domain2.com' ] } else { opts . email = 'youremail@example.com' , opts . agreeTos = true ; } cb ( null , { options : opts , certs : certs } ) ; } } ) ; //Optional: Add this line if you want to redirect all your traffic to https require ( 'http' ) . createServer ( lex . middleware ( require ( 'redirect-https' ) ( ) ) ) . listen ( 80 , function ( ) { console . log ( "Listening for ACME http-01 challenges on" , this . address ( ) ) ; } ) ; // handles your app var server = require ( 'https' ) . createServer ( lex . httpsOptions , lex . middleware ( app ) ) server . listen ( 443 , function ( ) { console . log ( "Listening for ACME tls-sni-01 challenges and serve app on" , this . address ( ) ) ; } ) ;

In line 10 replace ‘domain1.com’ and ‘domain2.com’ with your own domains, if you have more than 2 domains you can add them in the array, if you have only one domain then you also keep just one single domain in the array.

In line 12 replace ‘youremail@example.com’ with your email address.

The code on line 19 to 23 is optional, you can add it if you want to redirect all your traffic to https, and if you skip it then both HTTP and HTTPS versions of your site will be live.

Let me know if you have any questions, concerns or suggestions in the comments.