前言
上一篇cloudflare Workers部署vless节点代码发布已经有一段时间了,这次带来的是基于之前代码的优化版本,主要提升了稳定性和传输速率,同时大大降低了延迟 🚀。这些改进将让我们搭建的 VLESS 节点更加高效和稳定,提供更流畅的使用体验 ⚡。
优化点
1. 架构与组织优化 🏗️
- 配置中心化 📊:通过使用
CONFIG
对象集中管理所有配置常量,简化了配置的维护和修改。 - 功能分离 🧩:将 VLESS 协议处理、WebSocket 流管理等功能独立成可复用模块,提升了代码的可读性和模块化程度。
2. 新增功能 🚀
- ALPN 支持增强 🔧:新增对
h3
和h2
的支持,提升了数据传输的稳定性。 - UUID 验证流程优化 🔐:优化了 UUID 验证流程,提升了验证的准确性和安全性。
- 请求大小限制优化 📏:WebSocket 单条消息大小和 HTTP 请求体大小的最大值可以手动指定,增强了数据传输的灵活性和效率。
3. 性能优化 ⚡
- Base64 解码优化 🔄:对 Base64 解码过程进行了优化,提升了性能。
- 节流机制改进 ⏳:通过
packetCount
控制,实现了更为高效的流量管理。 - 管道传输处理 🛠️:改进了管道传输的处理方式,提升了数据流转速度。
- 预计算优化 🔢:使用
Array.from
预生成BYTE_TO_HEX
,减少了临时对象的创建,提高了性能。
4. 安全性增强 🔒
- 错误隔离 🚧:为每个处理阶段添加了独立的错误捕获机制,提升了系统的容错能力。
5. 协议处理增强 🏅
- 明确的头部大小常量 📐:新增
VLESS_HEADER_SIZE
常量,使协议头处理更加规范。 - 更健壮的协议头解析 🔍:优化了协议头的解析,增强了容错能力。
- 支持 MUX 命令(命令类型 3) 📨:增加了对 MUX 命令的支持,拓展了协议的灵活性。
- WebSocket 安全性增强 🛡️:对早期数据处理进行了安全性增强,确保连接的稳定与安全。
客户端配置
优选域名(推荐)
综合各种环境 fast-fast.asuscomm.com
电信最优 fast-10000.asuscomm.com
联通最优 fast-10010.asuscomm.com
移动最优 fast-10086.asuscomm.com
代码
import { connect } from "cloudflare:sockets";
// ====================== 配置常量 ======================
const CONFIG = {
UUID: "8221ea74-6b86-40b7-9c8c-924f558d2d13", // 默认UUID(记得改),建议通过环境变量覆盖
DISGUISED_DOMAIN: "https://blog.hgtrojan.com", // 伪装域名
PATH: "/hello", // 路径检查
HTTP2_ENABLED: true, // 启用HTTP/2支持
MAX_WS_MESSAGE_SIZE: 100 * 1024 * 1024, // WebSocket单条消息最大100MB
MAX_HTTP_BODY_SIZE: 200 * 1024 * 1024, // HTTP请求体最大200MB
VLESS_HEADER_SIZE: 24, // VLESS协议头固定24字节
DNS_PORT: 53, // 允许的UDP端口(仅DNS)
DEBUG: true // 调试模式
};
// UUID验证正则
const UUID_REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
const WS_READY_STATE_OPEN = 1;
// ====================== 工具函数 ======================
// 预计算字节到十六进制的映射
const BYTE_TO_HEX = Array.from({ length: 256 }, (_, i) =>
(i + 256).toString(16).substring(1).toLowerCase()
);
// 验证UUID格式
function validateUUID(uuid) {
return typeof uuid === "string" && UUID_REGEX.test(uuid);
}
// 将Uint8Array转换为UUID字符串
function uuidBufferToString(arr, offset = 0) {
return (
BYTE_TO_HEX[arr[offset]] +
BYTE_TO_HEX[arr[offset + 1]] +
BYTE_TO_HEX[arr[offset + 2]] +
BYTE_TO_HEX[arr[offset + 3]] +
"-" +
BYTE_TO_HEX[arr[offset + 4]] +
BYTE_TO_HEX[arr[offset + 5]] +
"-" +
BYTE_TO_HEX[arr[offset + 6]] +
BYTE_TO_HEX[arr[offset + 7]] +
"-" +
BYTE_TO_HEX[arr[offset + 8]] +
BYTE_TO_HEX[arr[offset + 9]] +
"-" +
BYTE_TO_HEX[arr[offset + 10]] +
BYTE_TO_HEX[arr[offset + 11]] +
BYTE_TO_HEX[arr[offset + 12]] +
BYTE_TO_HEX[arr[offset + 13]] +
BYTE_TO_HEX[arr[offset + 14]] +
BYTE_TO_HEX[arr[offset + 15]]
);
}
// 从缓冲区获取UUID并验证
function getValidatedUUID(arr, offset = 0) {
const uuid = uuidBufferToString(arr, offset);
if (!validateUUID(uuid)) {
throw new TypeError(`Invalid UUID: ${uuid}`);
}
return uuid;
}
// 获取伪装域名内容
async function fetchDisguisedContent() {
try {
const response = await fetch(CONFIG.DISGUISED_DOMAIN);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.text();
} catch (error) {
logError("Fetch disguised content failed", error);
return `<html><body>Welcome to ${CONFIG.DISGUISED_DOMAIN}</body></html>`;
}
}
// 处理未授权请求
async function handleUnauthorizedRequest() {
const disguisedContent = await fetchDisguisedContent();
return new Response(disguisedContent, {
status: 200,
headers: { "content-type": "text/html; charset=utf-8" }
});
}
// 安全关闭WebSocket
function closeWebSocketSafely(socket) {
try {
if (socket?.readyState === WS_READY_STATE_OPEN) {
socket.close();
}
} catch (error) {
logError("WebSocket close error", error);
}
}
// 日志记录
function logInfo(message, context = {}) {
if (CONFIG.DEBUG) {
console.log(JSON.stringify({ type: "info", message, ...context }));
}
}
function logError(message, error, context = {}) {
console.error(JSON.stringify({
type: "error",
message,
error: error?.message || String(error),
stack: error?.stack,
...context
}));
}
// ====================== HTTP/2 处理器 ======================
async function createHttp2Handler(request, env, ctx) {
const userID = env.UUID || CONFIG.UUID;
// 检查必要头部
const requiredHeaders = [
"x-vless-version",
"x-vless-address",
"x-vless-port",
"x-vless-uuid"
];
for (const header of requiredHeaders) {
if (!request.headers.has(header)) {
logError("Missing required header", { header });
return handleUnauthorizedRequest();
}
}
// 验证UUID
const requestUUID = request.headers.get("x-vless-uuid");
if (!validateUUID(requestUUID) || requestUUID !== userID) {
logError("UUID validation failed", { received: requestUUID, expected: userID });
return handleUnauthorizedRequest();
}
// 从头部获取目标信息
const targetAddress = request.headers.get("x-vless-address");
const targetPort = parseInt(request.headers.get("x-vless-port") || "0");
const isUDP = request.headers.get("x-vless-udp") === "true";
// 检查UDP请求(仅支持DNS)
if (isUDP && targetPort !== CONFIG.DNS_PORT) {
logError("UDP port not allowed", { port: targetPort });
return new Response(`UDP proxy only supports port ${CONFIG.DNS_PORT} (DNS)`, {
status: 400
});
}
// 日志上下文
const logContext = {
address: targetAddress,
port: targetPort,
protocol: isUDP ? "UDP" : "TCP",
mode: "HTTP/2"
};
try {
// 检查请求体大小
const contentLength = parseInt(request.headers.get("content-length") || "0");
if (contentLength > CONFIG.MAX_HTTP_BODY_SIZE) {
logError("Request body too large", { size: contentLength, ...logContext });
return new Response("Request body too large", { status: 413 });
}
// 使用流式处理请求体
const remoteSocket = connect({
hostname: targetAddress,
port: targetPort
});
logInfo("Connection established", logContext);
// 管道传输:请求体 → 远程套接字
await request.body.pipeTo(remoteSocket.writable);
// 返回响应流
return new Response(remoteSocket.readable, {
status: 200,
headers: {
"content-type": "application/octet-stream",
"cache-control": "no-store"
}
});
} catch (error) {
logError("Connection failed", error, logContext);
return new Response(`Connection failed: ${error.message}`, {
status: 502
});
}
}
// ====================== WebSocket 处理器 ======================
function createReadableWebSocketStream(webSocket, earlyDataHeader, logContext) {
let isStreamCancelled = false;
let bufferSize = 0;
return new ReadableStream({
start(controller) {
webSocket.addEventListener("message", (event) => {
if (isStreamCancelled) return;
// 检查消息大小
if (event.data.byteLength > CONFIG.MAX_WS_MESSAGE_SIZE) {
controller.error(`Message exceeds ${CONFIG.MAX_WS_MESSAGE_SIZE} bytes limit`);
closeWebSocketSafely(webSocket);
return;
}
bufferSize += event.data.byteLength;
controller.enqueue(event.data);
});
webSocket.addEventListener("error", (error) => {
logError("WebSocket error", error, logContext);
isStreamCancelled = true;
controller.error(error);
});
webSocket.addEventListener("close", () => {
if (isStreamCancelled) return;
logInfo("WebSocket closed", { ...logContext, bufferSize });
controller.close();
});
// 处理早期数据
if (earlyDataHeader) {
try {
const binaryStr = atob(earlyDataHeader.replace(/-/g, "+").replace(/_/g, "/"));
const buffer = new Uint8Array(binaryStr.length);
for (let i = 0; i < binaryStr.length; i++) {
buffer[i] = binaryStr.charCodeAt(i);
}
bufferSize += buffer.byteLength;
controller.enqueue(buffer.buffer);
} catch (error) {
logError("Early data decode failed", error, logContext);
}
}
},
cancel(reason) {
logInfo("WebSocket stream cancelled", { reason, ...logContext });
isStreamCancelled = true;
closeWebSocketSafely(webSocket);
}
});
}
// 处理VLESS协议头
function processVlessHeader(buffer, userID) {
// 检查最小长度
if (buffer.byteLength < CONFIG.VLESS_HEADER_SIZE) {
return { hasError: true, message: `Header too short (min ${CONFIG.VLESS_HEADER_SIZE} bytes)` };
}
const view = new DataView(buffer);
const version = view.getUint8(0);
try {
// 验证用户ID
const headerUserID = getValidatedUUID(new Uint8Array(buffer.slice(1, 17)));
if (headerUserID !== userID) {
return { hasError: true, message: "User authentication failed" };
}
// 处理选项和命令
const optLength = view.getUint8(17);
const cmdPos = 18 + optLength;
const command = view.getUint8(cmdPos);
// 检查命令类型
const isUDP = command === 3; // 1=TCP, 2=UDP, 3=MUX
if (![1, 2].includes(command)) {
return { hasError: true, message: `Unsupported command: ${command}` };
}
// 处理端口
const portRemote = view.getUint16(cmdPos + 1);
// 处理地址类型和值
const addrTypePos = cmdPos + 3;
const addressType = view.getUint8(addrTypePos);
let addrValuePos = addrTypePos + 1;
let addrLength = 0;
let addressValue = "";
switch (addressType) {
case 1: // IPv4
addrLength = 4;
addressValue = Array.from(new Uint8Array(buffer.slice(addrValuePos, addrValuePos + addrLength)))
.join(".");
break;
case 2: // 域名
addrLength = view.getUint8(addrValuePos);
addrValuePos += 1;
addressValue = new TextDecoder().decode(
buffer.slice(addrValuePos, addrValuePos + addrLength)
);
break;
case 3: // IPv6
addrLength = 16;
const ipv6Parts = [];
for (let i = 0; i < 8; i++) {
ipv6Parts.push(view.getUint16(addrValuePos + i * 2).toString(16));
}
addressValue = ipv6Parts.join(":");
break;
default:
return { hasError: true, message: `Invalid address type: ${addressType}` };
}
if (!addressValue) {
return { hasError: true, message: `Empty address (type: ${addressType})` };
}
return {
hasError: false,
addressRemote: addressValue,
portRemote,
rawDataIndex: addrValuePos + addrLength,
vlessVersion: version,
isUDP
};
} catch (error) {
return { hasError: true, message: `Header parse error: ${error.message}` };
}
}
async function handleWebSocketConnection(request, env) {
const userID = env.UUID || CONFIG.UUID;
let remoteSocket = null;
let vlessResponseHeader = new Uint8Array([0, 0]);
let address = "";
let portWithRandomLog = "";
// 创建WebSocket对
const webSocketPair = new WebSocketPair();
const [client, server] = Object.values(webSocketPair);
// 获取早期数据头并接受WebSocket
const earlyDataHeader = request.headers.get("sec-websocket-protocol") || "";
server.accept();
// 远程连接Promise
let remoteSocketReady;
const remoteSocketPromise = new Promise(resolve => {
remoteSocketReady = resolve;
});
// 日志上下文
const getLogContext = () => ({
address,
port: portWithRandomLog.split("--")[0],
earlyData: earlyDataHeader ? "yes" : "no"
});
// 创建WebSocket可读流
const webSocketStream = createReadableWebSocketStream(
server,
earlyDataHeader,
getLogContext()
);
// 处理WebSocket数据
webSocketStream.pipeTo(new WritableStream({
async write(chunk, controller) {
if (remoteSocket) {
// 已有远程连接,直接转发数据
const writer = remoteSocket.writable.getWriter();
await writer.write(chunk);
writer.releaseLock();
return;
}
try {
// 解析VLESS头
const {
hasError,
message,
portRemote,
addressRemote,
rawDataIndex,
vlessVersion,
isUDP
} = processVlessHeader(chunk, userID);
address = addressRemote || "";
portWithRandomLog = `${portRemote}--${Math.random().toString(36).substring(2, 8)} ${isUDP ? "UDP" : "TCP"}`;
// 检查UDP请求
if (isUDP && portRemote !== CONFIG.DNS_PORT) {
throw new Error(`UDP only allowed on port ${CONFIG.DNS_PORT}`);
}
if (hasError) throw new Error(message);
// 设置响应头
vlessResponseHeader = new Uint8Array([vlessVersion, 0]);
// 提取剩余数据
const clientData = chunk.slice(rawDataIndex);
// 连接到远程
remoteSocket = connect({
hostname: addressRemote,
port: portRemote
});
logInfo("Remote connection established", getLogContext());
// 发送初始数据
const writer = remoteSocket.writable.getWriter();
await writer.write(clientData);
writer.releaseLock();
remoteSocketReady(remoteSocket);
} catch (error) {
logError("WebSocket processing failed", error, getLogContext());
controller.error(error);
closeWebSocketSafely(server);
}
},
close() {
logInfo("WebSocket stream closed", getLogContext());
},
abort(reason) {
logError("WebSocket stream aborted", reason, getLogContext());
}
})).catch(error => {
logError("WebSocket pipe error", error, getLogContext());
closeWebSocketSafely(server);
});
// 处理远程数据回传
(async () => {
try {
await remoteSocketPromise;
let packetCount = 0;
await remoteSocket.readable.pipeTo(new WritableStream({
start() {
if (server.readyState === WS_READY_STATE_OPEN) {
server.send(vlessResponseHeader);
}
},
async write(chunk, controller) {
if (server.readyState === WS_READY_STATE_OPEN) {
// 简单的节流控制
if (packetCount++ > 100000000000) {
packetCount = 0;
await new Promise(resolve => setTimeout(resolve, 0));
}
server.send(chunk);
} else {
controller.error("WebSocket closed");
}
},
close() {
logInfo("Remote stream closed", getLogContext());
closeWebSocketSafely(server);
},
abort(reason) {
logError("Remote stream aborted", reason, getLogContext());
closeWebSocketSafely(server);
}
}));
} catch (error) {
logError("Remote connection failed", error, getLogContext());
closeWebSocketSafely(server);
}
})();
return new Response(null, {
status: 101,
webSocket: client
});
}
// ====================== 主入口 ======================
export default {
async fetch(request, env, ctx) {
try {
// HTTP/2模式
if (CONFIG.HTTP2_ENABLED && request.headers.get("content-type") === "application/vless") {
return createHttp2Handler(request, env, ctx);
}
// WebSocket模式
if (request.headers.get("Upgrade") === "websocket") {
return handleWebSocketConnection(request, env);
}
// 其他请求返回伪装内容
return handleUnauthorizedRequest();
} catch (error) {
logError("Top-level error", error);
return handleUnauthorizedRequest();
}
}
};