Adds certbot plugin installation check on startup

This commit is contained in:
chaptergy 2020-10-17 12:13:08 +02:00
parent 5c2f13ed8e
commit 1028de8158
4 changed files with 64 additions and 33 deletions

View File

@ -788,7 +788,7 @@ const internalCertificate = {
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
const credentials_loc = '/etc/letsencrypt/credentials-' + certificate.id; const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
const credentials_cmd = 'echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\''; const credentials_cmd = 'echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
const prepare_cmd = 'pip3 install ' + dns_plugin.package_name + '==' + dns_plugin.package_version; const prepare_cmd = 'pip3 install ' + dns_plugin.package_name + '==' + dns_plugin.package_version;
@ -819,10 +819,8 @@ const internalCertificate = {
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd; main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
} }
const teardown_cmd = `rm '${credentials_loc}'`;
if (debug_mode) { if (debug_mode) {
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`); logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd}`);
} }
return utils.exec(credentials_cmd) return utils.exec(credentials_cmd)
@ -831,11 +829,15 @@ const internalCertificate = {
.then(() => { .then(() => {
return utils.exec(main_cmd) return utils.exec(main_cmd)
.then(async (result) => { .then(async (result) => {
await utils.exec(teardown_cmd);
logger.info(result); logger.info(result);
return result; return result;
}); });
}); });
}).catch(async (err) => {
// Don't fail if file does not exist
const delete_credentials_cmd = `rm -f '${credentials_loc}' || true`;
await utils.exec(delete_credentials_cmd);
throw err;
}); });
}, },
@ -922,10 +924,6 @@ const internalCertificate = {
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
const credentials_loc = '/etc/letsencrypt/credentials-' + certificate.id;
const credentials_cmd = 'echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
const prepare_cmd = 'pip3 install ' + dns_plugin.package_name + '==' + dns_plugin.package_version;
let main_cmd = let main_cmd =
certbot_command + ' renew --non-interactive ' + certbot_command + ' renew --non-interactive ' +
'--cert-name "npm-' + certificate.id + '" ' + '--cert-name "npm-' + certificate.id + '" ' +
@ -937,23 +935,14 @@ const internalCertificate = {
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd; main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
} }
const teardown_cmd = `rm '${credentials_loc}'`;
if (debug_mode) { if (debug_mode) {
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`); logger.info('Command:', main_cmd);
} }
return utils.exec(credentials_cmd) return utils.exec(main_cmd)
.then(() => { .then(async (result) => {
return utils.exec(prepare_cmd) logger.info(result);
.then(() => { return result;
return utils.exec(main_cmd)
.then(async (result) => {
await utils.exec(teardown_cmd);
logger.info(result);
return result;
});
});
}); });
}, },
@ -965,20 +954,21 @@ const internalCertificate = {
revokeLetsEncryptSsl: (certificate, throw_errors) => { revokeLetsEncryptSsl: (certificate, throw_errors) => {
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
let cmd = certbot_command + ' revoke --non-interactive ' + const main_cmd = certbot_command + ' revoke --non-interactive ' +
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' + '--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
'--delete-after-revoke ' + '--delete-after-revoke ' +
(le_staging ? '--staging' : ''); (le_staging ? '--staging' : '');
// Don't fail command if file does not exist
const delete_credentials_cmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
if (debug_mode) { if (debug_mode) {
logger.info('Command:', cmd); logger.info('Command:', main_cmd + '; ' + delete_credentials_cmd);
} }
return utils.exec(cmd) return utils.exec(main_cmd)
.then((result) => { .then(async (result) => {
if (debug_mode) { await utils.exec(delete_credentials_cmd);
logger.info('Command:', cmd);
}
logger.info(result); logger.info(result);
return result; return result;
}) })

View File

@ -2,10 +2,13 @@ const fs = require('fs');
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa');
const config = require('config'); const config = require('config');
const logger = require('./logger').setup; const logger = require('./logger').setup;
const certificateModel = require('./models/certificate');
const userModel = require('./models/user'); const userModel = require('./models/user');
const userPermissionModel = require('./models/user_permission'); const userPermissionModel = require('./models/user_permission');
const utils = require('./lib/utils');
const authModel = require('./models/auth'); const authModel = require('./models/auth');
const settingModel = require('./models/setting'); const settingModel = require('./models/setting');
const dns_plugins = require('./global/certbot-dns-plugins');
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
/** /**
@ -155,8 +158,46 @@ const setupDefaultSettings = () => {
}); });
}; };
/**
* Installs all Certbot plugins which are required for an installed certificate
*
* @returns {Promise}
*/
const setupCertbotPlugins = () => {
return certificateModel
.query()
.where('is_deleted', 0)
.andWhere('provider', 'letsencrypt')
.then((certificates) => {
if (certificates && certificates.length) {
let plugins = [];
let promises = [];
certificates.map(function (certificate) {
if (certificate.meta && certificate.meta.dns_challenge === true) {
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
const package = `${dns_plugin.package_name}==${dns_plugin.package_version}`;
if (plugins.indexOf(package) === -1) plugins.push(package);
// Make sure credentials file exists
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir /etc/letsencrypt/credentials; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
promises.push(utils.exec(credentials_cmd));
}
});
const install_cmd = 'pip3 install ' + plugins.join(' ');
promises.push(utils.exec(install_cmd));
return Promise.all(promises).then(() => {
logger.info('Added Certbot plugins ' + plugins.join(', '));
});
}
});
};
module.exports = function () { module.exports = function () {
return setupJwt() return setupJwt()
.then(setupDefaultUser) .then(setupDefaultUser)
.then(setupDefaultSettings); .then(setupDefaultSettings)
.then(setupCertbotPlugins);
}; };

View File

@ -109,7 +109,7 @@
"please-choose": "Please Choose...", "please-choose": "Please Choose...",
"credentials-file-content": "Credentials File Content", "credentials-file-content": "Credentials File Content",
"credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider", "credentials-file-content-info": "This plugin requires a configuration file containing an API token or other credentials to your provider",
"stored-as-plaintext-info": "This data will be stored as plaintext in the database!", "stored-as-plaintext-info": "This data will be stored as plaintext in the database and in a file!",
"propagation-seconds": "Propagation Seconds", "propagation-seconds": "Propagation Seconds",
"propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.", "propagation-seconds-info": "Leave empty to use the plugins default value. Number of seconds to wait for DNS propagation.",
"processing-info": "Processing... This might take a few minutes." "processing-info": "Processing... This might take a few minutes."

View File

@ -181,7 +181,7 @@ dns_netcup_api_password = abcdef0123456789abcdef01234567abcdef0123`,
njalla: { njalla: {
display_name: 'Njalla', display_name: 'Njalla',
package_name: 'certbot-dns-njalla', package_name: 'certbot-dns-njalla',
package_version: '0.0.4', package_version: '1.0.0',
credentials: 'certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567', credentials: 'certbot_dns_njalla:dns_njalla_token = 0123456789abcdef0123456789abcdef01234567',
full_plugin_name: 'certbot-dns-njalla:dns-njalla', full_plugin_name: 'certbot-dns-njalla:dns-njalla',
}, },