@abtnode/router-provider 1.16.49-beta-20250827-025603-2bb1a7ee → 1.16.49-beta-20250828-094758-93e69d1f
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/daemon/ssl +3 -0
- package/lib/nginx/index.js +92 -7
- package/lib/util.js +1 -0
- package/package.json +7 -7
package/lib/nginx/index.js
CHANGED
|
@@ -164,6 +164,7 @@ class NginxProvider extends BaseProvider {
|
|
|
164
164
|
|
|
165
165
|
this._copyConfigFiles();
|
|
166
166
|
this._ensureDhparam();
|
|
167
|
+
this._ensureDaemonSecurityHeaders();
|
|
167
168
|
this.updateProxyPolicy({ enabled: false });
|
|
168
169
|
this.initialize();
|
|
169
170
|
}
|
|
@@ -303,6 +304,7 @@ class NginxProvider extends BaseProvider {
|
|
|
303
304
|
// if match certificate, then add https server
|
|
304
305
|
this._addHttpsServer({
|
|
305
306
|
conf,
|
|
307
|
+
serviceType: site.serviceType,
|
|
306
308
|
locations: rules,
|
|
307
309
|
certificateFileName: certificate.domain,
|
|
308
310
|
serverName: parsedServerName,
|
|
@@ -314,6 +316,7 @@ class NginxProvider extends BaseProvider {
|
|
|
314
316
|
} else {
|
|
315
317
|
this._addHttpServer({
|
|
316
318
|
conf,
|
|
319
|
+
serviceType: site.serviceType,
|
|
317
320
|
locations: rules,
|
|
318
321
|
serverName: parsedServerName,
|
|
319
322
|
corsAllowedOrigins,
|
|
@@ -581,6 +584,16 @@ class NginxProvider extends BaseProvider {
|
|
|
581
584
|
}
|
|
582
585
|
}
|
|
583
586
|
|
|
587
|
+
_addSecurityHeaders(location, serviceType) {
|
|
588
|
+
if (serviceType === 'daemon') {
|
|
589
|
+
if (fs.existsSync(path.join(this.includesDir, 'daemon', 'security'))) {
|
|
590
|
+
location._add('include', 'includes/daemon/security');
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
location._add('include', 'includes/daemon/ssl');
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
584
597
|
/**
|
|
585
598
|
* Returns:
|
|
586
599
|
* server /flash/ {
|
|
@@ -605,6 +618,7 @@ class NginxProvider extends BaseProvider {
|
|
|
605
618
|
commonHeaders,
|
|
606
619
|
cacheGroup,
|
|
607
620
|
pageGroup,
|
|
621
|
+
serviceType,
|
|
608
622
|
}) {
|
|
609
623
|
server._add('location', concatPath(prefix, suffix, root));
|
|
610
624
|
|
|
@@ -637,6 +651,8 @@ class NginxProvider extends BaseProvider {
|
|
|
637
651
|
location._add('include', 'includes/cache');
|
|
638
652
|
}
|
|
639
653
|
|
|
654
|
+
this._addSecurityHeaders(location, serviceType);
|
|
655
|
+
|
|
640
656
|
// Redirect blocklet traffic
|
|
641
657
|
if (type === ROUTING_RULE_TYPES.BLOCKLET) {
|
|
642
658
|
// FIXME: logic related to server gateway should not in provider
|
|
@@ -680,7 +696,7 @@ class NginxProvider extends BaseProvider {
|
|
|
680
696
|
location._add('proxy_pass', `http://${getUpstreamName(port)}`);
|
|
681
697
|
}
|
|
682
698
|
|
|
683
|
-
_addRedirectTypeLocation({ server, url, redirectCode, prefix, suffix }) {
|
|
699
|
+
_addRedirectTypeLocation({ server, url, redirectCode, prefix, suffix, serviceType }) {
|
|
684
700
|
const cleanUrl = trimEndSlash(url);
|
|
685
701
|
server._add('location', `${concatPath(prefix, suffix)}`);
|
|
686
702
|
const location = this._getLastLocation(server);
|
|
@@ -694,6 +710,8 @@ class NginxProvider extends BaseProvider {
|
|
|
694
710
|
// always allow cors here since we are doing a redirect
|
|
695
711
|
location._add('include', 'includes/cors');
|
|
696
712
|
|
|
713
|
+
this._addSecurityHeaders(location, serviceType);
|
|
714
|
+
|
|
697
715
|
// 如果 prefix 是根路径,则不需要重写,直接将当前的请求附加到设置的重定向地址后面
|
|
698
716
|
if (prefix === '/') {
|
|
699
717
|
location._add('return', `${redirectCode} ${cleanUrl}$request_uri`);
|
|
@@ -704,24 +722,28 @@ class NginxProvider extends BaseProvider {
|
|
|
704
722
|
}
|
|
705
723
|
}
|
|
706
724
|
|
|
707
|
-
_addRewriteTypeLocation({ server, url, prefix, suffix }) {
|
|
725
|
+
_addRewriteTypeLocation({ server, url, prefix, suffix, serviceType }) {
|
|
708
726
|
server._add('location', concatPath(prefix, suffix));
|
|
709
727
|
const location = this._getLastLocation(server);
|
|
728
|
+
|
|
729
|
+
this._addSecurityHeaders(location, serviceType);
|
|
710
730
|
location._add('rewrite', `^${prefix}(.*) ${url}$1 last`);
|
|
711
731
|
}
|
|
712
732
|
|
|
713
|
-
_addNotFoundLocation({ server, prefix, suffix }) {
|
|
733
|
+
_addNotFoundLocation({ server, prefix, suffix, serviceType }) {
|
|
714
734
|
server._add('location', concatPath(prefix, suffix));
|
|
715
735
|
const location = this._getLastLocation(server);
|
|
716
|
-
this._addTailSlashRedirection(location, prefix);
|
|
717
736
|
|
|
737
|
+
this._addSecurityHeaders(location, serviceType);
|
|
738
|
+
this._addTailSlashRedirection(location, prefix);
|
|
718
739
|
location._add('try_files', '$uri /404.html break');
|
|
719
740
|
}
|
|
720
741
|
|
|
721
|
-
_addGeneralProxyLocation({ server, port, prefix, suffix, blockletDid, targetPrefix }) {
|
|
742
|
+
_addGeneralProxyLocation({ server, port, prefix, suffix, blockletDid, targetPrefix, serviceType }) {
|
|
722
743
|
server._add('location', concatPath(prefix, suffix));
|
|
723
744
|
const location = this._getLastLocation(server);
|
|
724
745
|
this._addCommonHeader(location);
|
|
746
|
+
this._addSecurityHeaders(location, serviceType);
|
|
725
747
|
location._add('include', 'includes/proxy');
|
|
726
748
|
if (blockletDid) {
|
|
727
749
|
location._add('proxy_set_header', `X-Blocklet-Did ${blockletDid}`);
|
|
@@ -867,6 +889,67 @@ class NginxProvider extends BaseProvider {
|
|
|
867
889
|
}
|
|
868
890
|
}
|
|
869
891
|
|
|
892
|
+
_ensureDaemonSecurityHeaders() {
|
|
893
|
+
const securityFilePath = path.join(this.includesDir, 'daemon', 'security');
|
|
894
|
+
const cspSources = [
|
|
895
|
+
'https://*.blocklet.dev',
|
|
896
|
+
'wss://*.blocklet.dev',
|
|
897
|
+
'https://didnames.io',
|
|
898
|
+
'https://*.did.abtnet.io',
|
|
899
|
+
'wss://*.did.abtnet.io',
|
|
900
|
+
'https://*.ip.abtnet.io',
|
|
901
|
+
'wss://*.ip.abtnet.io',
|
|
902
|
+
'data:',
|
|
903
|
+
'blob:',
|
|
904
|
+
'*/__blocklet__.js',
|
|
905
|
+
'*/.well-known/ping',
|
|
906
|
+
'https://api.simplesvg.com',
|
|
907
|
+
'https://api.unisvg.com',
|
|
908
|
+
'https://api.iconify.design',
|
|
909
|
+
];
|
|
910
|
+
const cspPolicy = `default-src 'self'; frame-ancestors 'none'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' ${cspSources.join(' ')}; font-src 'self' data:; connect-src 'self' ${cspSources.join(' ')} */.well-known/ping; base-uri 'self'; object-src 'none'`;
|
|
911
|
+
const cspLine = `add_header Content-Security-Policy "${cspPolicy}" always;`;
|
|
912
|
+
|
|
913
|
+
try {
|
|
914
|
+
if (fs.existsSync(securityFilePath)) {
|
|
915
|
+
logger.info('security include file already exists', { path: securityFilePath });
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
const baseContent = [
|
|
920
|
+
'## Global HTTP security headers (safe baseline)',
|
|
921
|
+
'',
|
|
922
|
+
'# MIME sniffing protection',
|
|
923
|
+
'add_header X-Content-Type-Options "nosniff" always;',
|
|
924
|
+
'# --- Secure Headers Baseline ---',
|
|
925
|
+
'# Hide headers from upstream (in case the upstream app sets them).',
|
|
926
|
+
'# This prevents duplicate values which may cause overly strict policies.',
|
|
927
|
+
'proxy_hide_header Content-Security-Policy;',
|
|
928
|
+
'proxy_hide_header Referrer-Policy;',
|
|
929
|
+
'proxy_hide_header Permissions-Policy;',
|
|
930
|
+
'# Referrer-Policy:',
|
|
931
|
+
'# Controls how much referrer information is included with requests.',
|
|
932
|
+
'# "strict-origin-when-cross-origin" is a balanced choice: full referrer',
|
|
933
|
+
'# for same-origin, origin only for cross-origin, nothing on downgrade.',
|
|
934
|
+
'# Use "no-referrer" if you want the strictest setting.',
|
|
935
|
+
'add_header Referrer-Policy "strict-origin-when-cross-origin" always;',
|
|
936
|
+
'add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), bluetooth=(), fullscreen=(), xr-spatial-tracking=(), magnetometer=(), gyroscope=(), accelerometer=(), browsing-topics=()" always;',
|
|
937
|
+
'add_header X-Frame-Options "DENY" always;',
|
|
938
|
+
'# Content-Security-Policy (CSP):',
|
|
939
|
+
'# Mitigates XSS by restricting resource loading.',
|
|
940
|
+
'# This baseline only allows self-hosted resources, blocks framing,',
|
|
941
|
+
'# disallows <base> tag overrides, and disables legacy plugins.',
|
|
942
|
+
'# Adjust sources (script-src, style-src, img-src, etc.) if you need CDNs.',
|
|
943
|
+
cspLine,
|
|
944
|
+
].join('\n');
|
|
945
|
+
|
|
946
|
+
fs.writeFileSync(securityFilePath, baseContent);
|
|
947
|
+
logger.info('security include file updated', { path: securityFilePath });
|
|
948
|
+
} catch (error) {
|
|
949
|
+
logger.error('Failed to update security include file', { error, path: securityFilePath });
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
870
953
|
_addCommonResHeaders(block, headers) {
|
|
871
954
|
if (!headers || Object.prototype.toString.call(headers) !== '[object Object]') {
|
|
872
955
|
return;
|
|
@@ -1019,11 +1102,12 @@ class NginxProvider extends BaseProvider {
|
|
|
1019
1102
|
daemonPort,
|
|
1020
1103
|
commonHeaders,
|
|
1021
1104
|
blockletDid,
|
|
1105
|
+
serviceType,
|
|
1022
1106
|
}) {
|
|
1023
1107
|
const httpServerUnit = this._addHttpServerUnit({ conf, serverName, port });
|
|
1024
1108
|
this._addDefaultLocations({ server: httpServerUnit, daemonPort, serverName });
|
|
1025
1109
|
// eslint-disable-next-line max-len
|
|
1026
|
-
locations.forEach((x) => this._addReverseProxy({ server: httpServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid })); // prettier-ignore
|
|
1110
|
+
locations.forEach((x) => this._addReverseProxy({ server: httpServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid, serviceType })); // prettier-ignore
|
|
1027
1111
|
}
|
|
1028
1112
|
|
|
1029
1113
|
_addHttpsServer({
|
|
@@ -1031,6 +1115,7 @@ class NginxProvider extends BaseProvider {
|
|
|
1031
1115
|
locations,
|
|
1032
1116
|
certificateFileName,
|
|
1033
1117
|
serverName,
|
|
1118
|
+
serviceType,
|
|
1034
1119
|
corsAllowedOrigins,
|
|
1035
1120
|
daemonPort,
|
|
1036
1121
|
commonHeaders,
|
|
@@ -1043,7 +1128,7 @@ class NginxProvider extends BaseProvider {
|
|
|
1043
1128
|
|
|
1044
1129
|
this._addDefaultLocations({ server: httpsServerUnit, daemonPort, serverName });
|
|
1045
1130
|
// eslint-disable-next-line max-len
|
|
1046
|
-
locations.forEach((x) => this._addReverseProxy({ server: httpsServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid })); // prettier-ignore
|
|
1131
|
+
locations.forEach((x) => this._addReverseProxy({ server: httpsServerUnit, ...x, serverName, corsAllowedOrigins, commonHeaders, blockletDid, serviceType })); // prettier-ignore
|
|
1047
1132
|
}
|
|
1048
1133
|
|
|
1049
1134
|
_addHttpServerUnit({ conf, serverName, port = '' }) {
|
package/lib/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/router-provider",
|
|
3
|
-
"version": "1.16.49-beta-
|
|
3
|
+
"version": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
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.49-beta-
|
|
36
|
-
"@abtnode/db-cache": "1.16.49-beta-
|
|
37
|
-
"@abtnode/logger": "1.16.49-beta-
|
|
38
|
-
"@abtnode/router-templates": "1.16.49-beta-
|
|
39
|
-
"@abtnode/util": "1.16.49-beta-
|
|
35
|
+
"@abtnode/constant": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
36
|
+
"@abtnode/db-cache": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
37
|
+
"@abtnode/logger": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
38
|
+
"@abtnode/router-templates": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
39
|
+
"@abtnode/util": "1.16.49-beta-20250828-094758-93e69d1f",
|
|
40
40
|
"@arcblock/http-proxy": "^1.19.1",
|
|
41
41
|
"@arcblock/is-valid-domain": "^1.0.5",
|
|
42
42
|
"@ocap/util": "^1.23.1",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"bluebird": "^3.7.2",
|
|
63
63
|
"fs-extra": "^11.2.0"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "587711a6df767cafaadbb503daeac586e22c3988"
|
|
66
66
|
}
|