@abtnode/router-provider 1.16.45-beta-20250620-082630-c0c76051 → 1.16.45-beta-20250625-064956-91b0fb8f
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/lib/nginx/includes/whitelist +0 -0
- package/lib/nginx/index.js +117 -15
- package/lib/nginx/util.js +4 -0
- package/package.json +7 -7
|
File without changes
|
package/lib/nginx/index.js
CHANGED
|
@@ -224,6 +224,9 @@ class NginxProvider extends BaseProvider {
|
|
|
224
224
|
} else {
|
|
225
225
|
this.updateBlacklist([]);
|
|
226
226
|
}
|
|
227
|
+
|
|
228
|
+
this.updateWhitelist();
|
|
229
|
+
|
|
227
230
|
this.updateProxyPolicy(proxyPolicy);
|
|
228
231
|
|
|
229
232
|
const allRules = sites.reduce((acc, site) => {
|
|
@@ -283,15 +286,20 @@ class NginxProvider extends BaseProvider {
|
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
if (!enableIpServer) {
|
|
286
|
-
this.
|
|
289
|
+
this._addIpBlackHoleServer(conf);
|
|
287
290
|
logger.info('add ip blackhole server success');
|
|
288
291
|
}
|
|
289
292
|
|
|
293
|
+
if (process.env.ABT_NODE_DOMAIN_BLACKLIST) {
|
|
294
|
+
this._addUnknownHostBlackHoleServer(conf, process.env.ABT_NODE_DOMAIN_BLACKLIST);
|
|
295
|
+
logger.info('add unknown host blacklist server success');
|
|
296
|
+
}
|
|
297
|
+
|
|
290
298
|
if (enableDefaultServer) {
|
|
291
299
|
this._addDefaultServer(conf, nodeInfo.port);
|
|
292
300
|
logger.info('enable default server success');
|
|
293
301
|
} else {
|
|
294
|
-
this.
|
|
302
|
+
this._addDefaultBlackHoleServer(conf);
|
|
295
303
|
logger.info('add default blackhole server success');
|
|
296
304
|
}
|
|
297
305
|
|
|
@@ -717,7 +725,7 @@ class NginxProvider extends BaseProvider {
|
|
|
717
725
|
location._addVerbatimBlock('if ($query_string)', 'set $abt_query_string "?$query_string";');
|
|
718
726
|
}
|
|
719
727
|
|
|
720
|
-
_addDefaultLocations(server, daemonPort) {
|
|
728
|
+
_addDefaultLocations({ server, daemonPort, serverName }) {
|
|
721
729
|
if (!server) {
|
|
722
730
|
throw new Error('server is required');
|
|
723
731
|
}
|
|
@@ -729,6 +737,8 @@ class NginxProvider extends BaseProvider {
|
|
|
729
737
|
server._add('root', this.getRelativeConfigDir(this.wwwDir));
|
|
730
738
|
server._addVerbatimBlock('if ($access_blocked)', 'return 403;');
|
|
731
739
|
|
|
740
|
+
this._addHostBlockWhitelistServer({ server, serverName });
|
|
741
|
+
|
|
732
742
|
server._add('error_page', '404 =404 /_abtnode_404');
|
|
733
743
|
server._add('error_page', '502 =502 /_abtnode_502');
|
|
734
744
|
server._add('error_page', '500 502 503 504 =500 /_abtnode_5xx');
|
|
@@ -814,20 +824,50 @@ class NginxProvider extends BaseProvider {
|
|
|
814
824
|
});
|
|
815
825
|
}
|
|
816
826
|
|
|
827
|
+
_addUnknownHostBlackHoleServer(conf, blacklist) {
|
|
828
|
+
let blacklistDomains = blacklist.split(',');
|
|
829
|
+
if (blacklistDomains.length === 0) {
|
|
830
|
+
logger.info('unknown host blacklist is empty');
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
blacklistDomains = blacklistDomains.filter((domain) => domain.trim() !== '').join(' ');
|
|
835
|
+
|
|
836
|
+
conf.nginx.http._add('server');
|
|
837
|
+
const server = this._getLastServer(conf);
|
|
838
|
+
server._add('server_name', blacklistDomains);
|
|
839
|
+
server._add('listen', `${decideHttpPort()}`);
|
|
840
|
+
|
|
841
|
+
const certPath = `${joinNginxPath(this.certDir, 'abtnode_dummy.crt')}`;
|
|
842
|
+
const keyPath = `${joinNginxPath(this.certDir, 'abtnode_dummy.key')}`;
|
|
843
|
+
|
|
844
|
+
if (fs.existsSync(certPath) && fs.existsSync(keyPath)) {
|
|
845
|
+
server._add('ssl_certificate', certPath);
|
|
846
|
+
server._add('ssl_certificate_key', keyPath);
|
|
847
|
+
server._add('listen', `${decideHttpsPort()} ssl`);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
server._add('return', '444');
|
|
851
|
+
|
|
852
|
+
logger.info('add unknown host blacklist server success');
|
|
853
|
+
}
|
|
854
|
+
|
|
817
855
|
_addDefaultServer(conf, daemonPort) {
|
|
818
856
|
conf.nginx.http._add('server');
|
|
819
857
|
const server = this._getLastServer(conf);
|
|
820
|
-
|
|
858
|
+
const serverName = '_';
|
|
859
|
+
|
|
860
|
+
server._add('server_name', serverName);
|
|
821
861
|
server._add('listen', `${decideHttpPort()} default_server`);
|
|
822
862
|
|
|
823
|
-
this._addDefaultLocations(server, daemonPort);
|
|
863
|
+
this._addDefaultLocations({ server, daemonPort, serverName });
|
|
824
864
|
server._add('location', '/');
|
|
825
865
|
const location = server.location[server.location.length - 1];
|
|
826
866
|
location._add('try_files', '$uri /404.html break');
|
|
827
867
|
location._add('add_header', 'X-Request-ID $request_id');
|
|
828
868
|
}
|
|
829
869
|
|
|
830
|
-
|
|
870
|
+
_addDefaultBlackHoleServer(conf) {
|
|
831
871
|
conf.nginx.http._add('server');
|
|
832
872
|
const server = this._getLastServer(conf);
|
|
833
873
|
server._add('server_name', '_');
|
|
@@ -845,7 +885,7 @@ class NginxProvider extends BaseProvider {
|
|
|
845
885
|
server._add('return', '444');
|
|
846
886
|
}
|
|
847
887
|
|
|
848
|
-
|
|
888
|
+
_addIpBlackHoleServer(conf) {
|
|
849
889
|
conf.nginx.http._add('server');
|
|
850
890
|
const server = this._getLastServer(conf);
|
|
851
891
|
server._add('server_name', DOMAIN_FOR_IP_SITE_REGEXP);
|
|
@@ -860,7 +900,12 @@ class NginxProvider extends BaseProvider {
|
|
|
860
900
|
server._add('listen', `${decideHttpsPort()} ssl`);
|
|
861
901
|
}
|
|
862
902
|
|
|
863
|
-
|
|
903
|
+
if (process.env.ABT_NODE_IP_WHITELIST) {
|
|
904
|
+
server._addVerbatimBlock('if ($access_trusted = 0)', 'return 444;');
|
|
905
|
+
server._add('return', '200');
|
|
906
|
+
} else {
|
|
907
|
+
server._add('return', '444');
|
|
908
|
+
}
|
|
864
909
|
}
|
|
865
910
|
|
|
866
911
|
_addStubStatusLocation(conf) {
|
|
@@ -922,7 +967,7 @@ class NginxProvider extends BaseProvider {
|
|
|
922
967
|
blockletDid,
|
|
923
968
|
}) {
|
|
924
969
|
const httpServerUnit = this._addHttpServerUnit({ conf, serverName, port });
|
|
925
|
-
this._addDefaultLocations(httpServerUnit, daemonPort);
|
|
970
|
+
this._addDefaultLocations({ server: httpServerUnit, daemonPort, serverName });
|
|
926
971
|
// eslint-disable-next-line max-len
|
|
927
972
|
locations.forEach((x) => this._addReverseProxy({ server: httpServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid })); // prettier-ignore
|
|
928
973
|
}
|
|
@@ -942,7 +987,7 @@ class NginxProvider extends BaseProvider {
|
|
|
942
987
|
const httpServerUnit = this._addHttpServerUnit({ conf, serverName });
|
|
943
988
|
httpServerUnit._add('return', '307 https://$host$request_uri'); // redirect to https if has https
|
|
944
989
|
|
|
945
|
-
this._addDefaultLocations(httpsServerUnit, daemonPort);
|
|
990
|
+
this._addDefaultLocations({ server: httpsServerUnit, daemonPort, serverName });
|
|
946
991
|
// eslint-disable-next-line max-len
|
|
947
992
|
locations.forEach((x) => this._addReverseProxy({ server: httpsServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid })); // prettier-ignore
|
|
948
993
|
}
|
|
@@ -958,6 +1003,48 @@ class NginxProvider extends BaseProvider {
|
|
|
958
1003
|
return httpServerUnit;
|
|
959
1004
|
}
|
|
960
1005
|
|
|
1006
|
+
_addHostBlockWhitelistServer({ server, serverName }) {
|
|
1007
|
+
if (
|
|
1008
|
+
process.env.ABT_NODE_DOMAIN_WHITELIST &&
|
|
1009
|
+
toLower(process.env.ABT_NODE_DOMAIN_WHITELIST).includes(toLower(serverName)) &&
|
|
1010
|
+
process.env.ABT_NODE_DOMAIN_WHITELIST_HEADERS
|
|
1011
|
+
) {
|
|
1012
|
+
let whitelistHeaders = [];
|
|
1013
|
+
try {
|
|
1014
|
+
whitelistHeaders = JSON.parse(process.env.ABT_NODE_DOMAIN_WHITELIST_HEADERS);
|
|
1015
|
+
if (whitelistHeaders && !Array.isArray(whitelistHeaders) && typeof whitelistHeaders === 'object') {
|
|
1016
|
+
whitelistHeaders = [whitelistHeaders];
|
|
1017
|
+
}
|
|
1018
|
+
} catch (e) {
|
|
1019
|
+
logger.warn('invalid ABT_NODE_DOMAIN_WHITELIST_HEADERS env, should be JSON array', {
|
|
1020
|
+
error: e,
|
|
1021
|
+
env: process.env.ABT_NODE_DOMAIN_WHITELIST_HEADERS,
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (!Array.isArray(whitelistHeaders) || whitelistHeaders.length === 0) {
|
|
1028
|
+
logger.warn('ABT_NODE_DOMAIN_WHITELIST_HEADERS env is empty');
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
for (let i = 0; i < whitelistHeaders.length; i++) {
|
|
1033
|
+
const h = whitelistHeaders[i];
|
|
1034
|
+
if (!h.name || typeof h.value === 'undefined') {
|
|
1035
|
+
// skip invalid header config
|
|
1036
|
+
logger.warn('invalid header config', { header: h });
|
|
1037
|
+
} else {
|
|
1038
|
+
server._addVerbatimBlock(
|
|
1039
|
+
`if ($http_${h.name.toLowerCase().replace(/-/g, '_')} != ${h.value})`,
|
|
1040
|
+
'return 444;'
|
|
1041
|
+
);
|
|
1042
|
+
logger.info('add host block whitelist server with multi-header success', { header: h });
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
961
1048
|
_addHttpsServerUnit({ conf, serverName, certificateFileName }) {
|
|
962
1049
|
// assignment the `server`segment just created to httpServerUnit
|
|
963
1050
|
conf.nginx.http._add('server');
|
|
@@ -1004,12 +1091,15 @@ class NginxProvider extends BaseProvider {
|
|
|
1004
1091
|
return;
|
|
1005
1092
|
}
|
|
1006
1093
|
|
|
1094
|
+
const maxBodySize = 1024 * 1024 * 5; // 5MB
|
|
1095
|
+
const minBodySize = 1024 * 1024 * 1; // 1MB
|
|
1096
|
+
|
|
1007
1097
|
const variables = {
|
|
1008
1098
|
...pick(wafPolicy, ['mode', 'inboundAnomalyScoreThreshold', 'outboundAnomalyScoreThreshold', 'logLevel']),
|
|
1009
1099
|
tmpDir: this.tmpDir,
|
|
1010
1100
|
logDir: this.logDir,
|
|
1011
1101
|
maxUploadSize: Math.floor(+CLIENT_MAX_BODY_SIZE * 1024 * 1024),
|
|
1012
|
-
maxBodySize: Math.floor((+CLIENT_MAX_BODY_SIZE * 1024 * 1024) /
|
|
1102
|
+
maxBodySize: Math.max(minBodySize, Math.min(Math.floor((+CLIENT_MAX_BODY_SIZE * 1024 * 1024) / 10), maxBodySize)),
|
|
1013
1103
|
};
|
|
1014
1104
|
|
|
1015
1105
|
logger.info('modsecurity variables', variables);
|
|
@@ -1108,6 +1198,18 @@ class NginxProvider extends BaseProvider {
|
|
|
1108
1198
|
fs.writeFileSync(blacklistFile, blacklist.map((x) => `${x} 1;`).join(os.EOL));
|
|
1109
1199
|
}
|
|
1110
1200
|
|
|
1201
|
+
updateWhitelist() {
|
|
1202
|
+
try {
|
|
1203
|
+
const whitelistFile = path.join(this.includesDir, 'whitelist');
|
|
1204
|
+
let whitelist = process.env.ABT_NODE_IP_WHITELIST?.split(',') || []; // IP 地址列表,支持 CIDR 格式
|
|
1205
|
+
whitelist = whitelist.map((x) => x.trim()).filter(Boolean);
|
|
1206
|
+
|
|
1207
|
+
fs.writeFileSync(whitelistFile, whitelist.map((x) => `${x} 1;`).join(os.EOL));
|
|
1208
|
+
} catch (error) {
|
|
1209
|
+
logger.error('Failed to update whitelist', { error, env: process.env.ABT_NODE_IP_WHITELIST });
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1111
1213
|
updateProxyPolicy(proxyPolicy) {
|
|
1112
1214
|
const proxyRaw = fs.readFileSync(path.join(this.includesDir, 'proxy.raw'), 'utf8');
|
|
1113
1215
|
const proxyPolicyFile = path.join(this.includesDir, 'proxy');
|
|
@@ -1365,6 +1467,10 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
1365
1467
|
await provider.start();
|
|
1366
1468
|
await provider.stop();
|
|
1367
1469
|
|
|
1470
|
+
if (fs.existsSync(testDir)) {
|
|
1471
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1368
1474
|
return result;
|
|
1369
1475
|
} catch (error) {
|
|
1370
1476
|
if (process.env.DEBUG) {
|
|
@@ -1374,10 +1480,6 @@ NginxProvider.check = async ({ configDir = '' } = {}) => {
|
|
|
1374
1480
|
result.error = error.message;
|
|
1375
1481
|
logger.error('check nginx failed', { error });
|
|
1376
1482
|
return result;
|
|
1377
|
-
} finally {
|
|
1378
|
-
if (fs.existsSync(testDir)) {
|
|
1379
|
-
fs.rmSync(testDir, { recursive: true, force: true });
|
|
1380
|
-
}
|
|
1381
1483
|
}
|
|
1382
1484
|
};
|
|
1383
1485
|
|
package/lib/nginx/util.js
CHANGED
|
@@ -209,6 +209,10 @@ real_ip_recursive ${proxyPolicy?.trustRecursive ? 'on' : 'off'};`
|
|
|
209
209
|
default 0;
|
|
210
210
|
include includes/blacklist;
|
|
211
211
|
}
|
|
212
|
+
geo $access_trusted {
|
|
213
|
+
default 0;
|
|
214
|
+
include includes/whitelist;
|
|
215
|
+
}
|
|
212
216
|
map $http_upgrade $connection_upgrade {
|
|
213
217
|
default upgrade;
|
|
214
218
|
'' "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/router-provider",
|
|
3
|
-
"version": "1.16.45-beta-
|
|
3
|
+
"version": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
4
4
|
"description": "Routing engine implementations for abt node",
|
|
5
5
|
"author": "polunzh <polunzh@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/ArcBlock/blocklet-server#readme",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"url": "https://github.com/ArcBlock/blocklet-server/issues"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@abtnode/constant": "1.16.45-beta-
|
|
36
|
-
"@abtnode/db-cache": "1.16.45-beta-
|
|
37
|
-
"@abtnode/logger": "1.16.45-beta-
|
|
38
|
-
"@abtnode/router-templates": "1.16.45-beta-
|
|
39
|
-
"@abtnode/util": "1.16.45-beta-
|
|
35
|
+
"@abtnode/constant": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
36
|
+
"@abtnode/db-cache": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
37
|
+
"@abtnode/logger": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
38
|
+
"@abtnode/router-templates": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
39
|
+
"@abtnode/util": "1.16.45-beta-20250625-064956-91b0fb8f",
|
|
40
40
|
"@arcblock/http-proxy": "^1.19.1",
|
|
41
41
|
"@arcblock/is-valid-domain": "^1.0.5",
|
|
42
42
|
"@ocap/util": "^1.20.14",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"bluebird": "^3.7.2",
|
|
63
63
|
"fs-extra": "^11.2.0"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "90b9c4c9352f9ae33139f4e376b97b3be43698fa"
|
|
66
66
|
}
|