@hyperwatch/hyperwatch 3.9.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ Hyperwatch is built on a real-time stream processor handling logs from inputs of
12
12
 
13
13
  ## Install
14
14
 
15
- Make sure you have Node.js version >= 11.14.
15
+ Make sure you have Node.js version >= 14.
16
16
 
17
17
  We recommend using [nvm](https://github.com/creationix/nvm): `nvm install && nvm use`.
18
18
 
package/docs/input.md CHANGED
@@ -152,10 +152,10 @@ Hyperwatch is distributed with two Nginx formats.
152
152
  - The default `combined` format:
153
153
  `'$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent"'`
154
154
 
155
- - the `access_watch_combined` format that extracts important HTTP headers from the request:
155
+ - the `hyperwatch_combined` format that extracts important HTTP headers from the request:
156
156
  `'$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host"'`.
157
157
 
158
- If possible, we recommend you to use the `access_watch_combined` format to take full advantage of the Hyperwatch data augmentation in the pipeline.
158
+ If possible, we recommend you to use the `hyperwatch_combined` format to take full advantage of the Hyperwatch data augmentation in the pipeline.
159
159
 
160
160
  ### Apache
161
161
 
@@ -176,10 +176,10 @@ Hyperwatch is distributed with two Apache formats.
176
176
  - The default `combined` format:
177
177
  `'%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"'`
178
178
 
179
- - the `access_watch_combined` format that extracts important HTTP headers from the request:
179
+ - the `hyperwatch_combined` format that extracts important HTTP headers from the request:
180
180
  `'%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" "%{Accept}i" "%{Accept-Charset}i" "%{Accept-Encoding}i" "%{Accept-Language}i" "%{Connection}i" "%{Dnt}i" "%{From}i" "%{Host}i"'`.
181
181
 
182
- If possible, we recommend you to use the `access_watch_combined` format to take full advantage of the Hyperwatch data augmentation in the pipeline.
182
+ If possible, we recommend you to use the `hyperwatch_combined` format to take full advantage of the Hyperwatch data augmentation in the pipeline.
183
183
 
184
184
  ### Custom
185
185
 
@@ -225,8 +225,8 @@ npm start config/custom
225
225
  For more detailed log processing, it is recommended to use the _Hyperwatch combined_ log format:
226
226
 
227
227
  ```
228
- log_format access_watch_combined '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host" "$http_x_forwarded_for"'
229
- access_log /logs/access.log access_watch_combined;
228
+ log_format hyperwatch_combined '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host"'
229
+ access_log /logs/access.log hyperwatch_combined;
230
230
  ```
231
231
 
232
232
  With the following configuration for Hyperwatch:
@@ -234,7 +234,7 @@ With the following configuration for Hyperwatch:
234
234
  ```
235
235
  const defaultInput = input.file.create({
236
236
  path: '/logs/access.log',
237
- parse: format.nginx.parser({format: format.nginx.formats.accessWatchCombined})
237
+ parse: format.nginx.parser({format: format.nginx.formats.hyperwatch_combined})
238
238
  })
239
239
  ```
240
240
 
@@ -243,8 +243,8 @@ const defaultInput = input.file.create({
243
243
  If behind a proxy, you might want to also report the `HTTP_X_FORWARDED_FOR` header to allow Hyperwatch to properly detect the client IP address.
244
244
 
245
245
  ```
246
- log_format access_watch_combined_with_x_forwarded_for '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host" "$http_x_forwarded_for"'
247
- access_log /logs/access.log access_watch_combined_with_x_forwarded_for;
246
+ log_format hyperwatch_combined_with_x_forwarded_for '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host" "$http_x_forwarded_for"'
247
+ access_log /logs/access.log hyperwatch_combined_with_x_forwarded_for;
248
248
  ```
249
249
 
250
250
  With the following configuration for Hyperwatch:
@@ -51,7 +51,7 @@ module.exports = function (hyperwatch) {
51
51
  const syslogApacheHyperwatchCombinedInput = input.syslog.create({
52
52
  port: 1518,
53
53
  parse: format.apache.parser({
54
- format: format.apache.formats.hyperwatchCombined,
54
+ format: format.apache.formats.hyperwatch_combined,
55
55
  }),
56
56
  });
57
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperwatch/hyperwatch",
3
- "version": "3.9.3",
3
+ "version": "4.0.0",
4
4
  "description": "Open Source HTTP Traffic Manager",
5
5
  "license": "Apache-2.0",
6
6
  "author": "François Hodierne <francois@hodierne.net>",
@@ -34,14 +34,14 @@
34
34
  "chalk": "^4.1.0",
35
35
  "country-code-emoji": "^2.3.0",
36
36
  "debug": "^4.3.4",
37
- "dnsbl": "^3.2.0",
37
+ "dnsbl": "^4.0.0",
38
38
  "express": "^4.18.2",
39
39
  "express-ws": "^5.0.2",
40
40
  "geoip-lite": "^1.4.6",
41
41
  "immutable": "^4.1.0",
42
42
  "ip-cidr": "^3.0.10",
43
43
  "lodash": "^4.17.21",
44
- "lru-cache": "^6.0.0",
44
+ "lru-cache": "^10.0.1",
45
45
  "micro-strptime": "^0.2.3",
46
46
  "proxy-addr": "^2.0.7",
47
47
  "rc": "^1.2.8",
@@ -58,11 +58,12 @@
58
58
  "husky": "^4.3.5",
59
59
  "lint-staged": "^10.5.3",
60
60
  "mocha": "^10.0.0",
61
- "prettier": "^2.7.1",
61
+ "node-fetch": "^2.0.0",
62
+ "prettier": "^3.0.3",
62
63
  "prettier-package-json": "^2.7.0"
63
64
  },
64
65
  "engines": {
65
- "node": ">=12.0"
66
+ "node": ">=14.0"
66
67
  },
67
68
  "depcheck": {
68
69
  "ignores": [
@@ -0,0 +1,56 @@
1
+ /* eslint-disable-next-line node/no-unpublished-require */
2
+ const fetch = require('node-fetch');
3
+
4
+ async function main() {
5
+ const response = await fetch(
6
+ 'https://ip-ranges.amazonaws.com/ip-ranges.json'
7
+ );
8
+
9
+ const ipRanges = await response.json();
10
+
11
+ console.log(
12
+ ipRanges.prefixes
13
+ .filter((p) => p.service === 'CLOUDFRONT')
14
+ .map((el) => el.ip_prefix)
15
+ .sort((a, b) => {
16
+ const aArray = a.split('.').map(Number);
17
+ const bArray = b.split('.').map(Number);
18
+ if (aArray[0] === bArray[0]) {
19
+ if (aArray[1] === bArray[1]) {
20
+ if (aArray[2] === bArray[2]) {
21
+ return aArray[3] > bArray[3] ? 1 : -1;
22
+ }
23
+ return aArray[2] > bArray[2] ? 1 : -1;
24
+ }
25
+ return aArray[1] > bArray[1] ? 1 : -1;
26
+ }
27
+ return aArray[0] > bArray[0] ? 1 : -1;
28
+ })
29
+ .map((el) => `"${el}"`)
30
+ .join(',\n')
31
+ );
32
+
33
+ console.log(
34
+ ipRanges.ipv6_prefixes
35
+ .filter((p) => p.service === 'CLOUDFRONT')
36
+ .map((el) => el.ipv6_prefix)
37
+ .sort((a, b) => {
38
+ const aArray = a.split(':').map(Number);
39
+ const bArray = b.split(':').map(Number);
40
+ if (aArray[0] === bArray[0]) {
41
+ if (aArray[1] === bArray[1]) {
42
+ if (aArray[2] === bArray[2]) {
43
+ return aArray[3] > bArray[3] ? 1 : -1;
44
+ }
45
+ return aArray[2] > bArray[2] ? 1 : -1;
46
+ }
47
+ return aArray[1] > bArray[1] ? 1 : -1;
48
+ }
49
+ return aArray[0] > bArray[0] ? 1 : -1;
50
+ })
51
+ .map((el) => `"${el}"`)
52
+ .join(',\n')
53
+ );
54
+ }
55
+
56
+ main();
@@ -94,7 +94,7 @@ function parser({ format }) {
94
94
 
95
95
  const formats = {
96
96
  combined: '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"',
97
- hyperwatchCombined:
97
+ hyperwatch_combined:
98
98
  '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" "%{Accept}i" "%{Accept-Charset}i" "%{Accept-Encoding}i" "%{Accept-Language}i" "%{Connection}i" "%{Dnt}i" "%{From}i" "%{Host}i"',
99
99
  };
100
100
 
@@ -95,9 +95,7 @@ function parser({ format = formats.combined } = {}) {
95
95
  const formats = {
96
96
  combined:
97
97
  '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent"',
98
- accessWatch:
99
- '"$time_iso8601" "$remote_addr" "$http_host" "$request" $status "$http_user_agent" "$http_accept" "$http_accept_language" "$http_accept_charset" "$http_accept_encoding" "$http_from" "$http_dnt" "$http_connection" "$http_referer"',
100
- hyperwatchCombined:
98
+ hyperwatch_combined:
101
99
  '$remote_addr - $remote_user [$time_local] "$request" $status $bytes_sent "$http_referer" "$http_user_agent" "$http_accept" "$http_accept_charset" "$http_accept_encoding" "$http_accept_language" "$http_connection" "$http_dnt" "$http_from" "$http_host"',
102
100
  };
103
101
 
@@ -0,0 +1,81 @@
1
+ const crypto = require('crypto');
2
+
3
+ const { fromJS } = require('immutable');
4
+
5
+ const app = require('../app/api');
6
+
7
+ /**
8
+ * Create a log from Vercel JSON log drain format
9
+ */
10
+ function parseVercel(request) {
11
+ return fromJS({
12
+ request: {
13
+ time: new Date(request.proxy.timestamp).toISOString(),
14
+ address: request.proxy.clientIp,
15
+ scheme: request.proxy.scheme,
16
+ method: request.proxy.method,
17
+ url: request.proxy.path,
18
+ headers: {
19
+ host: request.proxy.host,
20
+ 'user-agent': request.proxy.userAgent[0],
21
+ },
22
+ captured_headers: ['host', 'user-agent'],
23
+ },
24
+ response: {
25
+ status: request.proxy.statusCode,
26
+ },
27
+ });
28
+ }
29
+
30
+ function verifySignature(req, secret) {
31
+ if (!req.headers['x-vercel-signature'] || !secret) {
32
+ return true;
33
+ }
34
+
35
+ return (
36
+ req.headers['x-vercel-signature'] ===
37
+ crypto.createHmac('sha1', secret).update(req.rawBody).digest('hex')
38
+ );
39
+ }
40
+
41
+ function create({
42
+ name = 'HTTP input (Vercel JSON log drain format)',
43
+ path = '/input/vercel',
44
+ parse = parseVercel,
45
+ verify,
46
+ secret,
47
+ }) {
48
+ return {
49
+ name: name,
50
+ start: ({ success, reject, status }) => {
51
+ app.post(path, (req, res) => {
52
+ // Send back verify header (only needed to setup the drain)
53
+ if (verify) {
54
+ res.set('x-vercel-verify', verify);
55
+ }
56
+ // Verify signature
57
+ if (!verifySignature(req, secret)) {
58
+ res.statusCode = 403;
59
+ res.send("Signature didn't match");
60
+ return;
61
+ }
62
+ // No extra validation before sending the response to the client
63
+ res.send('Ok');
64
+ // Processing the message(s)
65
+ const messages = Array.isArray(req.body) ? req.body : [req.body];
66
+ messages.forEach((message) => {
67
+ try {
68
+ success(parse(message));
69
+ } catch (err) {
70
+ reject(err);
71
+ }
72
+ });
73
+ });
74
+ status(null, `Listening on http://__HOST__${path}`);
75
+ },
76
+ };
77
+ }
78
+
79
+ module.exports = {
80
+ create: create,
81
+ };
package/src/lib/cache.js CHANGED
@@ -1,14 +1,14 @@
1
- const lruCache = require('lru-cache');
1
+ const { LRUCache } = require('lru-cache');
2
2
 
3
3
  const lruProvider = (options) => {
4
- const lruInstance = new lruCache(options);
4
+ const lruInstance = new LRUCache(options);
5
5
  return {
6
- clear: async () => lruInstance.reset(),
7
- del: async (key) => lruInstance.del(key),
6
+ clear: async () => lruInstance.clear(),
7
+ del: async (key) => lruInstance.delete(key),
8
8
  get: async (key) => lruInstance.get(key),
9
9
  has: async (key) => lruInstance.has(key),
10
10
  set: async (key, value, ttlInSeconds) =>
11
- lruInstance.set(key, value, ttlInSeconds ? ttlInSeconds * 1000 : null),
11
+ lruInstance.set(key, value, { ttl: ttlInSeconds * 1000 }),
12
12
  };
13
13
  };
14
14
 
@@ -30,4 +30,12 @@ async function set(key, value, ttlInSeconds) {
30
30
  return cacheProvider.set(key, value, ttlInSeconds);
31
31
  }
32
32
 
33
- module.exports = { has, get, set, setProvider };
33
+ async function del(key) {
34
+ return cacheProvider.del(key);
35
+ }
36
+
37
+ async function clear(key) {
38
+ return cacheProvider.clear(key);
39
+ }
40
+
41
+ module.exports = { has, get, set, del, clear, setProvider };
@@ -186,6 +186,19 @@ function augment(log) {
186
186
  return hostname && hostname.endsWith('.dataforseo.com')
187
187
  ? log.set('identity', 'DataForSeo')
188
188
  : log;
189
+ case 'Qwantify':
190
+ case 'Qwantify-dev':
191
+ return hostname && hostname.endsWith('.qwant.com')
192
+ ? log.set('identity', 'Qwant')
193
+ : log;
194
+ case 'InfoTigerBot':
195
+ return hostname && hostname.endsWith('.infotiger.com')
196
+ ? log.set('identity', 'InfoTiger')
197
+ : log;
198
+ case 'Amazonbot':
199
+ return hostname && hostname.endsWith('.crawl.amazonbot.amazon')
200
+ ? log.set('identity', 'Amazonbot')
201
+ : log;
189
202
 
190
203
  // Per hostname + CIDR
191
204
  case 'Twitterbot':
@@ -253,10 +266,6 @@ function augment(log) {
253
266
  hostname.endsWith('.eu-central-1.compute.amazonaws.com')
254
267
  ? log.set('identity', 'Wise')
255
268
  : log;
256
- case 'Amazonbot':
257
- return hostname && hostname.endsWith('.compute-1.amazonaws.com')
258
- ? log.set('identity', 'Amazonbot')
259
- : log;
260
269
 
261
270
  // GCE
262
271
  case 'VelenPublicWebCrawler':
@@ -3,52 +3,169 @@ const proxyaddr = require('proxy-addr');
3
3
 
4
4
  const ipRanges = {
5
5
  cloudflare: [
6
+ // Source: https://www.cloudflare.com/ips/
7
+ '173.245.48.0/20',
6
8
  '103.21.244.0/22',
7
9
  '103.22.200.0/22',
8
10
  '103.31.4.0/22',
9
- '104.16.0.0/12',
10
- '108.162.192.0/18',
11
- '131.0.72.0/22',
12
11
  '141.101.64.0/18',
13
- '162.158.0.0/15',
14
- '172.64.0.0/13',
15
- '173.245.48.0/20',
16
- '188.114.96.0/20',
12
+ '108.162.192.0/18',
17
13
  '190.93.240.0/20',
14
+ '188.114.96.0/20',
18
15
  '197.234.240.0/22',
19
16
  '198.41.128.0/17',
20
- '199.27.128.0/21',
17
+ '162.158.0.0/15',
18
+ '104.16.0.0/13',
19
+ '104.24.0.0/14',
20
+ '172.64.0.0/13',
21
+ '131.0.72.0/22',
21
22
  '2400:cb00::/32',
22
- '2405:8100::/32',
23
- '2405:b500::/32',
24
23
  '2606:4700::/32',
25
24
  '2803:f800::/32',
25
+ '2405:b500::/32',
26
+ '2405:8100::/32',
27
+ '2a06:98c0::/29',
28
+ '2c0f:f248::/32',
26
29
  ],
27
30
  cloudfront: [
31
+ // Source: scripts/cloudfront-ips.js
32
+ '3.10.17.128/25',
33
+ '3.11.53.0/24',
34
+ '3.35.130.128/25',
35
+ '3.101.158.0/23',
36
+ '3.128.93.0/24',
37
+ '3.134.215.0/24',
38
+ '3.160.0.0/14',
39
+ '3.231.2.0/25',
40
+ '3.234.232.224/27',
41
+ '3.236.48.0/23',
42
+ '3.236.169.192/26',
28
43
  '13.32.0.0/15',
44
+ '13.35.0.0/16',
45
+ '13.48.32.0/24',
29
46
  '13.54.63.128/26',
47
+ '13.59.250.0/26',
48
+ '13.113.196.64/26',
49
+ '13.113.203.0/24',
50
+ '13.124.199.0/24',
51
+ '13.210.67.128/26',
52
+ '13.224.0.0/14',
53
+ '13.228.69.0/24',
54
+ '13.233.177.192/26',
55
+ '13.249.0.0/16',
56
+ '15.158.0.0/16',
57
+ '15.188.184.0/24',
58
+ '15.207.13.128/25',
59
+ '15.207.213.128/25',
60
+ '18.64.0.0/14',
61
+ '18.68.0.0/16',
62
+ '18.154.0.0/15',
63
+ '18.160.0.0/15',
64
+ '18.164.0.0/15',
65
+ '18.172.0.0/15',
66
+ '18.192.142.0/23',
67
+ '18.200.212.0/23',
68
+ '18.216.170.128/25',
69
+ '18.229.220.192/26',
70
+ '18.238.0.0/15',
71
+ '18.244.0.0/15',
30
72
  '34.195.252.0/24',
73
+ '34.216.51.0/25',
74
+ '34.223.12.224/27',
75
+ '34.223.80.192/26',
76
+ '34.226.14.0/24',
77
+ '35.158.136.0/24',
31
78
  '35.162.63.192/26',
32
79
  '35.167.191.128/26',
80
+ '36.103.232.0/25',
81
+ '36.103.232.128/26',
82
+ '44.227.178.0/24',
83
+ '44.234.90.252/30',
84
+ '44.234.108.128/25',
33
85
  '52.15.127.128/26',
34
86
  '52.46.0.0/18',
87
+ '52.47.139.0/24',
35
88
  '52.52.191.128/26',
36
89
  '52.56.127.0/25',
37
90
  '52.57.254.0/24',
38
91
  '52.66.194.128/26',
39
92
  '52.78.247.128/26',
93
+ '52.82.128.0/19',
40
94
  '52.84.0.0/15',
95
+ '52.124.128.0/17',
41
96
  '52.199.127.192/26',
42
97
  '52.212.248.0/26',
43
98
  '52.220.191.0/26',
44
99
  '52.222.128.0/17',
45
100
  '54.182.0.0/16',
46
101
  '54.192.0.0/16',
47
- '54.230.0.0/16',
102
+ '54.230.0.0/17',
103
+ '54.230.128.0/18',
104
+ '54.230.200.0/21',
105
+ '54.230.208.0/20',
106
+ '54.230.224.0/19',
48
107
  '54.233.255.128/26',
49
108
  '54.239.128.0/18',
50
109
  '54.239.192.0/19',
51
110
  '54.240.128.0/18',
111
+ '58.254.138.128/26',
112
+ '58.254.138.0/25',
113
+ '64.252.64.0/18',
114
+ '64.252.128.0/18',
115
+ '65.8.0.0/16',
116
+ '65.9.0.0/17',
117
+ '65.9.128.0/18',
118
+ '70.132.0.0/18',
119
+ '71.152.0.0/17',
120
+ '99.79.169.0/24',
121
+ '99.84.0.0/16',
122
+ '99.86.0.0/16',
123
+ '108.138.0.0/15',
124
+ '108.156.0.0/14',
125
+ '111.13.171.192/26',
126
+ '111.13.171.128/26',
127
+ '111.13.185.64/27',
128
+ '111.13.185.32/27',
129
+ '116.129.226.0/25',
130
+ '116.129.226.128/26',
131
+ '118.193.97.128/25',
132
+ '118.193.97.64/26',
133
+ '119.147.182.128/26',
134
+ '119.147.182.0/25',
135
+ '120.52.12.64/26',
136
+ '120.52.22.96/27',
137
+ '120.52.39.128/27',
138
+ '120.52.153.192/26',
139
+ '120.232.236.128/26',
140
+ '120.232.236.0/25',
141
+ '120.253.240.192/26',
142
+ '120.253.241.160/27',
143
+ '120.253.245.192/27',
144
+ '120.253.245.128/26',
145
+ '130.176.0.0/17',
146
+ '130.176.128.0/18',
147
+ '130.176.192.0/19',
148
+ '130.176.224.0/20',
149
+ '143.204.0.0/16',
150
+ '144.220.0.0/16',
151
+ '180.163.57.0/25',
152
+ '180.163.57.128/26',
153
+ '204.246.164.0/22',
154
+ '204.246.168.0/22',
155
+ '204.246.172.0/24',
156
+ '204.246.173.0/24',
157
+ '204.246.174.0/23',
158
+ '204.246.176.0/20',
159
+ '205.251.200.0/21',
160
+ '205.251.208.0/20',
161
+ '205.251.249.0/24',
162
+ '205.251.250.0/23',
163
+ '205.251.252.0/23',
164
+ '205.251.254.0/24',
165
+ '216.137.32.0/19',
166
+ '223.71.11.0/27',
167
+ '223.71.71.96/27',
168
+ '223.71.71.128/25',
52
169
  '204.246.164.0/22',
53
170
  '204.246.168.0/22',
54
171
  '204.246.174.0/23',
@@ -59,9 +176,43 @@ const ipRanges = {
59
176
  '205.251.252.0/23',
60
177
  '205.251.254.0/24',
61
178
  '216.137.32.0/19',
179
+ '2400:7fc0:500::/40',
180
+ '2404:c2c0:500::/40',
181
+ '2409:8c00:2421:400::/56',
182
+ '2409:8c00:2421:300::/56',
183
+ '2600:9000:eee::/48',
184
+ '2600:9000:f580::/41',
185
+ '2600:9000:5310::/44',
186
+ '2600:9000:f520::/44',
187
+ '2600:9000:f534::/46',
188
+ '2600:9000:5308::/45',
189
+ '2600:9000:fff::/48',
190
+ '2600:9000:1000::/36',
191
+ '2600:9000:2000::/36',
192
+ '2600:9000:4000::/36',
193
+ '2600:9000:5320::/43',
194
+ '2600:9000:5340::/42',
195
+ '2600:9000:5380::/41',
196
+ '2600:9000:f538::/45',
197
+ '2600:9000:f400::/40',
198
+ '2600:9000:f800::/37',
199
+ '2600:9000:ddd::/48',
200
+ '2600:9000:f500::/43',
201
+ '2600:9000:f000::/38',
202
+ '2600:9000:f540::/42',
203
+ '2600:9000:f600::/39',
204
+ '2600:9000:3000::/36',
205
+ ],
206
+ sucuri: [
207
+ // Source: https://docs.sucuri.net/website-firewall/sucuri-firewall-troubleshooting-guide/
208
+ '192.88.134.0/23',
209
+ '185.93.228.0/22',
210
+ '66.248.200.0/22',
211
+ '2a02:fe80::/29',
212
+ '208.109.0.0/22',
62
213
  ],
63
- cloudproxy: ['192.88.134.0/23', '185.93.228.0/22', '66.248.200.0/22'],
64
- incapsula: [
214
+ imperva: [
215
+ // Source: https://docs.imperva.com/howto/c85245b7
65
216
  '199.83.128.0/21',
66
217
  '198.143.32.0/19',
67
218
  '149.126.72.0/21',