block-proxy 0.1.1 → 0.1.2
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/bin/start.js +80 -29
- package/config.json +1 -1
- package/package.json +1 -1
- package/proxy/proxy.js +8 -3
- package/server/express.js +1 -1
- package/socks5/server.js +15 -4
package/bin/start.js
CHANGED
|
@@ -3,43 +3,94 @@
|
|
|
3
3
|
const { spawn } = require('child_process');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
-
// 获取包根目录和 start.js 路径
|
|
7
6
|
const pkgDir = path.join(__dirname, '..');
|
|
8
7
|
const startScript = path.resolve(pkgDir, 'server/start.js');
|
|
8
|
+
const MAX_RESTARTS = 10000;
|
|
9
|
+
let restartCount = 0;
|
|
10
|
+
let restartTimer = null;
|
|
11
|
+
let currentChild = null; // 👈 全局引用当前子进程
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
const command = `npm run cp && node "${startScript}"`;
|
|
13
|
+
function startApp() {
|
|
14
|
+
const command = `npm run cp && node "${startScript}"`;
|
|
15
|
+
console.error(`[💟] Block-Proxy 启动 (第 ${restartCount + 1} 次): ${command}`);
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
currentChild = spawn(command, {
|
|
18
|
+
cwd: pkgDir,
|
|
19
|
+
shell: true,
|
|
20
|
+
stdio: 'pipe'
|
|
21
|
+
});
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
shell: true, // ⭐ 必须启用 shell 才能解析 &&、|、> 等
|
|
19
|
-
stdio: 'pipe' // 我们要手动处理流
|
|
20
|
-
});
|
|
23
|
+
currentChild.stdout.on('data', (data) => {
|
|
24
|
+
process.stdout.write(data);
|
|
25
|
+
});
|
|
21
26
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
27
|
+
currentChild.stderr.on('data', (data) => {
|
|
28
|
+
process.stderr.write(data);
|
|
29
|
+
});
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
currentChild.on('close', (code, signal) => {
|
|
32
|
+
currentChild = null; // 清空引用
|
|
33
|
+
if (restartTimer) {
|
|
34
|
+
clearTimeout(restartTimer);
|
|
35
|
+
restartTimer = null;
|
|
36
|
+
}
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
38
|
+
if (code === 0) {
|
|
39
|
+
console.error('[block proxy] 正常退出,不重启。');
|
|
40
|
+
process.exit(0);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (signal === 'SIGINT' || signal === 'SIGTERM') {
|
|
45
|
+
console.error('[block-proxy] 被信号终止,不重启。');
|
|
46
|
+
process.exit(128 + (signal === 'SIGINT' ? 2 : 15));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
37
49
|
|
|
38
|
-
|
|
50
|
+
if (restartCount < MAX_RESTARTS) {
|
|
51
|
+
restartCount++;
|
|
52
|
+
console.error(`[block proxy] 将在 3 秒后自动重启...(已重启 ${restartCount}/${MAX_RESTARTS} 次)`);
|
|
53
|
+
restartTimer = setTimeout(() => {
|
|
54
|
+
restartTimer = null;
|
|
55
|
+
startApp();
|
|
56
|
+
}, 3000);
|
|
57
|
+
} else {
|
|
58
|
+
console.error(`[block proxy] 已达到最大重启次数 (${MAX_RESTARTS}),停止尝试。`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ✅ 只注册一次 SIGINT 监听器(在 startApp 外部!)
|
|
39
65
|
process.on('SIGINT', () => {
|
|
40
|
-
console.error('\n[
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
66
|
+
console.error('\n[block proxy] 收到 SIGINT,正在关闭子进程...');
|
|
67
|
+
|
|
68
|
+
if (restartTimer) {
|
|
69
|
+
clearTimeout(restartTimer);
|
|
70
|
+
restartTimer = null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (currentChild) {
|
|
74
|
+
currentChild.kill('SIGINT');
|
|
75
|
+
// 注意:不要在这里 exit,等 close 事件处理
|
|
76
|
+
} else {
|
|
77
|
+
// 如果没有子进程,直接退出
|
|
78
|
+
process.exit(0);
|
|
79
|
+
}
|
|
45
80
|
});
|
|
81
|
+
|
|
82
|
+
process.on('SIGTERM', () => {
|
|
83
|
+
console.error('\n[block proxy] 收到 SIGTERM,正在关闭子进程...');
|
|
84
|
+
if (restartTimer) {
|
|
85
|
+
clearTimeout(restartTimer);
|
|
86
|
+
restartTimer = null;
|
|
87
|
+
}
|
|
88
|
+
if (currentChild) {
|
|
89
|
+
currentChild.kill('SIGTERM');
|
|
90
|
+
} else {
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// 启动
|
|
96
|
+
startApp();
|
package/config.json
CHANGED
package/package.json
CHANGED
package/proxy/proxy.js
CHANGED
|
@@ -207,7 +207,12 @@ async function loadConfig() {
|
|
|
207
207
|
|
|
208
208
|
async function updateWanIp() {
|
|
209
209
|
// var ips = await domain.getDomainIP(your_domain);
|
|
210
|
-
var ip =
|
|
210
|
+
var ip = "0.0.0.0";
|
|
211
|
+
try {
|
|
212
|
+
ip = await wanip.getPublicIp();
|
|
213
|
+
} catch(e) {
|
|
214
|
+
ip = "0.0.0.0";
|
|
215
|
+
}
|
|
211
216
|
if (ip === null) {
|
|
212
217
|
ip = "0.0.0.0";
|
|
213
218
|
}
|
|
@@ -398,9 +403,9 @@ function startProxyServer() {
|
|
|
398
403
|
proxyServerInstance = new AnyProxy.ProxyServer(options);
|
|
399
404
|
|
|
400
405
|
proxyServerInstance.on('ready', () => {
|
|
401
|
-
console.log(`✅
|
|
406
|
+
console.log(`✅ \x1b[32mHTTP 代理服务启动,端口 ${proxyPort}\x1b[0m`);
|
|
402
407
|
if (enable_webinterface == "1") {
|
|
403
|
-
console.log(`✅
|
|
408
|
+
console.log(`✅ \x1b[32mAnyProxy 监控面板启动,端口 ${webInterfacePort}\x1b[0m`);
|
|
404
409
|
}
|
|
405
410
|
console.log('Intercepting requests to hosts:', blockHosts.join(', '));
|
|
406
411
|
console.log('All other requests will be passed through without HTTPS interception');
|
package/server/express.js
CHANGED
|
@@ -206,7 +206,6 @@ module.exports = {
|
|
|
206
206
|
init: function() {
|
|
207
207
|
// 启动服务器
|
|
208
208
|
app.listen(PORT, async () => {
|
|
209
|
-
console.log(`✅ 静态服务器运行在 http://localhost:${PORT}`);
|
|
210
209
|
// 如果是开发环境,则启动SSR服务,开启端口3000
|
|
211
210
|
if (DEV === '1') {
|
|
212
211
|
const child = exec('npm run craco', { cwd: path.join(__dirname,'../') });
|
|
@@ -227,6 +226,7 @@ module.exports = {
|
|
|
227
226
|
}
|
|
228
227
|
// 启动本地代理
|
|
229
228
|
await LocalProxy.init();
|
|
229
|
+
console.log(`✅ \x1b[32m后台配置面板启动 → http://localhost:${PORT}\x1b[0m`);
|
|
230
230
|
});
|
|
231
231
|
}
|
|
232
232
|
};
|
package/socks5/server.js
CHANGED
|
@@ -196,6 +196,12 @@ async function init() {
|
|
|
196
196
|
|
|
197
197
|
// 创建 TLS 封装的 SOCKS5 服务器
|
|
198
198
|
const server = tls.createServer(tlsOptions, async (socket) => {
|
|
199
|
+
// 👇 关键:捕获 socket 级别的错误(包括 ECONNRESET)
|
|
200
|
+
socket.on('error', (err) => {
|
|
201
|
+
console.warn('Client socket error (ignored):', err.message);
|
|
202
|
+
// 不需要手动 destroy(),Node.js 会自动关闭
|
|
203
|
+
});
|
|
204
|
+
|
|
199
205
|
try {
|
|
200
206
|
// Step 1: 协商认证方法
|
|
201
207
|
const authMethodsBuf = await new Promise((resolve) => {
|
|
@@ -295,6 +301,11 @@ async function init() {
|
|
|
295
301
|
}
|
|
296
302
|
});
|
|
297
303
|
|
|
304
|
+
server.on('clientError', (err, socket) => {
|
|
305
|
+
console.warn('TLS client error during handshake:', err.message);
|
|
306
|
+
socket?.end(); // 安全关闭
|
|
307
|
+
});
|
|
308
|
+
|
|
298
309
|
// 错误处理
|
|
299
310
|
server.on('tlsClientError', (err, tlsSocket) => {
|
|
300
311
|
console.warn('TLS handshake failed:', err.message);
|
|
@@ -307,10 +318,10 @@ async function init() {
|
|
|
307
318
|
|
|
308
319
|
// 启动监听
|
|
309
320
|
server.listen(LISTEN_PORT, () => {
|
|
310
|
-
console.log(`✅
|
|
311
|
-
console.log(`🔒
|
|
312
|
-
console.log(`➡️ TCP →
|
|
313
|
-
console.log(`➡️ UDP →
|
|
321
|
+
console.log(`✅ \x1b[32mSOCKS5 (over TLS) 服务启动,端口 ${LISTEN_PORT}\x1b[0m`);
|
|
322
|
+
console.log(`🔒 传输加密和认证基于 TLS`);
|
|
323
|
+
console.log(`➡️ TCP → 流量转发至 HTTP 代理 → ${DOWNSTREAM_HTTP_PROXY_HOST}:${DOWNSTREAM_HTTP_PROXY_PORT}`);
|
|
324
|
+
console.log(`➡️ UDP → 直接发起请求`);
|
|
314
325
|
});
|
|
315
326
|
} catch (err) {
|
|
316
327
|
console.error('Failed to initialize SOCKS5-TLS proxy:', err);
|