Created
June 3, 2016 03:48
-
-
Save lukemelia/bf727fb4f28811c115023e0aa0368021 to your computer and use it in GitHub Desktop.
letsencrypt with node and heroku
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var LE = require('letsencrypt'); | |
var pem = require('pem'); | |
var RSVP = require('rsvp'); | |
var fs = require('fs'); | |
var path = require('path'); | |
var mkdirp = require('mkdirp'); | |
var domains, herokuAppName, duplicate; | |
if (process.env.YAPP_ENV === 'qa') { | |
domains = ['heroku.yappqa.us', 'my.yappqa.us', 'api.yappqa.us', 'support.yappqa.us' ]; | |
herokuAppName = 'qa-yapp-cedar'; | |
duplicate = true; // create new cert even if they are less than 1 week old | |
} else if (process.env.YAPP_ENV === 'prod') { | |
domains = ['heroku.yapp.us', 'my.yapp.us', 'api.yapp.us', 'support.yapp.us']; | |
herokuAppName = 'yapp-cedar'; | |
duplicate = false; | |
} else { | |
throw new Error('Must provide valid YAPP_ENV (qa or prod)'); | |
} | |
var redisUrlExtraction = new RSVP.Promise(function(resolve, reject){ | |
var exec = require('child_process').exec; | |
exec('heroku config:get REDISTOGO_URL --app ' + herokuAppName, function (error, stdout, stderr) { | |
var redisUrl = stdout.replace(/\n/, '').replace(/\/\/redistogo:/, '//:'); | |
if (error) { | |
reject(error); | |
} else { | |
resolve(redisUrl); | |
} | |
}); | |
}); | |
var createPrivateKey = RSVP.denodeify(pem.createPrivateKey); | |
var privateKeyGeneration = createPrivateKey(2048).then(function(privateKey) { | |
var pemPath = require('homedir')() + '/letsencrypt/etc/live/' + domains[0] + '/privkey.pem'; | |
mkdirp.sync(path.dirname(pemPath)); | |
fs.writeFileSync(pemPath, privateKey.key); | |
}).catch(function(reason){ | |
console.log(reason); | |
throw reason; | |
}); | |
privateKeyGeneration.then(function(){ | |
var config = { | |
server: LE.productionServerUrl, | |
manual: true, | |
configDir: require('homedir')() + '/letsencrypt/etc', | |
privkeyPath: ':config/live/:hostname/privkey.pem', | |
fullchainPath: ':config/live/:hostname/fullchain.pem', | |
certPath: ':config/live/:hostname/cert.pem', | |
chainPath: ':config/live/:hostname/chain.pem', | |
debug: true | |
}; | |
var handlers = { | |
setChallenge: function (opts, hostname, key, val, cb) { | |
// called during the ACME server handshake, before validation | |
redisUrlExtraction.then(function(redisUrl){ | |
var redis = require("redis"); | |
var redisClient = redis.createClient(redisUrl); | |
redisClient.set("letsencrypt:" + key, val, function(err){ | |
// console.log("set redis key letsencrypt:" + key + " = " + val); | |
if (err) { | |
console.log(err); | |
throw err; | |
} | |
cb(); | |
}); | |
}).catch(function(reason){ | |
console.log(reason); | |
throw reason; | |
}); | |
}, | |
removeChallenge: function (opts, hostname, key, cb) {} // called after validation on both success and failure | |
}; | |
var le = LE.create(config, handlers); | |
le.register({ // either renews or registers | |
domains: domains, | |
email: '[email protected]', | |
agreeTos: true, | |
duplicate: true | |
}, function (err, results) { | |
if (err) { | |
console.error('[Error]: node-letsencrypt'); | |
console.error(err.stack || err); | |
return; | |
} | |
if (!results || ('object' !== typeof results)) { | |
console.error("Error: An unknown error occurred. My best guess is that we got an error that we're not used to from the ACME server and accidentally interpretted it as a success... or forgot to expose the error."); | |
console.error(results); | |
err = new Error("Here's a stack trace, in case it helps:"); | |
console.error(err.stack); | |
return; | |
} | |
// if (handlers.closeServers) { | |
// handlers.closeServers(); | |
// } | |
console.log('\nCertificate files downloaded! Please run:'); | |
console.log("heroku certs:update " + results.fullchainPath + ' ' + results.privkeyPath + ' --app ' + herokuAppName); | |
process.exit(0); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "node-ssl-script", | |
"dependencies": { | |
"homedir": "^0.6.0", | |
"letsencrypt": "1.4.4", | |
"mkdirp": "^0.5.1", | |
"pem": "^1.8.3", | |
"redis": "^2.6.1", | |
"rsvp": "^3.2.1" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment