需要机场?点击https://jichang.mhdy.net

需要exhentai里站账号,eh GP,eh代捐赠(铜星),telegram账号,点击下方抢购吧!

https://shop.mhdy.net

看前须知,本方法与cf workers pages vless无本质区别,只是加密方式不同和使用略有区别

自建你首先得有个域名,workers.dev国内无法访问、

https://youtu.be/Y_SHcD3prt8?si=y4BCuZSqDXviv3td

下面是配置文件的变量

变量作用

变量名称

变量值要求

变量默认值

变量要求

1、CF服务端域名:端口

cf_domain

域名:443系端口或者80系端口

无,必须CF处获取workers/pages/自定义的域名

必填

2、CF服务端密钥

token

与服务端一样的字母数字

无密钥

可选但推荐

3、客户端本地IP端口

client_ip

10000-65000之间

30000

可选

4、指定优选IP/域名

cf_cdnip

CF的优选IP或者优选域名

yg(可任意1-13数字).ygkkk.dpdns.org,中国移动基本上是落地香港,电信联通基本上落地日本新加坡

可选,也推荐使用cloudflare-ech.com这个优选域名,基本上落地美欧地区

5、指定ProxyIP

pyip

ipv4或[ipv6]或域名

使用服务端ProxyIP

可选

6、DNS指定DoH

dns

DNS的DoH格式

dns.alidns.com/dns-query

可选(cf的doh:https://cloudflare-dns.com/dns-query)

7、ECH开关

enable_ech

y=开启,n=关闭

开启ECH

可选(仅workers.dev域名开启)

8、分流开关

cnrule

y=国内外分流代理,n=全局代理

国内外分流代理

可选

Cloudflare Workers配置


const pyip = ['pyip.ygkkk.dpdns.org']; //自定义proxyip:''之间可使用IP或者域名,IPV6需[],不支持带端口
const token = '';//''之间可使用任意字符密码,客户端token保持一致

const WS_READY_STATE_OPEN = 1;
const WS_READY_STATE_CLOSING = 2;
const encoder = new TextEncoder();
import { connect } from 'cloudflare:sockets';
export default {
  async fetch(request, env, ctx) {
    try {
      const upgradeHeader = request.headers.get('Upgrade');
      if (!upgradeHeader || upgradeHeader.toLowerCase() !== 'websocket') {
        return new URL(request.url).pathname === '/'
          ? new Response('恭喜,当前网址可用于CF Workers/Pages的Socks5或Http本地代理服务', { status: 200 })
          : new Response('当前网址出错,请确认', { status: 426 });
      }
      if (token && request.headers.get('Sec-WebSocket-Protocol') !== token) {
        return new Response('Unauthorized', { status: 401 });
      }
      const [client, server] = Object.values(new WebSocketPair());
      server.accept();
      server.binaryType = 'arraybuffer';
      handleSession(server).catch(() => safeCloseWebSocket(server));
      const responseInit = {
        status: 101,
        webSocket: client
      };
      if (token) {
        responseInit.headers = { 'Sec-WebSocket-Protocol': token };
      }
      return new Response(null, responseInit);

    } catch (err) {
      return new Response(err.toString(), { status: 500 });
    }
  },
};
async function handleSession(webSocket) {
  let remoteSocket, remoteWriter, remoteReader;
  let isClosed = false;

  const cleanup = () => {
    if (isClosed) return;
    isClosed = true;
    try { remoteWriter?.releaseLock(); } catch {}
    try { remoteReader?.releaseLock(); } catch {}
    try { remoteSocket?.close(); } catch {}
    remoteWriter = remoteReader = remoteSocket = null;
    safeCloseWebSocket(webSocket);
  };
  const pumpRemoteToWebSocket = async () => {
    try {
      while (!isClosed && remoteReader) {
        const { done, value } = await remoteReader.read();

        if (done) break;
        if (webSocket.readyState !== WS_READY_STATE_OPEN) break;
        if (value?.byteLength > 0) webSocket.send(value);
      }
    } catch {}

    if (!isClosed) {
      try { webSocket.send('CLOSE'); } catch {}
      cleanup();
    }
  };
  const parseAddress = (addr) => {
    if (addr[0] === '[') {
      const end = addr.indexOf(']');
      return {
        host: addr.substring(1, end),
        port: parseInt(addr.substring(end + 2), 10)
      };
    }
    const sep = addr.lastIndexOf(':');
    return {
      host: addr.substring(0, sep),
      port: parseInt(addr.substring(sep + 1), 10)
    };
  };
  const isCFError = (err) => {
    const msg = err?.message?.toLowerCase() || '';
    return msg.includes('proxy request') ||
           msg.includes('cannot connect') ||
           msg.includes('cloudflare');
  };
  const parseClientPyip = (s) => {
    if (!s) return null;
    const trimmed = String(s).trim();
    if (!trimmed.toUpperCase().startsWith('PYIP=')) return null;

    const val = trimmed.substring(5).trim();
    if (!val) return null;

    const arr = val.split(',')
      .map(x => x.trim())
      .filter(Boolean);

    return arr.length ? arr : null;
  };
  const connectToRemote = async (targetAddr, firstFrameData, clientPyip) => {
    const { host, port } = parseAddress(targetAddr);

    const pyipList = (Array.isArray(clientPyip) && clientPyip.length)
      ? clientPyip
      : pyip;
    const attempts = [null, ...pyipList];
    for (let i = 0; i < attempts.length; i++) {
      try {
        remoteSocket = connect({
          hostname: attempts[i] || host,
          port
        });
        if (remoteSocket.opened) await remoteSocket.opened;
        remoteWriter = remoteSocket.writable.getWriter();
        remoteReader = remoteSocket.readable.getReader();
        if (firstFrameData) {
          await remoteWriter.write(encoder.encode(firstFrameData));
        }
        webSocket.send('CONNECTED');
        pumpRemoteToWebSocket();
        return;
      } catch (err) {
        try { remoteWriter?.releaseLock(); } catch {}
        try { remoteReader?.releaseLock(); } catch {}
        try { remoteSocket?.close(); } catch {}
        remoteWriter = remoteReader = remoteSocket = null;

        if (!isCFError(err) || i === attempts.length - 1) {
          throw err;
        }
      }
    }
  };
  webSocket.addEventListener('message', async (event) => {
    if (isClosed) return;
    try {
      const data = event.data;
      if (typeof data === 'string') {
        if (data.startsWith('CONNECT:')) {
          const parts = data.substring(8).split('|');
          const targetAddr = parts[0] || '';
          const firstFrameData = parts[1] ?? '';
          const clientPyip = parseClientPyip(parts[2]);
          await connectToRemote(targetAddr, firstFrameData, clientPyip);
        }
        else if (data.startsWith('DATA:')) {
          if (remoteWriter) {
            await remoteWriter.write(encoder.encode(data.substring(5)));
          }
        }
        else if (data === 'CLOSE') {
          cleanup();
        }
      }
      else if (data instanceof ArrayBuffer && remoteWriter) {
        await remoteWriter.write(new Uint8Array(data));
      }
    } catch (err) {
      try { webSocket.send('ERROR:' + err.message); } catch {}
      cleanup();
    }
  });
  webSocket.addEventListener('close', cleanup);
  webSocket.addEventListener('error', cleanup);
}
function safeCloseWebSocket(ws) {
  try {
    if (ws.readyState === WS_READY_STATE_OPEN ||
        ws.readyState === WS_READY_STATE_CLOSING) {
      ws.close(1000, 'Server closed');
    }
  } catch {}
}

创建一个workers,将上述代码覆盖后修改token即可proxyip不会改就别动

软路由等linux系统

curl -sSL https://raw.githubusercontent.com/yonggekkk/Cloudflare_vless_trojan/main/s5http_wkpgs/cfsh.sh -o cfsh.sh && chmod +x cfsh.sh && bash cfsh.sh

执行脚本后添加节点即可

配置同下Windows

Windows使用

首先点击下载代理程序

在同目录下创建一个start.bat文件,下面的示例为博主自建的,推荐自建使用,也可以直接使用下面的,但是更推荐自建

@echo off

set client_ip=127.0.0.1:30000
:: 本地代理地址,需要给其他机子使用则改为0.0.0.0,端口随意
set dns=cloudflare-dns.com/dns-query
:: 需要的dns,必须doh,谁家的都行
set token=mhdy
:: 你在workers中设置的token
set cf_domain=proxy.64396439.xyz:443
:: workers.dev域名国内无法连接,改为自定义域名,端口443即可
set cf_cdnip=cloudflare-ech.com
:: 任意优选ip即可如: yg1.ygkkk.dpdns.org
set enable_ech=n
:: 是否开启ech,仅workers.dev域名开启
set cnrule=y
:: 是否开启绕过国内
set pyip=
:: proxyip, 可用可不用

windows-amd64.exe client_ip=%client_ip% cf_domain=%cf_domain% cf_cdnip=%cf_cdnip% token=%token% enable_ech=%enable_ech% dns=%dns% cnrule=%cnrule% pyip=%pyip%
pause

编辑完成后双击start.bat启动程序,出现下图这样的说明可用

此时打开你的代理软件,任意即可

甚至你还可以直接修改系统代理来使用,虽然没什么问题但不是很推荐

V2rayN socks设置如下,http也一样,只需要地址和端口即可,socks和http端口一致

Clash类使用只需要在配置文件添加

  - name: "cf ech"

    type: http

    server: 127.0.0.1

    port: 30000

然后在需要的代理组添加即可

手机/安卓客户端

点击下载app

填写配置同上Windows,手机不自带分流只有分应用和全局

和pc一样你不勾选全局和分应用那就只会创建socks/http代理,可以配合V2ranyNG等代理软件使用

当然你也可以直接在网络代理里指定手动代理