mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Implements backend changes to allow more dns challenges
This commit is contained in:
		| @@ -13,6 +13,7 @@ const internalNginx    = require('./nginx'); | |||||||
| const internalHost     = require('./host'); | const internalHost     = require('./host'); | ||||||
| const certbot_command  = '/usr/bin/certbot'; | const certbot_command  = '/usr/bin/certbot'; | ||||||
| const le_config        = '/etc/letsencrypt.ini'; | const le_config        = '/etc/letsencrypt.ini'; | ||||||
|  | const dns_plugins      = require('../../utils/certbot-dns-plugins') | ||||||
|  |  | ||||||
| function omissions() { | function omissions() { | ||||||
| 	return ['is_deleted']; | 	return ['is_deleted']; | ||||||
| @@ -141,11 +142,11 @@ const internalCertificate = { | |||||||
| 								}); | 								}); | ||||||
| 						}) | 						}) | ||||||
| 						.then((in_use_result) => { | 						.then((in_use_result) => { | ||||||
| 							// Is CloudFlare, no config needed, so skip 3 and 5. | 							// With DNS challenge no config is needed, so skip 3 and 5. | ||||||
| 							if (data.meta.cloudflare_use) { | 							if (certificate.meta.dns_challenge) { | ||||||
| 								return internalNginx.reload().then(() => { | 								return internalNginx.reload().then(() => { | ||||||
| 									// 4. Request cert | 									// 4. Request cert | ||||||
| 									return internalCertificate.requestLetsEncryptCloudFlareDnsSsl(certificate, data.meta.cloudflare_token); | 									return internalCertificate.requestLetsEncryptSslWithDnsChallenge(certificate); | ||||||
| 								}) | 								}) | ||||||
| 									.then(internalNginx.reload) | 									.then(internalNginx.reload) | ||||||
| 									.then(() => { | 									.then(() => { | ||||||
| @@ -772,35 +773,58 @@ const internalCertificate = { | |||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * @param   {Object}  certificate   the certificate row | 	 * @param   {Object}  certificate   			the certificate row | ||||||
| 	 * @param	{String} apiToken		the cloudflare api token | 	 * @param		{String} 	dns_provider				the dns provider name (key used in `certbot-dns-plugins.js`) | ||||||
|  | 	 * @param		{String | null} 	credentials	the content of this providers credentials file | ||||||
|  | 	 * @param		{String} 	propagation_seconds	the cloudflare api token | ||||||
| 	 * @returns {Promise} | 	 * @returns {Promise} | ||||||
| 	 */ | 	 */ | ||||||
| 	requestLetsEncryptCloudFlareDnsSsl: (certificate, apiToken) => { | 	requestLetsEncryptSslWithDnsChallenge: (certificate) => { | ||||||
| 		logger.info('Requesting Let\'sEncrypt certificates via Cloudflare DNS for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); | 		const dns_plugin = dns_plugins[certificate.meta.dns_provider]; | ||||||
|  |  | ||||||
| 		let tokenLoc = '~/cloudflare-token'; | 		if(!dns_plugin){ | ||||||
| 		let storeKey = 'echo "dns_cloudflare_api_token = ' + apiToken + '" > ' + tokenLoc;	 | 			throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`) | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		let cmd =  | 		logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); | ||||||
| 			storeKey + ' && ' + |  | ||||||
|  | 		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; | ||||||
|  |  | ||||||
|  | 		const main_cmd =  | ||||||
| 			certbot_command + ' certonly --non-interactive ' + | 			certbot_command + ' certonly --non-interactive ' + | ||||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | 			'--cert-name "npm-' + certificate.id + '" ' + | ||||||
| 			'--agree-tos ' + | 			'--agree-tos ' + | ||||||
| 			'--email "' + certificate.meta.letsencrypt_email + '" ' +			 | 			'--email "' + certificate.meta.letsencrypt_email + '" ' +			 | ||||||
| 			'--domains "' + certificate.domain_names.join(',') + '" ' + | 			'--domains "' + certificate.domain_names.join(',') + '" ' + | ||||||
| 			'--dns-cloudflare --dns-cloudflare-credentials ' + tokenLoc + | 			'--authenticator ' + dns_plugin.full_plugin_name + ' ' + | ||||||
| 			(le_staging ? ' --staging' : '') | 			'--' + dns_plugin.full_plugin_name + '-credentials "' + credentials_loc + '"' + | ||||||
| 			+ ' && rm ' + tokenLoc; | 			( | ||||||
|  | 				certificate.meta.propagation_seconds !== undefined  | ||||||
|  | 				? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds  | ||||||
|  | 				: '' | ||||||
|  | 			) + | ||||||
|  | 			(le_staging ? ' --staging' : ''); | ||||||
|  | 		 | ||||||
|  | 		const teardown_cmd = `rm '${credentials_loc}'`; | ||||||
|  |  | ||||||
| 		if (debug_mode) { | 		if (debug_mode) { | ||||||
| 			logger.info('Command:', cmd); | 			logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return utils.exec(cmd).then((result) => { | 		return utils.exec(credentials_cmd) | ||||||
| 			logger.info(result); | 			.then(() => { | ||||||
| 			return result; | 				return utils.exec(prepare_cmd) | ||||||
| 		}); | 					.then(() => { | ||||||
|  | 						return utils.exec(main_cmd) | ||||||
|  | 							.then(async (result) => { | ||||||
|  | 								await utils.exec(teardown_cmd); | ||||||
|  | 								logger.info(result); | ||||||
|  | 								return result; | ||||||
|  | 							}); | ||||||
|  | 					}); | ||||||
|  | 			}); | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -817,7 +841,7 @@ const internalCertificate = { | |||||||
| 			}) | 			}) | ||||||
| 			.then((certificate) => { | 			.then((certificate) => { | ||||||
| 				if (certificate.provider === 'letsencrypt') { | 				if (certificate.provider === 'letsencrypt') { | ||||||
| 					let renewMethod = certificate.meta.cloudflare_use ? internalCertificate.renewLetsEncryptCloudFlareSsl : internalCertificate.renewLetsEncryptSsl;		 | 					let renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;		 | ||||||
|  |  | ||||||
| 					return renewMethod(certificate) | 					return renewMethod(certificate) | ||||||
| 						.then(() => { | 						.then(() => { | ||||||
| @@ -877,22 +901,42 @@ const internalCertificate = { | |||||||
| 	 * @param   {Object}  certificate   the certificate row | 	 * @param   {Object}  certificate   the certificate row | ||||||
| 	 * @returns {Promise} | 	 * @returns {Promise} | ||||||
| 	 */ | 	 */ | ||||||
| 	renewLetsEncryptCloudFlareSsl: (certificate) => { | 	renewLetsEncryptSslWithDnsChallenge: (certificate) => { | ||||||
| 		logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', ')); | 		const dns_plugin = dns_plugins[certificate.meta.dns_provider]; | ||||||
|  |  | ||||||
| 		let cmd = certbot_command + ' renew --non-interactive ' + | 		if(!dns_plugin){ | ||||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | 			throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`) | ||||||
| 			'--disable-hook-validation ' + |  | ||||||
| 			(le_staging ? '--staging' : ''); |  | ||||||
|  |  | ||||||
| 		if (debug_mode) { |  | ||||||
| 			logger.info('Command:', cmd); |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return utils.exec(cmd) | 		logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`); | ||||||
| 			.then((result) => { |  | ||||||
| 				logger.info(result); | 		const credentials_loc = `/etc/letsencrypt/credentials-${certificate.id}`; | ||||||
| 				return result; | 		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 main_cmd = | ||||||
|  | 			certbot_command + ' renew --non-interactive ' + | ||||||
|  | 			'--cert-name "npm-' + certificate.id + '" ' + | ||||||
|  | 			'--disable-hook-validation' + | ||||||
|  | 			(le_staging ? ' --staging' : ''); | ||||||
|  |  | ||||||
|  | 		const teardown_cmd = `rm '${credentials_loc}'`; | ||||||
|  |  | ||||||
|  | 		if (debug_mode) { | ||||||
|  | 			logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd} && ${teardown_cmd}`); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return utils.exec(credentials_cmd) | ||||||
|  | 			.then(() => { | ||||||
|  | 				return utils.exec(prepare_cmd) | ||||||
|  | 					.then(() => { | ||||||
|  | 						return utils.exec(main_cmd) | ||||||
|  | 							.then(async (result) => { | ||||||
|  | 								await utils.exec(teardown_cmd); | ||||||
|  | 								logger.info(result); | ||||||
|  | 								return result; | ||||||
|  | 							}); | ||||||
|  | 					}); | ||||||
| 			}); | 			}); | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -42,11 +42,23 @@ | |||||||
|         "letsencrypt_agree": { |         "letsencrypt_agree": { | ||||||
|           "type": "boolean" |           "type": "boolean" | ||||||
|         }, |         }, | ||||||
|         "cloudflare_use": { |         "dns_challenge": { | ||||||
|           "type": "boolean" |           "type": "boolean" | ||||||
|         }, |         }, | ||||||
|         "cloudflare_token": { |         "dns_provider": { | ||||||
|           "type": "string" |           "type": "string" | ||||||
|  |         }, | ||||||
|  |         "dns_provider_credentials": { | ||||||
|  |           "type": "string" | ||||||
|  |         }, | ||||||
|  |         "propagation_seconds": { | ||||||
|  |           "anyOf": [ | ||||||
|  |             {  | ||||||
|  |               "type": "integer", | ||||||
|  |               "minimum": 0  | ||||||
|  |             } | ||||||
|  |           ] | ||||||
|  |            | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user