block-proxy 0.1.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.
Files changed (49) hide show
  1. package/.eslintignore +3 -0
  2. package/AD_BLOCK.md +38 -0
  3. package/Dockerfile +51 -0
  4. package/LICENSE +21 -0
  5. package/README.md +182 -0
  6. package/bin/start.js +45 -0
  7. package/cert/rootCA.crt +20 -0
  8. package/cert/rootCA.key +27 -0
  9. package/config.json +234 -0
  10. package/craco.config.js +52 -0
  11. package/hack-of-anyproxy/lib/requestHandler.js +1028 -0
  12. package/package.json +54 -0
  13. package/proxy/attacker.js +135 -0
  14. package/proxy/domain.js +26 -0
  15. package/proxy/fs.js +46 -0
  16. package/proxy/http.js +224 -0
  17. package/proxy/mitm/persistentStore.js +34 -0
  18. package/proxy/mitm/persistentStore.json +3 -0
  19. package/proxy/mitm/rule.js +116 -0
  20. package/proxy/mitm/uaFilter.js +47 -0
  21. package/proxy/mitm/ydcd/ydcd.js +34 -0
  22. package/proxy/mitm/youtube/youtube.response.js +39 -0
  23. package/proxy/monitor.js +283 -0
  24. package/proxy/proxy.js +1488 -0
  25. package/proxy/scan.js +120 -0
  26. package/proxy/start.js +7 -0
  27. package/proxy/wanip.js +76 -0
  28. package/public/favicon.ico +0 -0
  29. package/public/index.html +43 -0
  30. package/public/iphone-proxy-setting.jpg +0 -0
  31. package/public/logo192.png +0 -0
  32. package/public/logo512.png +0 -0
  33. package/public/manifest.json +25 -0
  34. package/public/proxy.jpg +0 -0
  35. package/public/robots.txt +3 -0
  36. package/server/express.js +232 -0
  37. package/server/start.js +24 -0
  38. package/server/util.js +166 -0
  39. package/socks5/server.js +321 -0
  40. package/socks5/start.js +7 -0
  41. package/socks5/test_tls_reuse.js +40 -0
  42. package/src/App.css +505 -0
  43. package/src/App.js +759 -0
  44. package/src/App.test.js +8 -0
  45. package/src/index.css +13 -0
  46. package/src/index.js +17 -0
  47. package/src/logo.svg +1 -0
  48. package/src/reportWebVitals.js +13 -0
  49. package/src/setupTests.js +5 -0
package/.eslintignore ADDED
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ build/
3
+ dist/
package/AD_BLOCK.md ADDED
@@ -0,0 +1,38 @@
1
+ [Rule]
2
+ AND,((DOMAIN-SUFFIX,googlevideo.com), (PROTOCOL,UDP)),REJECT
3
+ AND,((DOMAIN,youtubei.googleapis.com), (PROTOCOL,UDP)),REJECT
4
+
5
+ [URL Rewrite]
6
+ (^https?:\/\/[\w-]+\.googlevideo\.com\/(?!dclk_video_ads).+?)&ctier=L(&.+?),ctier,(.+) $1$2$3 302
7
+ ^https?:\/\/[\w-]+\.googlevideo\.com\/(?!(dclk_video_ads|videoplayback\?)).+&oad _ reject-200
8
+ ^https?:\/\/(www|s)\.youtube\.com\/api\/stats\/ads _ reject-200
9
+ ^https?:\/\/(www|s)\.youtube\.com\/(pagead|ptracking) _ reject-200
10
+ ^https?:\/\/s\.youtube\.com\/api\/stats\/qoe\?adcontext _ reject-200
11
+
12
+ [Script]
13
+ youtube.response = type=http-response,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|search|reel\/reel_watch_sequence|guide|account\/get_setting|get_watch),requires-body=1,max-size=-1,binary-body-mode=1,engine={{{脚本执行引擎}}},script-path=https://raw.githubusercontent.com/Maasea/sgmodule/master/Script/Youtube/youtube.response.js,argument="{"lyricLang":"{{{歌词翻译语言}}}","captionLang":"{{{字幕翻译语言}}}","blockUpload":{{{屏蔽上传按钮}}},"blockImmersive":{{{屏蔽选段按钮}}},"debug":{{{启用调试模式}}}}"
14
+
15
+ [MITM]
16
+ hostname = %APPEND% -redirector*.googlevideo.com,*.googlevideo.com,www.youtube.com,s.youtube.com,youtubei.googleapis.com
17
+
18
+
19
+
20
+ --------------------
21
+
22
+ youtube.com
23
+ `^https?:\/\/(www|s)\.youtube\.com\/api\/stats\/ads`
24
+
25
+ youtube.com
26
+ `^https?:\/\/(www|s)\.youtube\.com\/(pagead|ptracking)`
27
+
28
+ youtube.com
29
+ `^https?:\/\/s\.youtube\.com\/api\/stats\/qoe\?adcontext`
30
+
31
+ googlevideo.com
32
+ `^https?:\/\/[\w-]+\.googlevideo\.com\/(?!(dclk_video_ads|videoplayback\?)).+(&oad|ctier)`
33
+
34
+ s.youtube.com
35
+ `^https?:\/\/s\.youtube\.com\/api\/stats\/atr.+&is_ad=1`
36
+
37
+ youtube.com
38
+ `^https?:\/\/(www|s)\.youtube\.com\/pcs\/activeview.+&ad_cpn=`
package/Dockerfile ADDED
@@ -0,0 +1,51 @@
1
+ # 构建阶段
2
+ # 使用与目标平台一致的基础镜像进行构建
3
+ FROM --platform=$TARGETPLATFORM node:18-alpine AS builder
4
+
5
+ WORKDIR /app
6
+
7
+ # 安装 pnpm
8
+ RUN npm install -g pnpm --registry=https://registry.npmmirror.com
9
+
10
+ # 复制依赖文件(利用 Docker 缓存)
11
+ COPY package.json pnpm-lock.yaml ./
12
+ #COPY start.js ./
13
+
14
+ # 安装依赖 - 这一步现在会在目标架构 (e.g., arm64) 的容器中执行
15
+ # 这样生成的 node_modules 中的 native addons 就是为正确的架构编译的
16
+ RUN pnpm install --force --registry=https://registry.npmmirror.com && \
17
+ pnpm store prune && \
18
+ rm -rf /root/.pnpm-store
19
+
20
+ # 复制应用代码
21
+ COPY . ./
22
+
23
+ # 修复权限
24
+ RUN chown -R 1001:1001 /app
25
+
26
+ # 生产阶段
27
+ # 同样使用与目标平台一致的基础镜像
28
+ FROM --platform=$TARGETPLATFORM node:18-alpine
29
+
30
+ # 创建非 root 用户
31
+ RUN addgroup -g 1001 -S nodejs && \
32
+ adduser -S nodeuser -u 1001
33
+
34
+ WORKDIR /app
35
+
36
+ # 从构建阶段复制文件 (现在复制的是为正确架构构建的 node_modules)
37
+ COPY --from=builder --chown=nodeuser:nodejs /app /app
38
+
39
+ # 复制证书
40
+ COPY cert/rootCA.key /root/.anyproxy/certificates/
41
+ COPY cert/rootCA.crt /root/.anyproxy/certificates/
42
+ # COPY init_permissions.sh /app/
43
+ # RUN chmod +x /app/init_permissions.sh
44
+ #COPY start.js /app/start.js
45
+
46
+ USER nodeuser
47
+
48
+ EXPOSE 8001 8002 8003
49
+
50
+ # 使用 node 启动脚本作为 CMD
51
+ CMD ["npm", "run", "start"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 lijing00333
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+
2
+ <img width="300" alt="image" src="https://github.com/user-attachments/assets/2bb069d8-508a-41b9-9fee-94a1e31cc0cb" />
3
+
4
+ ---------------------------
5
+
6
+ > **Block-Proxy**
7
+
8
+ 基于 MITM 的代理和上网过滤工具
9
+
10
+ 主要是限制小朋友上网,依赖 anyproxy,用在 openwrt 里。特性:
11
+
12
+ - HTTP/Socks5 代理
13
+ - 域名拦截
14
+ - url 正则拦截
15
+ - 指定拦截Mac地址
16
+ - 设定日期和时间段
17
+ - 顺便过滤广告
18
+
19
+ ### 1)使用方法
20
+
21
+ #### ① 快速部署
22
+
23
+ 安装:
24
+
25
+ `npm install -g block-proxy`
26
+
27
+ 启动:
28
+
29
+ `block-proxy`
30
+
31
+ #### ② Docker 部署(推荐)
32
+
33
+ 1. 下载 Docker 文件
34
+ - Arm 架构 → <a href="http://yui.cool:7001/public/downloads/block-proxy/arm/block-proxy.tar" target=_blank>block-proxy-arm.tar</a>
35
+ - X86 架构 → <a href="http://yui.cool:7001/public/downloads/block-proxy/x86/block-proxy-x86.tar" target=_blank>block-proxy-x86.tar</a>
36
+ 2. 导入:`docker load < block-proxy.tar`
37
+ 3. 启动:参照下文 Docker 部署
38
+ 4. 服务端配置:配置面板 <http://server-ip:8004>,关闭、启用配置面板:<http://server-ip:8001>
39
+ 5. 客户端配置:http 代理直接在 iphone wifi 详情里手动配置,socks5 代理只支持 socks5 over TLS,用小火箭配置。配置信息参照[配置面板](http://localhost:8004)
40
+
41
+ ### 2)开发和调试
42
+
43
+ 代码 clone 下来后执行`pnpm i`,执行 `npm run dev` 运行本地服务。默认开启 5 个端口:
44
+
45
+ |端口 |说明 |可否关闭|
46
+ |:----:|:------:|:------:|
47
+ |3000 |调试端口(仅开发调试配置面板用)| 生产环境不启用|
48
+ |8001 |HTTP 代理端口 | 不可禁用 |
49
+ |8002 |Socks5(Over TLS)代理端口 | 可禁用 |
50
+ |8003 |AnyProxy 监控页面| 可禁用 |
51
+ |8004 |后台配置页端口 | 可禁用 |
52
+
53
+
54
+ ### 3)Docker 构建和部署
55
+
56
+ 准备工作,构建 docker 包,先启动本地 Docker:
57
+
58
+ - 开发调试:`npm run dev`,开发调试用3000端口
59
+ - 生产启动:`npm run start`,生产环境使用
60
+ - 只启动代理:`npm run proxy`,不启动配置后台,只启动代理
61
+ - 后台构建:`npm run build`
62
+ - 本地打包:`npm run docker:build`
63
+ - 打arm包:`npm run docker:build_arm`
64
+ - 导出tar包到本地:`docker save -o block-proxy.tar block-proxy`
65
+ - 安装包到openwrt:`docker load < block-proxy.tar`
66
+
67
+ > 要是打包 docker 空间不够就执行 `docker system prune -a --volumes`
68
+
69
+ 拷贝 tar 到 openwrt 后启动容器:
70
+
71
+ ```
72
+ docker run --init -d --restart=unless-stopped \
73
+ -e TZ=Asia/Shanghai --network=host \
74
+ --user=root \
75
+ --log-driver local \
76
+ --log-opt max-size=10m \
77
+ --log-opt max-file=3 \
78
+ --cpus="5" \
79
+ --memory 400m \
80
+ --name block-proxy block-proxy
81
+ ```
82
+
83
+ > block-proxy 可以配置只启动 proxy 不启动后台面板,首次启动后访问 http://代理IP:8001 根据提示操作。
84
+
85
+ 网关里为了方便获取子网机器 ip 和 mac 地址,docker 容器需要和宿主机共享同一个网络,同时指定时区。
86
+
87
+ 如果是在 Window/Mac 中,需要手动指定端口绑定(不推荐):
88
+
89
+ ```
90
+ docker run --init -d --restart=unless-stopped --user=root \
91
+ -e TZ=Asia/Shanghai -p 8001:8001 -p 8002:8002 -p 8003:8003 \
92
+ --name block-proxy block-proxy
93
+ ```
94
+
95
+
96
+ ### 4)配置说明
97
+
98
+ #### 代理端口
99
+
100
+ 默认开启两个代理端口:HTTP 8001 和 Socks5(over TLS) 8002。
101
+
102
+ ⚠️ Socks5 代理不支持对 Mac 地址的定向拦截,Mac 地址的拦截只对局域网内的 HTTP 代理绑定生效。建议局域网绑定 http 代理,公网绑定 Socks5 代理。
103
+
104
+ ⚠️ 使用小火箭的 Socks5 over TLS 代理,TLS 选项里勾选“允许不安全”
105
+
106
+ #### 后台配置
107
+
108
+ 访问路径:`http://proxy-ip:8004`
109
+
110
+ 路由表间隔两小时刷新一次。如果新加入网的设备没生效,刷新一下路由表。添加限制条件后,点击重启代理按钮。
111
+
112
+ <img src="https://github.com/user-attachments/assets/16f47d3f-1ef9-47a2-8640-c7e04ec64e1a" width=300 />
113
+
114
+
115
+ #### 设备配置
116
+
117
+ 1. 代理设置:iPhone/iPad 为例:设置 → 无线局域网 → 点击当前网络 → HTTP代理/配置代理,设置服务器和端口。
118
+ 2. 证书设置:打开anproxy监控地址(8003端口),扫码安装证书,在手机设置中安装该证书,同时配置完全信任:设置→通用→关于本机→证书信任设置→打开对AnyProxy的完全信任
119
+
120
+ 小朋友的设备里把 Mac 固定下来:
121
+
122
+ <img width="350" alt="image" src="https://github.com/user-attachments/assets/f9bfab89-7194-4a72-b1ae-5cca27911bc9" />
123
+
124
+ #### 禁掉设备直连
125
+
126
+ 防止小朋友修改网Wifi连接,只允许设备通过代理访问,把直连上网权限关掉。网关里配置防火墙规则:
127
+
128
+ ```
129
+ iptables -I FORWARD -m mac --mac-source D2:9E:8D:1B:F1:4E -j REJECT
130
+ ip6tables -I forwarding_rule -m mac --mac-source D2:9E:8D:1B:F1:4E -j REJECT
131
+ ```
132
+
133
+ 然后重启防火墙
134
+
135
+
136
+ ### 5)使用说明
137
+
138
+ #### 应用条件:
139
+
140
+ 1. MITM 基于 AnyProxy 的规则实现,客户端设备必须要安装 AnyProxy 的证书。
141
+ 2. 服务需要根据 ip 反查 mac 地址,需要代理服务工作在对子网有扫描权限的节点,最好是部署在 openwrt 网关,可以`arp -a`看下是否可以扫描完全。
142
+ 3. 服务会自动更新路由表,每 2 个小时更新一次,对于新入网的设备,最好在后台手动刷新并重启代理,以免拦截规则不能立即生效。
143
+ 4. 所有规则都在 HTTP 代理中生效,Socks5 是指向 AnyProxy 的反向代理,且默认开启了 TLS 加密,内网 Mac 地址的拦截只对直接绑定 HTTP 代理的情况生效。因此建议优先使用 HTTP 代理。
144
+
145
+ #### Youtube 去广告
146
+
147
+ 一共六条拦截规则,这几条 reject 规则直接配置在后台里:
148
+
149
+ - *youtube.com*:`^https?:\/\/(www|s)\.youtube\.com\/(pagead|ptracking)`
150
+ - *youtube.com*:`^https?:\/\/s\.youtube\.com\/api\/stats\/qoe\?adcontext`
151
+ - *youtube.com*:`^https?:\/\/(www|s)\.youtube\.com\/api\/stats\/ads`
152
+ - *googlevideo.com*:`^https?:\/\/[\w-]+\.googlevideo\.com\/(?!(dclk_video_ads|videoplayback\?)).+&oad`
153
+ - <del>*youtubei.googleapis.com*:`\/youtubei\/v1\/notification_registration\/get_settings`</del>
154
+
155
+ 另外两条规则在这里:<https://github.com/jayli/block-proxy/blob/main/proxy/mitm/rule.js>(手工添加上面四条规则就够了)
156
+
157
+ #### 有道词典会员
158
+
159
+ done!
160
+
161
+ #### 代理性能
162
+
163
+ **并发测试**:
164
+
165
+ |直连测试 |代理测试 |
166
+ |:---------:|:----------------:|
167
+ |<img height="500" alt="image" src="https://github.com/user-attachments/assets/8268bc5c-956f-4b67-89c1-cdd5725114b3" /> | <img height="500" alt="image" src="https://github.com/user-attachments/assets/abf4bfa1-c8b8-4907-ba0e-bcc76e8899fa" />|
168
+
169
+ **网速测试**:
170
+
171
+ <img width="544" alt="image" src="https://github.com/user-attachments/assets/67c61e34-67ae-4345-97ca-d266cd35ddf4" />
172
+
173
+ > ⚠️ 提示:如果把 block-proxy 部署在 openwrt 网关上,代理地址和网关地址一致,iOS Safari 有一个默认安全限制,不支持带认证的代理和网关 IP 一致,两个解决办法:
174
+ >
175
+ >1. 不要填代理认证用户名和密码
176
+ >2. 给 openwrt lan 口再绑定一个 IP,ios 设备在局域网内绑定这个 IP
177
+ >
178
+ ><img width="300" alt="image" src="https://github.com/user-attachments/assets/0f46d6b4-00b1-44aa-9be7-fa23a09bb199" />
179
+
180
+ ### License
181
+
182
+ MIT
package/bin/start.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ // 获取包根目录和 start.js 路径
7
+ const pkgDir = path.join(__dirname, '..');
8
+ const startScript = path.resolve(pkgDir, 'server/start.js');
9
+
10
+ // 构造命令:先运行 npm run cp,再运行 node server/start.js
11
+ const command = `npm run cp && node "${startScript}"`;
12
+
13
+ console.error(`[💟] Block-Proxy 启动: ${command}`);
14
+
15
+ // 使用 spawn + shell: true 来支持 && 和管道
16
+ const child = spawn(command, {
17
+ cwd: pkgDir,
18
+ shell: true, // ⭐ 必须启用 shell 才能解析 &&、|、> 等
19
+ stdio: 'pipe' // 我们要手动处理流
20
+ });
21
+
22
+ // 实时输出 stdout(流式)
23
+ child.stdout.on('data', (data) => {
24
+ process.stdout.write(data); // 直接写到父进程 stdout
25
+ });
26
+
27
+ // 实时输出 stderr(流式)
28
+ child.stderr.on('data', (data) => {
29
+ process.stderr.write(data);
30
+ });
31
+
32
+ // 处理子进程退出
33
+ child.on('close', (code, signal) => {
34
+ console.error(`\n[my_app] Process exited with code ${code}`);
35
+ process.exit(code || 0);
36
+ });
37
+
38
+ // 转发 Ctrl+C 信号(重要!)
39
+ process.on('SIGINT', () => {
40
+ console.error('\n[my_app] Received SIGINT, shutting down...');
41
+ child.kill('SIGINT'); // 发送中断信号给子进程
42
+ setTimeout(() => {
43
+ child.kill('SIGTERM'); // 2秒后强制终止
44
+ }, 2000);
45
+ });
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDRzCCAi+gAwIBAgIDA4l1MA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNVBAYTAkNO
3
+ MREwDwYDVQQKEwhBbnlQcm94eTELMAkGA1UECBMCU0gxGzAZBgNVBAsTEkFueVBy
4
+ b3h5IFNTTCBQcm94eTERMA8GA1UEAxMIQW55UHJveHkwHhcNMjUxMjI4MTYzNTA4
5
+ WhcNMjgwNDAxMTYzNTA4WjBdMQswCQYDVQQGEwJDTjERMA8GA1UEChMIQW55UHJv
6
+ eHkxCzAJBgNVBAgTAlNIMRswGQYDVQQLExJBbnlQcm94eSBTU0wgUHJveHkxETAP
7
+ BgNVBAMTCEFueVByb3h5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
8
+ plZZJFrG1gyWdhU8vhcTsFp0qTTbDAd87i4NQtPlGWpojM6ftORbmOZpSv1r5cZZ
9
+ iGC+o3+so/9WRx2a1PmZJvklTeurtTyQ7SsKCNGR+e3TospW05QHvH9CEpBzJ+eV
10
+ A3Z9Vn84GzFABkXJ9lDw0yIbAe+uQkZKaJPR4xCJQTYjDcm62lKQbpUxV8+NVj+A
11
+ HXDY0vj88NXYTPe0AXCxWXWuirNe9M61fo5SZK81B/sNNsEyZs/VW9n8u0BXTg+p
12
+ Lr9qC6NFro7WAnBn0Z4DxGhC1pdzlAMD1+LDcqYsJD6cfhfI+kSQJms8tOE062M5
13
+ uwxnLnp2y5P8Os1nvf0snQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
14
+ DQEBCwUAA4IBAQCLoyYxU1VnX3nmpBAe9TJdCCja44LMwW+vKFAOanciwIX1cK59
15
+ soRmpROMKh2KkEzMtEXYhjnogZLaE2RU9zfsqgKUf85RXynxphJiexWOWCk1mgzV
16
+ XMbh3U3LsaP9E+mQhsRfWnbizT9s1JXJdlQSbVUqR/+ipFLlizGHpICrO6uSaCmc
17
+ qGW4EMamtQVYQQGPW9FneE0uesMUqxNDmAqlB3KppbQampdHNGZUPOi3q0uFeXAc
18
+ QpvHPuX1ek0lW/Vy79lLUMISnmSFWiqEdZPh5wlX1qZcZ0/aUu6dt2T8Zd2nAd5L
19
+ GV+pAFmLQL4qEiUJ4JShBwSpeTha/HhyHsfD
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEAplZZJFrG1gyWdhU8vhcTsFp0qTTbDAd87i4NQtPlGWpojM6f
3
+ tORbmOZpSv1r5cZZiGC+o3+so/9WRx2a1PmZJvklTeurtTyQ7SsKCNGR+e3TospW
4
+ 05QHvH9CEpBzJ+eVA3Z9Vn84GzFABkXJ9lDw0yIbAe+uQkZKaJPR4xCJQTYjDcm6
5
+ 2lKQbpUxV8+NVj+AHXDY0vj88NXYTPe0AXCxWXWuirNe9M61fo5SZK81B/sNNsEy
6
+ Zs/VW9n8u0BXTg+pLr9qC6NFro7WAnBn0Z4DxGhC1pdzlAMD1+LDcqYsJD6cfhfI
7
+ +kSQJms8tOE062M5uwxnLnp2y5P8Os1nvf0snQIDAQABAoIBADjtyKiWoQLVYBGe
8
+ ByIQB98NtmvK+UVOssVZ4ZQDrZ9bOdknRqXEmkzkXxkZTvpfPnlckyKmKdIfK8o/
9
+ KaTGoFIkZ04Z4LSwu/FQD6khANMHQK2wjrLvMQ6kh1qPMbpwmiGLRi56cBtuabk7
10
+ 3Xl+Dk5Ul+W7wGpSYFkWbnlGSZOVg3GUceTl/ws9Eu4lgnRraJFB1DVUTrD3aL+e
11
+ 1p4+Z+yI4jQDJxXU87JHM70zm5KLD3SNVPLH3xE2KztfgSvX2cE/r0HS6c/2SM+O
12
+ t4doP4JeanVXsvzkDNcuY9XrAC0UOisVTSirISGW+VPqnX4e+cRwDupG4Y1WDSC4
13
+ XqACMsECgYEA6QqR0RVc6Umm5+pNNWQvYRqmWd37MpZYRKDVX1oom46sYAyhFLVu
14
+ YRmNOqHzPV717vs1iVuAqr6K7S90hKy5UBBBVBdRRuGjDBysyrDpiCemFT3Pmzaq
15
+ UjonwJt4fMh3MuWTqgabJUMwBjJMM+fx/WGwPNCkbQnLHJY+HU0TrTUCgYEAtrl3
16
+ j0T+vREGUj9q00dA2DfV3qH88hR69H2vzpp8rPY3Un/tgP9NOq2Dl5W6StDSgvh+
17
+ s1Zx6QV5pmmAlIbNGLZ6bX/4qAD8w0eU1GmMEcIsD6auI4DC7oa1EIhwqDZ/oapr
18
+ DfgcE+MpX/nOTi6CvrfjCEKD13HZvLWYFiQdNskCgYAOb9Uwur4SxblNTLqTwC0f
19
+ OuNrVdEmBSJavgv56D/zwxbyrFWeTs8TvN1+8GF9P9DEiVN7uutxqHQ61WHGhlzE
20
+ lP03FGq4lWngajZaKDOPd8VWM4oU94H9rhSgXgFM2a5ovMg1FEuwN0VWXO9Tl97p
21
+ 749XdSV6i8zFbJlUf13ksQKBgQCw27keYfCSfUz6BMnX78qSvRBzqaSTh0EvLgwh
22
+ VCRCoRoQ7yOpzPIqTlHlQZYL3i0zeWPhH1Wn7pW9fbZnjEYtmknLfKbnrfT46mri
23
+ YbqiYaeWCoXYdUO37YiJlRY9qmpExxdRcQl0MlYUwExwHdKM2J2VnBPSTy8p2TZ4
24
+ j8H7CQKBgGYFm/QkLlsCb3lfqsnS3lpRbvslNuxbl+f4db5LNpV5bnYEtb4TCki4
25
+ XC8diX+JbOm28POIkVZrXzZa/KL2x5JXavbUwimSgG32etlR9OJsUUMUV7F4yQhU
26
+ VxJQ3dSq3u4uPaP+cUThuAkaCKeLNPDMgF+gVLqWYZH/J4OiReQE
27
+ -----END RSA PRIVATE KEY-----
package/config.json ADDED
@@ -0,0 +1,234 @@
1
+ {
2
+ "network_scanning_status": "1",
3
+ "progress_time_stamp": "1766571511705",
4
+ "block_hosts": [
5
+ {
6
+ "filter_host": "bilibili.com",
7
+ "filter_match_rule": "",
8
+ "filter_start_time": "00:00",
9
+ "filter_end_time": "23:59",
10
+ "filter_weekday": [
11
+ 1,
12
+ 2,
13
+ 3,
14
+ 4,
15
+ 5,
16
+ 6,
17
+ 7
18
+ ],
19
+ "filter_mac": "6E:FB:18:4D:9C:3E"
20
+ },
21
+ {
22
+ "filter_host": "doubao.com",
23
+ "filter_match_rule": "",
24
+ "filter_start_time": "00:00",
25
+ "filter_end_time": "23:59",
26
+ "filter_weekday": [
27
+ 1,
28
+ 2,
29
+ 3,
30
+ 4,
31
+ 5,
32
+ 6,
33
+ 7
34
+ ],
35
+ "filter_mac": "6E:FB:18:4D:9C:3E"
36
+ },
37
+ {
38
+ "filter_host": "dburl.net",
39
+ "filter_match_rule": "",
40
+ "filter_start_time": "00:00",
41
+ "filter_end_time": "23:59",
42
+ "filter_weekday": [
43
+ 1,
44
+ 2,
45
+ 3,
46
+ 4,
47
+ 5,
48
+ 6,
49
+ 7
50
+ ],
51
+ "filter_mac": "6E:FB:18:4D:9C:3E"
52
+ },
53
+ {
54
+ "filter_host": "baidu.com",
55
+ "filter_match_rule": "",
56
+ "filter_start_time": "00:00",
57
+ "filter_end_time": "23:59",
58
+ "filter_weekday": [
59
+ 1,
60
+ 2,
61
+ 3,
62
+ 4,
63
+ 5,
64
+ 6,
65
+ 7
66
+ ],
67
+ "filter_mac": "6E:FB:18:4D:9C:3E"
68
+ },
69
+ {
70
+ "filter_host": "youtube.com",
71
+ "filter_match_rule": "^https?:\\/\\/(www|s)\\.youtube\\.com\\/(pagead|ptracking)",
72
+ "filter_start_time": "00:00",
73
+ "filter_end_time": "23:59",
74
+ "filter_weekday": [
75
+ 1,
76
+ 2,
77
+ 3,
78
+ 4,
79
+ 5,
80
+ 6,
81
+ 7
82
+ ],
83
+ "compiledFilterRegexp": {}
84
+ },
85
+ {
86
+ "filter_host": "youtube.com",
87
+ "filter_match_rule": "^https?:\\/\\/s\\.youtube\\.com\\/api\\/stats\\/qoe\\?adcontext",
88
+ "filter_start_time": "00:00",
89
+ "filter_end_time": "23:59",
90
+ "filter_weekday": [
91
+ 1,
92
+ 2,
93
+ 3,
94
+ 4,
95
+ 5,
96
+ 6,
97
+ 7
98
+ ],
99
+ "compiledFilterRegexp": {}
100
+ },
101
+ {
102
+ "filter_host": "youtube.com",
103
+ "filter_match_rule": "^https?:\\/\\/(www|s)\\.youtube\\.com\\/api\\/stats\\/ads",
104
+ "filter_start_time": "00:00",
105
+ "filter_end_time": "23:59",
106
+ "filter_weekday": [
107
+ 1,
108
+ 2,
109
+ 3,
110
+ 4,
111
+ 5,
112
+ 6,
113
+ 7
114
+ ],
115
+ "compiledFilterRegexp": {}
116
+ },
117
+ {
118
+ "filter_host": "googlevideo.com",
119
+ "filter_match_rule": "^https?:\\/\\/[\\w-]+\\.googlevideo\\.com\\/(?!(dclk_video_ads|videoplayback\\?)).+&oad",
120
+ "filter_start_time": "00:00",
121
+ "filter_end_time": "23:59",
122
+ "filter_weekday": [
123
+ 1,
124
+ 2,
125
+ 3,
126
+ 4,
127
+ 5,
128
+ 6,
129
+ 7
130
+ ],
131
+ "compiledFilterRegexp": {}
132
+ }
133
+ ],
134
+ "proxy_port": 8001,
135
+ "web_interface_port": 8003,
136
+ "your_domain": "abc.com",
137
+ "vpn_proxy": "",
138
+ "auth_username": "",
139
+ "auth_password": "",
140
+ "enable_express": "1",
141
+ "enable_socks5": "1",
142
+ "socks5_port": 8002,
143
+ "enable_webinterface": "1",
144
+ "devices": [
145
+ {
146
+ "ip": "192.168.124.1",
147
+ "mac": "66:65:A3:5A:D7:8C"
148
+ },
149
+ {
150
+ "ip": "192.168.124.2",
151
+ "mac": "7C:DE:78:A9:83:A0"
152
+ },
153
+ {
154
+ "ip": "192.168.124.3",
155
+ "mac": "0:DD:B6:EA:E6:2A"
156
+ },
157
+ {
158
+ "ip": "192.168.124.6",
159
+ "mac": "0:DD:B6:EB:26:5C"
160
+ },
161
+ {
162
+ "ip": "192.168.124.20",
163
+ "mac": "DC:97:58:D:FD:9F"
164
+ },
165
+ {
166
+ "ip": "192.168.124.37",
167
+ "mac": "DE:1E:87:ED:17:8B"
168
+ },
169
+ {
170
+ "ip": "192.168.124.54",
171
+ "mac": "E2:4D:6E:1:21:6E"
172
+ },
173
+ {
174
+ "ip": "192.168.124.111",
175
+ "mac": "74:3F:C2:67:74:98"
176
+ },
177
+ {
178
+ "ip": "192.168.124.117",
179
+ "mac": "48:F3:F3:CA:1D:E"
180
+ },
181
+ {
182
+ "ip": "192.168.124.149",
183
+ "mac": "14:C0:50:14:6E:A5"
184
+ },
185
+ {
186
+ "ip": "192.168.124.181",
187
+ "mac": "9A:8A:4A:A5:C8:C7"
188
+ },
189
+ {
190
+ "ip": "192.168.124.200",
191
+ "mac": "54:52:84:95:DF:5E"
192
+ },
193
+ {
194
+ "ip": "192.168.124.210",
195
+ "mac": "F4:3C:3B:77:E:AE"
196
+ },
197
+ {
198
+ "ip": "192.168.124.212",
199
+ "mac": "D2:E9:D1:F8:CE:ED"
200
+ },
201
+ {
202
+ "ip": "192.168.124.229",
203
+ "mac": "D6:A0:61:69:67:F6"
204
+ },
205
+ {
206
+ "ip": "192.168.124.240",
207
+ "mac": "F4:6B:8C:90:29:5"
208
+ },
209
+ {
210
+ "ip": "192.168.124.251",
211
+ "mac": "6E:FB:18:4D:9C:3E"
212
+ },
213
+ {
214
+ "ip": "192.168.124.255",
215
+ "mac": "FF:FF:FF:FF:FF:FF"
216
+ },
217
+ {
218
+ "ip": "192.168.124.53",
219
+ "mac": "E2:4D:6E:1:21:6E"
220
+ },
221
+ {
222
+ "ip": "192.168.124.211",
223
+ "mac": "D2:E9:D1:F8:CE:ED"
224
+ },
225
+ {
226
+ "ip": "192.168.124.10",
227
+ "mac": "66:65:A3:5A:D7:8C"
228
+ },
229
+ {
230
+ "ip": "192.168.124.150",
231
+ "mac": "14:C0:50:14:6E:A5"
232
+ }
233
+ ]
234
+ }
@@ -0,0 +1,52 @@
1
+ // craco 具体的配置,只给开发环境使用
2
+ const http = require('http');
3
+ const https = require('https');
4
+ const { URL } = require('url');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ module.exports = {
9
+ devServer: (devServerConfig, { env, paths, proxy, allowedHost }) => {
10
+
11
+ devServerConfig.onBeforeSetupMiddleware = (devServer) => {
12
+
13
+ // get/post /api/config...
14
+ devServer.app.use('/api', async (req, res) => {
15
+ const proxyReq = http.request({
16
+ hostname: 'localhost',
17
+ port: 8003,
18
+ path: '/api' + req.url, // 关键修改:添加缺失的 /api 前缀
19
+ method: req.method,
20
+ headers: req.headers
21
+ }, (proxyRes) => {
22
+ res.writeHead(proxyRes.statusCode, proxyRes.headers);
23
+ proxyRes.pipe(res);
24
+ });
25
+
26
+ proxyReq.on('error', (err) => {
27
+ console.error('Proxy error:', err);
28
+ res.status(500).send('Proxy Error');
29
+ });
30
+
31
+ req.pipe(proxyReq);
32
+ });
33
+ };
34
+
35
+ /*
36
+ // 保存原始的onListening回调(如果存在)
37
+ const originalOnListening = devServerConfig.onListening;
38
+
39
+ // 在服务监听完成后启动LocalProxy
40
+ devServerConfig.onListening = (devServer) => {
41
+ // 调用原始的onListening(如果存在)
42
+ if (originalOnListening) {
43
+ originalOnListening(devServer);
44
+ }
45
+
46
+ // LocalProxy.init();
47
+ };
48
+ */
49
+
50
+ return devServerConfig;
51
+ },
52
+ };