You've already forked nginx-proxy-manager
							
							
				mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-30 18:05:34 +03:00 
			
		
		
		
	- Changes for objection migration - Moved common access template code to an include - Fixed access rules configuration generation
		
			
				
	
	
		
			148 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const https         = require('https');
 | |
| const fs            = require('fs');
 | |
| const logger        = require('../logger').ip_ranges;
 | |
| const error         = require('../lib/error');
 | |
| const utils         = require('../lib/utils');
 | |
| const internalNginx = require('./nginx');
 | |
| 
 | |
| 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 regIpV4 = /^(\d+\.?){4}\/\d+/;
 | |
| const regIpV6 = /^(([\da-fA-F]+)?:)+\/\d+/;
 | |
| 
 | |
| 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').filter((line) => regIpV4.test(line));
 | |
| 					ip_ranges = [... ip_ranges, ... items];
 | |
| 				})
 | |
| 				.then(() => {
 | |
| 					return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL);
 | |
| 				})
 | |
| 				.then((cloudfare_data) => {
 | |
| 					let items = cloudfare_data.split('\n').filter((line) => regIpV6.test(line));
 | |
| 					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) => {
 | |
| 		const renderEngine = utils.getRenderEngine();
 | |
| 		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;
 |