Skip to content

Commit 3836f7c

Browse files
committed
Fetch ip ranges for CDN servers, Cloudfront and Cloudfare
1 parent 9fcd32c commit 3836f7c

File tree

6 files changed

+355
-8
lines changed

6 files changed

+355
-8
lines changed

rootfs/etc/nginx/conf.d/default.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Generated IP Ranges for safe real IP determination
2+
include conf.d/include/ip_ranges.conf;
3+
14
# Healthcheck Host which proxies to the Manager,
25
# thus the healthcheck ensures both services are running
36
server {
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
2+
set_real_ip_from 13.124.199.0/24;
3+
4+
set_real_ip_from 34.226.14.0/24;
5+
6+
set_real_ip_from 52.124.128.0/17;
7+
8+
set_real_ip_from 54.230.0.0/16;
9+
10+
set_real_ip_from 54.239.128.0/18;
11+
12+
set_real_ip_from 52.82.128.0/19;
13+
14+
set_real_ip_from 99.84.0.0/16;
15+
16+
set_real_ip_from 52.15.127.128/26;
17+
18+
set_real_ip_from 35.158.136.0/24;
19+
20+
set_real_ip_from 52.57.254.0/24;
21+
22+
set_real_ip_from 18.216.170.128/25;
23+
24+
set_real_ip_from 13.54.63.128/26;
25+
26+
set_real_ip_from 13.59.250.0/26;
27+
28+
set_real_ip_from 13.210.67.128/26;
29+
30+
set_real_ip_from 35.167.191.128/26;
31+
32+
set_real_ip_from 52.47.139.0/24;
33+
34+
set_real_ip_from 52.199.127.192/26;
35+
36+
set_real_ip_from 52.212.248.0/26;
37+
38+
set_real_ip_from 205.251.192.0/19;
39+
40+
set_real_ip_from 52.66.194.128/26;
41+
42+
set_real_ip_from 54.239.192.0/19;
43+
44+
set_real_ip_from 70.132.0.0/18;
45+
46+
set_real_ip_from 13.32.0.0/15;
47+
48+
set_real_ip_from 13.113.203.0/24;
49+
50+
set_real_ip_from 34.195.252.0/24;
51+
52+
set_real_ip_from 35.162.63.192/26;
53+
54+
set_real_ip_from 34.223.12.224/27;
55+
56+
set_real_ip_from 13.35.0.0/16;
57+
58+
set_real_ip_from 204.246.172.0/23;
59+
60+
set_real_ip_from 204.246.164.0/22;
61+
62+
set_real_ip_from 52.56.127.0/25;
63+
64+
set_real_ip_from 204.246.168.0/22;
65+
66+
set_real_ip_from 13.228.69.0/24;
67+
68+
set_real_ip_from 34.216.51.0/25;
69+
70+
set_real_ip_from 71.152.0.0/17;
71+
72+
set_real_ip_from 216.137.32.0/19;
73+
74+
set_real_ip_from 205.251.249.0/24;
75+
76+
set_real_ip_from 99.86.0.0/16;
77+
78+
set_real_ip_from 52.46.0.0/18;
79+
80+
set_real_ip_from 52.84.0.0/15;
81+
82+
set_real_ip_from 54.233.255.128/26;
83+
84+
set_real_ip_from 64.252.64.0/18;
85+
86+
set_real_ip_from 52.52.191.128/26;
87+
88+
set_real_ip_from 204.246.174.0/23;
89+
90+
set_real_ip_from 64.252.128.0/18;
91+
92+
set_real_ip_from 205.251.254.0/24;
93+
94+
set_real_ip_from 143.204.0.0/16;
95+
96+
set_real_ip_from 205.251.252.0/23;
97+
98+
set_real_ip_from 52.78.247.128/26;
99+
100+
set_real_ip_from 204.246.176.0/20;
101+
102+
set_real_ip_from 52.220.191.0/26;
103+
104+
set_real_ip_from 13.249.0.0/16;
105+
106+
set_real_ip_from 54.240.128.0/18;
107+
108+
set_real_ip_from 205.251.250.0/23;
109+
110+
set_real_ip_from 52.222.128.0/17;
111+
112+
set_real_ip_from 54.182.0.0/16;
113+
114+
set_real_ip_from 54.192.0.0/16;
115+
116+
set_real_ip_from 34.232.163.208/29;
117+
118+
set_real_ip_from 2600:9000:eee::/48;
119+
120+
set_real_ip_from 2600:9000:4000::/36;
121+
122+
set_real_ip_from 2600:9000:3000::/36;
123+
124+
set_real_ip_from 2600:9000:f000::/36;
125+
126+
set_real_ip_from 2600:9000:fff::/48;
127+
128+
set_real_ip_from 2600:9000:2000::/36;
129+
130+
set_real_ip_from 2600:9000:1000::/36;
131+
132+
set_real_ip_from 2600:9000:ddd::/48;
133+
134+
set_real_ip_from 2600:9000:5300::/40;
135+
136+
set_real_ip_from 103.21.244.0/22;
137+
138+
set_real_ip_from 103.22.200.0/22;
139+
140+
set_real_ip_from 103.31.4.0/22;
141+
142+
set_real_ip_from 104.16.0.0/12;
143+
144+
set_real_ip_from 108.162.192.0/18;
145+
146+
set_real_ip_from 131.0.72.0/22;
147+
148+
set_real_ip_from 141.101.64.0/18;
149+
150+
set_real_ip_from 162.158.0.0/15;
151+
152+
set_real_ip_from 172.64.0.0/13;
153+
154+
set_real_ip_from 173.245.48.0/20;
155+
156+
set_real_ip_from 188.114.96.0/20;
157+
158+
set_real_ip_from 190.93.240.0/20;
159+
160+
set_real_ip_from 197.234.240.0/22;
161+
162+
set_real_ip_from 198.41.128.0/17;
163+
164+
set_real_ip_from 2400:cb00::/32;
165+
166+
set_real_ip_from 2405:b500::/32;
167+
168+
set_real_ip_from 2606:4700::/32;
169+
170+
set_real_ip_from 2803:f800::/32;
171+
172+
set_real_ip_from 2c0f:f248::/32;
173+
174+
set_real_ip_from 2a06:98c0::/29;

src/backend/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,19 @@ function appStart () {
1111
const app = require('./app');
1212
const apiValidator = require('./lib/validator/api');
1313
const internalCertificate = require('./internal/certificate');
14+
const internalIpRanges = require('./internal/ip_ranges');
1415

1516
return migrate.latest()
1617
.then(setup)
1718
.then(importer)
1819
.then(() => {
1920
return apiValidator.loadSchemas;
2021
})
22+
.then(internalIpRanges.fetch)
2123
.then(() => {
2224

2325
internalCertificate.initTimer();
26+
internalIpRanges.initTimer();
2427

2528
const server = app.listen(81, () => {
2629
logger.info('PID ' + process.pid + ' listening on port 81 ...');

src/backend/internal/ip_ranges.js

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
'use strict';
2+
3+
const https = require('https');
4+
const fs = require('fs');
5+
const _ = require('lodash');
6+
const logger = require('../logger').ip_ranges;
7+
const debug_mode = process.env.NODE_ENV !== 'production';
8+
const error = require('../lib/error');
9+
const internalNginx = require('./nginx');
10+
const Liquid = require('liquidjs');
11+
12+
const CLOUDFRONT_URL = 'https://ip-ranges.amazonaws.com/ip-ranges.json';
13+
const CLOUDFARE_V4_URL = 'https://www.cloudflare.com/ips-v4';
14+
const CLOUDFARE_V6_URL = 'https://www.cloudflare.com/ips-v6';
15+
16+
const internalIpRanges = {
17+
18+
interval_timeout: 1000 * 60 * 60 * 6, // 6 hours
19+
interval: null,
20+
interval_processing: false,
21+
iteration_count: 0,
22+
23+
initTimer: () => {
24+
logger.info('IP Ranges Renewal Timer initialized');
25+
internalIpRanges.interval = setInterval(internalIpRanges.fetch, internalIpRanges.interval_timeout);
26+
},
27+
28+
fetchUrl: url => {
29+
return new Promise((resolve, reject) => {
30+
logger.info('Fetching ' + url);
31+
return https.get(url, res => {
32+
res.setEncoding('utf8');
33+
let raw_data = '';
34+
res.on('data', chunk => {
35+
raw_data += chunk;
36+
});
37+
38+
res.on('end', () => {
39+
resolve(raw_data);
40+
});
41+
}).on('error', err => {
42+
reject(err);
43+
});
44+
});
45+
},
46+
47+
/**
48+
* Triggered at startup and then later by a timer, this will fetch the ip ranges from services and apply them to nginx.
49+
*/
50+
fetch: () => {
51+
if (!internalIpRanges.interval_processing) {
52+
internalIpRanges.interval_processing = true;
53+
logger.info('Fetching IP Ranges from online services...');
54+
55+
let ip_ranges = [];
56+
57+
return internalIpRanges.fetchUrl(CLOUDFRONT_URL)
58+
.then(cloudfront_data => {
59+
let data = JSON.parse(cloudfront_data);
60+
61+
if (data && typeof data.prefixes !== 'undefined') {
62+
data.prefixes.map(item => {
63+
if (item.service === 'CLOUDFRONT') {
64+
ip_ranges.push(item.ip_prefix);
65+
}
66+
});
67+
}
68+
69+
if (data && typeof data.ipv6_prefixes !== 'undefined') {
70+
data.ipv6_prefixes.map(item => {
71+
if (item.service === 'CLOUDFRONT') {
72+
ip_ranges.push(item.ipv6_prefix);
73+
}
74+
});
75+
}
76+
})
77+
.then(() => {
78+
return internalIpRanges.fetchUrl(CLOUDFARE_V4_URL);
79+
})
80+
.then(cloudfare_data => {
81+
let items = cloudfare_data.split('\n');
82+
ip_ranges = [... ip_ranges, ... items];
83+
})
84+
.then(() => {
85+
return internalIpRanges.fetchUrl(CLOUDFARE_V6_URL);
86+
})
87+
.then(cloudfare_data => {
88+
let items = cloudfare_data.split('\n');
89+
ip_ranges = [... ip_ranges, ... items];
90+
})
91+
.then(() => {
92+
let clean_ip_ranges = [];
93+
ip_ranges.map(range => {
94+
if (range) {
95+
clean_ip_ranges.push(range);
96+
}
97+
});
98+
99+
return internalIpRanges.generateConfig(clean_ip_ranges)
100+
.then(() => {
101+
if (internalIpRanges.iteration_count) {
102+
// Reload nginx
103+
return internalNginx.reload();
104+
}
105+
});
106+
})
107+
.then(() => {
108+
internalIpRanges.interval_processing = false;
109+
internalIpRanges.iteration_count++;
110+
})
111+
.catch(err => {
112+
logger.error(err.message);
113+
internalIpRanges.interval_processing = false;
114+
});
115+
}
116+
},
117+
118+
/**
119+
* @param {Array} ip_ranges
120+
* @returns {Promise}
121+
*/
122+
generateConfig: (ip_ranges) => {
123+
if (debug_mode) {
124+
logger.info('Generating IP Ranges Config', ip_ranges);
125+
}
126+
127+
let renderEngine = Liquid({
128+
root: __dirname + '/../templates/'
129+
});
130+
131+
return new Promise((resolve, reject) => {
132+
let template = null;
133+
let filename = '/etc/nginx/conf.d/include/ip_ranges.conf';
134+
try {
135+
template = fs.readFileSync(__dirname + '/../templates/ip_ranges.conf', {encoding: 'utf8'});
136+
} catch (err) {
137+
reject(new error.ConfigurationError(err.message));
138+
return;
139+
}
140+
141+
renderEngine
142+
.parseAndRender(template, {ip_ranges: ip_ranges})
143+
.then(config_text => {
144+
fs.writeFileSync(filename, config_text, {encoding: 'utf8'});
145+
146+
if (debug_mode) {
147+
logger.debug('Wrote config:', filename, config_text);
148+
}
149+
150+
resolve(true);
151+
})
152+
.catch(err => {
153+
if (debug_mode) {
154+
logger.warn('Could not write ' + filename + ':', err.message);
155+
}
156+
157+
reject(new error.ConfigurationError(err.message));
158+
});
159+
});
160+
}
161+
};
162+
163+
module.exports = internalIpRanges;

src/backend/logger.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const {Signale} = require('signale');
22

33
module.exports = {
4-
global: new Signale({scope: 'Global '}),
5-
migrate: new Signale({scope: 'Migrate '}),
6-
express: new Signale({scope: 'Express '}),
7-
access: new Signale({scope: 'Access '}),
8-
nginx: new Signale({scope: 'Nginx '}),
9-
ssl: new Signale({scope: 'SSL '}),
10-
import: new Signale({scope: 'Importer'}),
11-
setup: new Signale({scope: 'Setup '})
4+
global: new Signale({scope: 'Global '}),
5+
migrate: new Signale({scope: 'Migrate '}),
6+
express: new Signale({scope: 'Express '}),
7+
access: new Signale({scope: 'Access '}),
8+
nginx: new Signale({scope: 'Nginx '}),
9+
ssl: new Signale({scope: 'SSL '}),
10+
import: new Signale({scope: 'Importer '}),
11+
setup: new Signale({scope: 'Setup '}),
12+
ip_ranges: new Signale({scope: 'IP Ranges'})
1213
};

src/backend/templates/ip_ranges.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% for range in ip_ranges %}
2+
set_real_ip_from {{ range }};
3+
{% endfor %}

0 commit comments

Comments
 (0)