@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.
File without changes
@@ -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._addIpBlackholeServer(conf);
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._addDefaultBlackholeServer(conf);
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
- server._add('server_name', '_');
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
- _addDefaultBlackholeServer(conf) {
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
- _addIpBlackholeServer(conf) {
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
- server._add('return', '444');
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) / 100),
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-20250620-082630-c0c76051",
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-20250620-082630-c0c76051",
36
- "@abtnode/db-cache": "1.16.45-beta-20250620-082630-c0c76051",
37
- "@abtnode/logger": "1.16.45-beta-20250620-082630-c0c76051",
38
- "@abtnode/router-templates": "1.16.45-beta-20250620-082630-c0c76051",
39
- "@abtnode/util": "1.16.45-beta-20250620-082630-c0c76051",
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": "70151f84be54392ce491a1f40976e533286d06b8"
65
+ "gitHead": "90b9c4c9352f9ae33139f4e376b97b3be43698fa"
66
66
  }