pixl-server-web 1.3.12 → 1.3.13
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 +14 -0
- package/package.json +1 -1
- package/test/test.js +65 -0
- package/web_server.js +12 -3
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
50
50
|
* [http_req_max_dump_enabled](#http_req_max_dump_enabled)
|
|
51
51
|
* [http_req_max_dump_dir](#http_req_max_dump_dir)
|
|
52
52
|
* [http_req_max_dump_debounce](#http_req_max_dump_debounce)
|
|
53
|
+
* [http_public_ip_offset](#http_public_ip_offset)
|
|
53
54
|
* [https](#https)
|
|
54
55
|
* [https_port](#https_port)
|
|
55
56
|
* [https_cert_file](#https_cert_file)
|
|
@@ -529,6 +530,19 @@ When the [Request Max Dump](#request-max-dump) system is enabled, the `http_req_
|
|
|
529
530
|
|
|
530
531
|
When the [Request Max Dump](#request-max-dump) system is enabled, the `http_req_max_dump_debounce` property sets how many seconds should elapse between dumps, as to not overwhelm the filesystem.
|
|
531
532
|
|
|
533
|
+
## http_public_ip_offset
|
|
534
|
+
|
|
535
|
+
This controls how [args.ip](#argsip) is chosen from the list of IP addresses in [args.ips](#argsips) for each incoming request. By default, the client IP is chosen by scanning the list from left to right, and selecting the first non-private IP. However, [modern wisdom](https://adam-p.ca/blog/2022/03/x-forwarded-for/) suggests that alternate selection logic may be more desirable to find the true public IP.
|
|
536
|
+
|
|
537
|
+
By setting `http_public_ip_offset` to an integer value, you can select *exactly* which IP to select from the list. Use negative numbers to select IP address from the *end* (right side) of the list. Here are the recommended values:
|
|
538
|
+
|
|
539
|
+
| Offset | Description |
|
|
540
|
+
|--------|-------------|
|
|
541
|
+
| `0` | The default value. Allow the server to select the public IP automatically. |
|
|
542
|
+
| `-1` | Always select the *last* IP in the list (i.e. the TCP socket IP). Use this mode if your server is connected to the internet directly. |
|
|
543
|
+
| `-2` | Always select the *second-to-last* IP in the list. Use this mode if you have a single proxy device in front of your server (e.g. a load balancer). |
|
|
544
|
+
| `-3` | Always select the *third-to-last* IP in the list. Use this mode if you have two proxy devices in front of your server (e.g. a load balancer and CDN / cache). |
|
|
545
|
+
|
|
532
546
|
## https
|
|
533
547
|
|
|
534
548
|
This boolean allows you to enable HTTPS (SSL) support in the web server. It defaults to `false`. Note that you must also set `https_port`, and possibly `https_cert_file` and `https_key_file` for this to work.
|
package/package.json
CHANGED
package/test/test.js
CHANGED
|
@@ -1339,6 +1339,71 @@ module.exports = {
|
|
|
1339
1339
|
);
|
|
1340
1340
|
},
|
|
1341
1341
|
|
|
1342
|
+
// http_public_ip_offset
|
|
1343
|
+
function testForwardedForOffsetNeg1(test) {
|
|
1344
|
+
var self = this;
|
|
1345
|
+
var web = this.web_server;
|
|
1346
|
+
web.config.set('http_public_ip_offset', -1);
|
|
1347
|
+
|
|
1348
|
+
request.json( 'http://127.0.0.1:3020/json', false,
|
|
1349
|
+
{
|
|
1350
|
+
headers: {
|
|
1351
|
+
"X-Forwarded-For": "1.2.3.4, 2.3.4.5, 3.4.5.6"
|
|
1352
|
+
}
|
|
1353
|
+
},
|
|
1354
|
+
function(err, resp, data, perf) {
|
|
1355
|
+
test.ok( !err, "No error from PixlRequest: " + err );
|
|
1356
|
+
test.ok( !!resp, "Got resp from PixlRequest" );
|
|
1357
|
+
test.ok( resp.statusCode == 200, "Got 200 response: " + resp.statusCode );
|
|
1358
|
+
test.ok( data.ip === "127.0.0.1", "Correct offset public IP in response: " + data.ip );
|
|
1359
|
+
web.config.set('http_public_ip_offset', 0); // reset
|
|
1360
|
+
test.done();
|
|
1361
|
+
}
|
|
1362
|
+
);
|
|
1363
|
+
},
|
|
1364
|
+
function testForwardedForOffsetNeg2(test) {
|
|
1365
|
+
var self = this;
|
|
1366
|
+
var web = this.web_server;
|
|
1367
|
+
web.config.set('http_public_ip_offset', -2);
|
|
1368
|
+
|
|
1369
|
+
request.json( 'http://127.0.0.1:3020/json', false,
|
|
1370
|
+
{
|
|
1371
|
+
headers: {
|
|
1372
|
+
"X-Forwarded-For": "1.2.3.4, 2.3.4.5, 3.4.5.6"
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
function(err, resp, data, perf) {
|
|
1376
|
+
test.ok( !err, "No error from PixlRequest: " + err );
|
|
1377
|
+
test.ok( !!resp, "Got resp from PixlRequest" );
|
|
1378
|
+
test.ok( resp.statusCode == 200, "Got 200 response: " + resp.statusCode );
|
|
1379
|
+
test.ok( data.ip === "3.4.5.6", "Correct offset public IP in response: " + data.ip );
|
|
1380
|
+
web.config.set('http_public_ip_offset', 0); // reset
|
|
1381
|
+
test.done();
|
|
1382
|
+
}
|
|
1383
|
+
);
|
|
1384
|
+
},
|
|
1385
|
+
function testForwardedForOffsetNeg3(test) {
|
|
1386
|
+
var self = this;
|
|
1387
|
+
var web = this.web_server;
|
|
1388
|
+
web.config.set('http_public_ip_offset', -3);
|
|
1389
|
+
|
|
1390
|
+
request.json( 'http://127.0.0.1:3020/json', false,
|
|
1391
|
+
{
|
|
1392
|
+
headers: {
|
|
1393
|
+
"X-Forwarded-For": "1.2.3.4, 2.3.4.5, 3.4.5.6"
|
|
1394
|
+
}
|
|
1395
|
+
},
|
|
1396
|
+
function(err, resp, data, perf) {
|
|
1397
|
+
test.ok( !err, "No error from PixlRequest: " + err );
|
|
1398
|
+
test.ok( !!resp, "Got resp from PixlRequest" );
|
|
1399
|
+
test.ok( resp.statusCode == 200, "Got 200 response: " + resp.statusCode );
|
|
1400
|
+
test.ok( data.ip === "2.3.4.5", "Correct offset public IP in response: " + data.ip );
|
|
1401
|
+
web.config.set('http_public_ip_offset', 0); // reset
|
|
1402
|
+
test.done();
|
|
1403
|
+
}
|
|
1404
|
+
);
|
|
1405
|
+
},
|
|
1406
|
+
|
|
1342
1407
|
// acl block
|
|
1343
1408
|
function testACL(test) {
|
|
1344
1409
|
request.get( 'http://127.0.0.1:3020/server-status', // ACL'ed endpoint
|
package/web_server.js
CHANGED
|
@@ -366,13 +366,22 @@ class WebServer extends Component {
|
|
|
366
366
|
|
|
367
367
|
getPublicIP(ips) {
|
|
368
368
|
// filter out garbage that doesn't resemble ips
|
|
369
|
+
var public_ip_offset = this.config.get('http_public_ip_offset') || 0;
|
|
370
|
+
|
|
369
371
|
var real_ips = ips.filter( function(ip) {
|
|
370
372
|
return ip.match( /^([\d\.]+|[a-f0-9:]+)$/ );
|
|
371
373
|
} );
|
|
372
374
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
375
|
+
if (public_ip_offset) {
|
|
376
|
+
// locate public IP using custom offset (usually negative, from end of list)
|
|
377
|
+
var temp = real_ips.slice( public_ip_offset, public_ip_offset + 1 || real_ips.length );
|
|
378
|
+
if (temp[0]) return temp[0];
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
// determine first public IP from list of IPs
|
|
382
|
+
for (var idx = 0, len = real_ips.length; idx < len; idx++) {
|
|
383
|
+
if (!this.aclPrivateRanges.check(real_ips[idx])) return real_ips[idx];
|
|
384
|
+
}
|
|
376
385
|
}
|
|
377
386
|
|
|
378
387
|
// default to first ip
|