mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Adds certbot plugin installation check on startup
This commit is contained in:
		| @@ -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; | ||||||
|  |  | ||||||
| @@ -818,11 +818,9 @@ const internalCertificate = { | |||||||
| 		if (certificate.meta.dns_provider === 'route53') { | 		if (certificate.meta.dns_provider === 'route53') { | ||||||
| 			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; | ||||||
| 			}) | 			}) | ||||||
|   | |||||||
| @@ -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); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -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." | ||||||
|   | |||||||
| @@ -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', | ||||||
| 	}, | 	}, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user