forked from eishare/tuic-hy2-node.js-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode.js
More file actions
223 lines (193 loc) · 6.66 KB
/
node.js
File metadata and controls
223 lines (193 loc) · 6.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env node
/**
* =========================================
* TUIC v5 over QUIC 自动部署脚本(Node.js 版,无需 root)
* 特性:
* - 支持自定义端口参数或环境变量 SERVER_PORT
* - 使用确认为 v1.4.5 x86_64-linux 二进制下载链接(硬编码)
* - 随机伪装域名
* - 自动生成证书
* - 自动下载 tuic-server
* - 自动生成配置文件与 TUIC 链接
* - 自动守护运行
* =========================================
*/
import { execSync, spawn } from "child_process";
import fs from "fs";
import https from "https";
import crypto from "crypto";
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
// ================== 基本配置 ==================
const MASQ_DOMAINS = [
"www.bing.com",
];
const SERVER_TOML = "server.toml";
const CERT_PEM = "tuic-cert.pem";
const KEY_PEM = "tuic-key.pem";
const LINK_TXT = "tuic_link.txt";
const TUIC_BIN = "./tuic-server";
// ================== 工具函数 ==================
const randomPort = () => Math.floor(Math.random() * 40000) + 20000;
const randomSNI = () =>
MASQ_DOMAINS[Math.floor(Math.random() * MASQ_DOMAINS.length)];
const randomHex = (len = 16) => crypto.randomBytes(len).toString("hex");
const uuid = () => crypto.randomUUID();
function fileExists(p) {
return fs.existsSync(p);
}
function execSafe(cmd) {
try {
return execSync(cmd, { encoding: "utf8", stdio: "pipe" }).trim();
} catch {
return "";
}
}
// ================== 下载文件(支持重定向) ==================
async function downloadFile(url, dest, redirectCount = 0) {
return new Promise((resolve, reject) => {
if (redirectCount > 5) return reject(new Error("重定向次数过多"));
const file = fs.createWriteStream(dest);
https
.get(url, (res) => {
if ([301, 302, 303, 307, 308].includes(res.statusCode)) {
const newUrl = res.headers.location;
console.log(`↪️ 跳转到新地址: ${newUrl}`);
file.close();
try { fs.unlinkSync(dest); } catch(e){}
return resolve(downloadFile(newUrl, dest, redirectCount + 1));
}
if (res.statusCode !== 200)
return reject(new Error(`下载失败: ${res.statusCode}`));
res.pipe(file);
file.on("finish", () => file.close(resolve));
})
.on("error", reject);
});
}
// ================== 读取端口 ==================
function readPort() {
const argPort = process.argv[2];
if (argPort && !isNaN(argPort)) {
console.log(`✅ 使用命令行端口: ${argPort}`);
return Number(argPort);
}
if (process.env.SERVER_PORT && !isNaN(process.env.SERVER_PORT)) {
console.log(`✅ 使用环境变量端口: ${process.env.SERVER_PORT}`);
return Number(process.env.SERVER_PORT);
}
const port = randomPort();
console.log(`🎲 自动分配随机端口: ${port}`);
return port;
}
// ================== 生成证书 ==================
function generateCert(domain) {
if (fileExists(CERT_PEM) && fileExists(KEY_PEM)) {
console.log("🔐 证书存在,跳过生成");
return;
}
console.log(`🔐 生成伪装证书 (${domain})...`);
execSafe(
`openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \
-keyout ${KEY_PEM} -out ${CERT_PEM} -subj "/CN=${domain}" -days 365 -nodes`
);
fs.chmodSync(KEY_PEM, 0o600);
fs.chmodSync(CERT_PEM, 0o644);
}
// ================== 检查或下载 tuic-server ==================
async function checkTuicServer() {
if (fileExists(TUIC_BIN)) {
console.log("✅ tuic-server 已存在");
return;
}
console.log("📥 下载 tuic-server v1.4.5 (x86_64‐linux)...");
const url = "https://github.com/Itsusinn/tuic/releases/download/v1.4.5/tuic-server-x86_64-linux";
await downloadFile(url, TUIC_BIN);
fs.chmodSync(TUIC_BIN, 0o755);
console.log("✅ tuic-server 下载完成");
}
// ================== 生成配置文件 ==================
function generateConfig(uuid, password, port, domain) {
const secret = randomHex(16);
const mtu = 1200 + Math.floor(Math.random() * 200);
const toml = `
log_level = "warn"
server = "0.0.0.0:${port}"
udp_relay_ipv6 = false
zero_rtt_handshake = true
dual_stack = false
auth_timeout = "8s"
task_negotiation_timeout = "4s"
gc_interval = "8s"
gc_lifetime = "8s"
max_external_packet_size = 8192
[users]
${uuid} = "${password}"
[tls]
certificate = "${CERT_PEM}"
private_key = "${KEY_PEM}"
alpn = ["h3"]
[restful]
addr = "127.0.0.1:${port}"
secret = "${secret}"
maximum_clients_per_user = 999999999
[quic]
initial_mtu = ${mtu}
min_mtu = 1200
gso = true
pmtu = true
send_window = 33554432
receive_window = 16777216
max_idle_time = "25s"
[quic.congestion_control]
controller = "bbr"
initial_window = 6291456
`;
fs.writeFileSync(SERVER_TOML, toml.trim() + "\n");
console.log("⚙️ 配置文件已生成:", SERVER_TOML);
}
// ================== 获取公网IP ==================
async function getPublicIP() {
return new Promise((resolve) => {
https
.get("https://api64.ipify.org", (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => resolve(data.trim() || "127.0.0.1"));
})
.on("error", () => resolve("127.0.0.1"));
});
}
// ================== 生成 TUIC 链接 ==================
function generateLink(uuid, password, ip, port, domain) {
const link = `tuic://${uuid}:${password}@${ip}:${port}?congestion_control=bbr&alpn=h3&allowInsecure=1&sni=${domain}&udp_relay_mode=native&disable_sni=0&reduce_rtt=1&max_udp_relay_packet_size=8192#TUIC-${ip}`;
fs.writeFileSync(LINK_TXT, link);
console.log("🔗 TUIC 链接已生成:");
console.log(link);
}
// ================== 守护运行 ==================
function runLoop() {
console.log("🚀 启动 TUIC 服务...");
const loop = () => {
const proc = spawn(TUIC_BIN, ["-c", SERVER_TOML], { stdio: "ignore" });
proc.on("exit", (code) => {
console.log(`⚠️ TUIC 异常退出 (${code}),5 秒后重启...`);
setTimeout(loop, 5000);
});
};
loop();
}
// ================== 主流程 ==================
async function main() {
console.log("🌐 TUIC v5 over QUIC 自动部署开始");
const port = readPort();
const domain = randomSNI();
const id = uuid();
const password = randomHex(16);
generateCert(domain);
await checkTuicServer();
generateConfig(id, password, port, domain);
const ip = await getPublicIP();
generateLink(id, password, ip, port, domain);
runLoop();
}
main().catch((err) => console.error("❌ 发生错误:", err));