Skip to content

Commit

Permalink
fix(ssl): copy acme certificates from home location if they exist
Browse files Browse the repository at this point in the history
closes TryGhost#309
- if a user deletes their instance and recreates it with the same domain, then acme will fail to generate the certificate because it already exists & is not due for renewal. We work around this issue by looking for the error and copying the right keys if it already exists
  • Loading branch information
acburdine committed Jul 8, 2017
1 parent 43ceff1 commit 8a2591c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
4 changes: 1 addition & 3 deletions extensions/nginx/index.js
Expand Up @@ -161,9 +161,7 @@ class NginxExtension extends cli.Extension {
task: () => this.restartNginx()
}, {
title: 'Getting SSL Certificate',
task: () => {
return letsencrypt(ctx.instance, argv.sslemail, argv.sslstaging);
}
task: () => letsencrypt(ctx.instance, argv.sslemail, argv.sslstaging)
}, {
title: 'Generating Encryption Key (may take a few minutes)',
task: (ctx) => {
Expand Down
28 changes: 20 additions & 8 deletions extensions/nginx/letsencrypt.js
@@ -1,5 +1,6 @@
'use strict';
const fs = require('fs-extra');
const os = require('os');
const url = require('url');
const path = require('path');
const execa = require('execa');
Expand All @@ -21,16 +22,16 @@ module.exports = function letsencrypt(instance, email, staging, renew) {
downloadPromise = download(acmeUrl).then(data => fs.writeFile(acmePath, data, {mode: 0o755}));
}

let hostname = url.parse(instance.config.get('url')).hostname;
let letsencryptFolder = path.join(instance.dir, 'system', 'letsencrypt');
let fullchain = path.join(letsencryptFolder, 'fullchain.pem');
let privkey = path.join(letsencryptFolder, 'privkey.pem');

return downloadPromise.then(() => {
let hostname = url.parse(instance.config.get('url')).hostname;
let rootPath = path.resolve(instance.dir, 'system', 'nginx-root');
let letsencryptFolder = path.join(instance.dir, 'system', 'letsencrypt');

fs.ensureDirSync(letsencryptFolder);

let fullchain = path.join(letsencryptFolder, 'fullchain.pem');
let privkey = path.join(letsencryptFolder, 'privkey.pem');

let cmd = `${acmePath} --${renew ? 'renew' : 'issue'} --domain ${hostname} --webroot ${rootPath} ` +
`--accountemail ${email} --key-file ${privkey} --fullchain-file ${fullchain}${staging ? ' --staging' : ''}`;

Expand All @@ -43,10 +44,21 @@ module.exports = function letsencrypt(instance, email, staging, renew) {

// This is an execa error
if (error.stdout.match(/Skip/)) {
instance.ui.log('Certificate not due for renewal yet, skipping', 'yellow');
return;
// Certificate already exists
if (renew) {
instance.ui.log('Certificate not due for renewal yet, skipping', 'yellow');
return;
}

// We're setting up a new instance, we want to re-use the certs
let acmeScriptDir = path.join(os.homedir(), '.acme.sh', hostname);

return Promise.all([
fs.copy(path.join(acmeScriptDir, 'fullchain.cer'), fullchain),
fs.copy(path.join(acmeScriptDir, `${hostname}.key`), privkey)
]);
}

return Promise.reject(new errors.ProcessError(error));
});;
});
};

0 comments on commit 8a2591c

Please sign in to comment.