mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	v2.1.0 (#293)
* Fix wrapping when too many hosts are shown (#207) * Update npm packages, fixes CVE-2019-10757 * Revert some breaking packages * Major overhaul - Docker buildx support in CI - Cypress API Testing in CI - Restructured folder layout (insert clean face meme) - Added Swagger documentation and validate API against that (to be completed) - Use common base image for all supported archs, which includes updated nginx with ipv6 support - Updated certbot and changes required for it - Large amount of Hosts names will wrap in UI - Updated packages for frontend - Version bump 2.1.0 * Updated documentation * Fix JWT expire time going crazy. Now set to 1day * Backend JS formatting rules * Remove v1 importer, I doubt anyone is using v1 anymore * Added backend formatting rules and enforce them in Jenkins builds * Fix CI, doesn't need a tty * Thanks bcrypt. Why can't you just be normal. * Cleanup after syntax check Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										147
									
								
								backend/internal/ip_ranges.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								backend/internal/ip_ranges.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| const https         = require('https'); | ||||
| const fs            = require('fs'); | ||||
| const logger        = require('../logger').ip_ranges; | ||||
| const error         = require('../lib/error'); | ||||
| const internalNginx = require('./nginx'); | ||||
| const Liquid        = require('liquidjs'); | ||||
|  | ||||
| const CLOUDFRONT_URL   = 'https://ip-ranges.amazonaws.com/ip-ranges.json'; | ||||
| const CLOUDFARE_V4_URL = 'https://www.cloudflare.com/ips-v4'; | ||||
| const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6'; | ||||
|  | ||||
| const internalIpRanges = { | ||||
|  | ||||
| 	interval_timeout:    1000 * 60 * 60 * 6, // 6 hours | ||||
| 	interval:            null, | ||||
| 	interval_processing: false, | ||||
| 	iteration_count:     0, | ||||
|  | ||||
| 	initTimer: () => { | ||||
| 		logger.info('IP Ranges Renewal Timer initialized'); | ||||
| 		internalIpRanges.interval = setInterval(internalIpRanges.fetch, internalIpRanges.interval_timeout); | ||||
| 	}, | ||||
|  | ||||
| 	fetchUrl: (url) => { | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			logger.info('Fetching ' + url); | ||||
| 			return https.get(url, (res) => { | ||||
| 				res.setEncoding('utf8'); | ||||
| 				let raw_data = ''; | ||||
| 				res.on('data', (chunk) => { | ||||
| 					raw_data += chunk; | ||||
| 				}); | ||||
|  | ||||
| 				res.on('end', () => { | ||||
| 					resolve(raw_data); | ||||
| 				}); | ||||
| 			}).on('error', (err) => { | ||||
| 				reject(err); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	/** | ||||
| 	 * Triggered at startup and then later by a timer, this will fetch the ip ranges from services and apply them to nginx. | ||||
| 	 */ | ||||
| 	fetch: () => { | ||||
| 		if (!internalIpRanges.interval_processing) { | ||||
| 			internalIpRanges.interval_processing = true; | ||||
| 			logger.info('Fetching IP Ranges from online services...'); | ||||
|  | ||||
| 			let ip_ranges = []; | ||||
|  | ||||
| 			return internalIpRanges.fetchUrl(CLOUDFRONT_URL) | ||||
| 				.then((cloudfront_data) => { | ||||
| 					let data = JSON.parse(cloudfront_data); | ||||
|  | ||||
| 					if (data && typeof data.prefixes !== 'undefined') { | ||||
| 						data.prefixes.map((item) => { | ||||
| 							if (item.service === 'CLOUDFRONT') { | ||||
| 								ip_ranges.push(item.ip_prefix); | ||||
| 							} | ||||
| 						}); | ||||
| 					} | ||||
|  | ||||
| 					if (data && typeof data.ipv6_prefixes !== 'undefined') { | ||||
| 						data.ipv6_prefixes.map((item) => { | ||||
| 							if (item.service === 'CLOUDFRONT') { | ||||
| 								ip_ranges.push(item.ipv6_prefix); | ||||
| 							} | ||||
| 						}); | ||||
| 					} | ||||
| 				}) | ||||
| 				.then(() => { | ||||
| 					return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL); | ||||
| 				}) | ||||
| 				.then((cloudfare_data) => { | ||||
| 					let items = cloudfare_data.split('\n'); | ||||
| 					ip_ranges = [... ip_ranges, ... items]; | ||||
| 				}) | ||||
| 				.then(() => { | ||||
| 					return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL); | ||||
| 				}) | ||||
| 				.then((cloudfare_data) => { | ||||
| 					let items = cloudfare_data.split('\n'); | ||||
| 					ip_ranges = [... ip_ranges, ... items]; | ||||
| 				}) | ||||
| 				.then(() => { | ||||
| 					let clean_ip_ranges = []; | ||||
| 					ip_ranges.map((range) => { | ||||
| 						if (range) { | ||||
| 							clean_ip_ranges.push(range); | ||||
| 						} | ||||
| 					}); | ||||
|  | ||||
| 					return internalIpRanges.generateConfig(clean_ip_ranges) | ||||
| 						.then(() => { | ||||
| 							if (internalIpRanges.iteration_count) { | ||||
| 								// Reload nginx | ||||
| 								return internalNginx.reload(); | ||||
| 							} | ||||
| 						}); | ||||
| 				}) | ||||
| 				.then(() => { | ||||
| 					internalIpRanges.interval_processing = false; | ||||
| 					internalIpRanges.iteration_count++; | ||||
| 				}) | ||||
| 				.catch((err) => { | ||||
| 					logger.error(err.message); | ||||
| 					internalIpRanges.interval_processing = false; | ||||
| 				}); | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	/** | ||||
| 	 * @param   {Array}  ip_ranges | ||||
| 	 * @returns {Promise} | ||||
| 	 */ | ||||
| 	generateConfig: (ip_ranges) => { | ||||
| 		let renderEngine = Liquid({ | ||||
| 			root: __dirname + '/../templates/' | ||||
| 		}); | ||||
|  | ||||
| 		return new Promise((resolve, reject) => { | ||||
| 			let template = null; | ||||
| 			let filename = '/etc/nginx/conf.d/include/ip_ranges.conf'; | ||||
| 			try { | ||||
| 				template = fs.readFileSync(__dirname + '/../templates/ip_ranges.conf', {encoding: 'utf8'}); | ||||
| 			} catch (err) { | ||||
| 				reject(new error.ConfigurationError(err.message)); | ||||
| 				return; | ||||
| 			} | ||||
|  | ||||
| 			renderEngine | ||||
| 				.parseAndRender(template, {ip_ranges: ip_ranges}) | ||||
| 				.then((config_text) => { | ||||
| 					fs.writeFileSync(filename, config_text, {encoding: 'utf8'}); | ||||
| 					resolve(true); | ||||
| 				}) | ||||
| 				.catch((err) => { | ||||
| 					logger.warn('Could not write ' + filename + ':', err.message); | ||||
| 					reject(new error.ConfigurationError(err.message)); | ||||
| 				}); | ||||
| 		}); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| module.exports = internalIpRanges; | ||||
		Reference in New Issue
	
	Block a user