From d6025287a0e80cfcbb928103160edf75c5b644c3 Mon Sep 17 00:00:00 2001 From: zeaslity Date: Thu, 10 Jul 2025 16:49:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E9=87=8F=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crawl4AI/craw4ai-docker-compose.yml | 22 + .../Dify-AI-Center/crawl4AI/环境变量.env | 9 + .../openai-web-dockercompose.yaml | 0 .../文章主题内容.txt | 5 + .../获取网页内容.txt | 5 + .../股票咨询工作流-ethinvestmentlab/输出内容.md | 6 + 0-部署应用/Oracle-Cloud/将内存挂载为硬盘.sh | 2 +- .../gitea-bitnami-docker-compose.yaml | 6 +- .../AI-Dify/docker-compose-modified.yaml | 48 +- .../Phoneix-arm64-01/AI-Dify/设置的环境.env | 15 +- .../AI-Dify/docker-compose-modified.yaml | 18 +- 0-部署应用/证书申请/证书申请模板.sh | 6 + .../0-香港节点/0-xtls-reality的配置.json | 38 - 1-代理Xray/0-香港节点/0-基础原生配置.json | 82 ++ 1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json | 84 ++ 1-代理Xray/0-香港节点/2-FV-韩国-首尔.json | 84 ++ 1-代理Xray/0-香港节点/3-FV-日本-东京.json | 84 ++ 1-代理Xray/0-香港节点/4-FV-英国-伦敦.json | 85 ++ 1-代理Xray/0-香港节点/5-FV-新加坡.json | 85 ++ 1-代理Xray/0-香港节点/6-FV-香港.json | 85 ++ 1-代理Xray/0-香港节点/9-Vless组合配置.json | 861 +++++++++++++++ ...层代理回落.json => 9-汇总+fvpn的配置-失败.json} | 20 +- 1-代理Xray/4-凤凰城-amd02节点/普通代理.json | 72 ++ 1-代理Xray/98-subscribe-clash.yaml | 348 ++++-- 1-代理Xray/99-subscribe-octopus-latest.txt | 40 +- .../cloudflare-worker-vless.yaml | 27 + .../cloudflare-机场/cmliu-vless-worker.js | 772 ++++++++++++++ 1-代理Xray/cloudflare-机场/yonge_cf_worker.js | 996 ++++++++++++++++++ 1-代理Xray/cloudflare-机场/yongge_cf_core.js | 581 ++++++++++ 1-代理Xray/cloudflare-机场/yongge_cf_core.md | 49 + 1-代理Xray/cloudflare-机场/参考文档.txt | 14 + 1-代理Xray/cloudflare-机场/自建proxyIP.txt | 25 + 1-代理Xray/v2ray-Socks5/sock5代理服务器.json | 25 + 1-代理Xray/v2ray-Socks5/socks5中继服务器.json | 12 +- 2-NGINX相关/107421.xyz/21-申请证书.sh | 7 +- 2-NGINX相关/nginx安装/80转443模板.conf | 30 + 2-NGINX相关/nginx安装/test.conf | 49 + 5-fastestVPN节点信息/FastestVPN-香港.txt | 9 + 5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt | 0 .../德国-杜塞尔多夫-无法使用.txt | 9 + 5-fastestVPN节点信息/德国-法兰克福.txt | 9 + 5-fastestVPN节点信息/新加坡.txt | 12 + 5-fastestVPN节点信息/日本-东京.txt | 9 + 5-fastestVPN节点信息/美国-洛杉矶.txt | 9 + 5-fastestVPN节点信息/英国-伦敦.txt | 9 + .../阿根廷-布伊利诺斯艾利斯.txt | 1 + 5-fastestVPN节点信息/韩国-首尔.txt | 9 + tmp.sh | 1 + 脚本参考/XA工作理解.txt | 10 + 49 files changed, 4620 insertions(+), 164 deletions(-) create mode 100644 0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml create mode 100644 0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env rename 0-部署应用/{Oracle-Cloud => Dify-AI-Center}/openai-reverse-proxy/openai-web-dockercompose.yaml (100%) create mode 100644 0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/文章主题内容.txt create mode 100644 0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/获取网页内容.txt create mode 100644 0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md delete mode 100644 1-代理Xray/0-香港节点/0-xtls-reality的配置.json create mode 100644 1-代理Xray/0-香港节点/0-基础原生配置.json create mode 100644 1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json create mode 100644 1-代理Xray/0-香港节点/2-FV-韩国-首尔.json create mode 100644 1-代理Xray/0-香港节点/3-FV-日本-东京.json create mode 100644 1-代理Xray/0-香港节点/4-FV-英国-伦敦.json create mode 100644 1-代理Xray/0-香港节点/5-FV-新加坡.json create mode 100644 1-代理Xray/0-香港节点/6-FV-香港.json create mode 100644 1-代理Xray/0-香港节点/9-Vless组合配置.json rename 1-代理Xray/0-香港节点/{0-分层代理回落.json => 9-汇总+fvpn的配置-失败.json} (82%) create mode 100644 1-代理Xray/4-凤凰城-amd02节点/普通代理.json create mode 100644 1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml create mode 100644 1-代理Xray/cloudflare-机场/cmliu-vless-worker.js create mode 100644 1-代理Xray/cloudflare-机场/yonge_cf_worker.js create mode 100644 1-代理Xray/cloudflare-机场/yongge_cf_core.js create mode 100644 1-代理Xray/cloudflare-机场/yongge_cf_core.md create mode 100644 1-代理Xray/cloudflare-机场/参考文档.txt create mode 100644 1-代理Xray/cloudflare-机场/自建proxyIP.txt create mode 100644 1-代理Xray/v2ray-Socks5/sock5代理服务器.json create mode 100644 2-NGINX相关/nginx安装/80转443模板.conf create mode 100644 2-NGINX相关/nginx安装/test.conf create mode 100644 5-fastestVPN节点信息/FastestVPN-香港.txt create mode 100644 5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt create mode 100644 5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt create mode 100644 5-fastestVPN节点信息/德国-法兰克福.txt create mode 100644 5-fastestVPN节点信息/新加坡.txt create mode 100644 5-fastestVPN节点信息/日本-东京.txt create mode 100644 5-fastestVPN节点信息/美国-洛杉矶.txt create mode 100644 5-fastestVPN节点信息/英国-伦敦.txt create mode 100644 5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt create mode 100644 5-fastestVPN节点信息/韩国-首尔.txt create mode 100644 脚本参考/XA工作理解.txt diff --git a/0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml b/0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml new file mode 100644 index 0000000..0f91820 --- /dev/null +++ b/0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' + +services: + crawl4ai: + image: unclecode/crawl4ai:basic + ports: + - "1235:11235" + environment: + - CRAWL4AI_API_TOKEN=${CRAWL4AI_API_TOKEN:-} # Optional API security + - MAX_CONCURRENT_TASKS=${CRAWL4AI_API_TOKEN:-} + # LLM Provider Keys + - OPENAI_API_KEY=${OPENAI_API_KEY:-} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} + - GEMINI_API_KEY=${GEMINI_API_KEY:-} + volumes: + - /dev/shm:/dev/shm + deploy: + resources: + limits: + memory: 4G + reservations: + memory: 1G \ No newline at end of file diff --git a/0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env b/0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env new file mode 100644 index 0000000..53fc4b8 --- /dev/null +++ b/0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env @@ -0,0 +1,9 @@ +# API Security (optional) +CRAWL4AI_API_TOKEN=EP53z52yx1r8k87G7y34AMojqpCHU4eMxO1MEGOBwa5mlDYe + +# LLM Provider Keys +OPENAI_API_KEY=sk-proj-lCRIbBe3ex7VJP5GzAklT3BlbkFJbOcB4cXRQKk7pNZjBCHM +GEMINI_API_KEY=AIzaSyBv2JN5aY_OKDI5e1aVEf6uDQli65X9NZM + +# Other Configuration +MAX_CONCURRENT_TASKS=5 \ No newline at end of file diff --git a/0-部署应用/Oracle-Cloud/openai-reverse-proxy/openai-web-dockercompose.yaml b/0-部署应用/Dify-AI-Center/openai-reverse-proxy/openai-web-dockercompose.yaml similarity index 100% rename from 0-部署应用/Oracle-Cloud/openai-reverse-proxy/openai-web-dockercompose.yaml rename to 0-部署应用/Dify-AI-Center/openai-reverse-proxy/openai-web-dockercompose.yaml diff --git a/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/文章主题内容.txt b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/文章主题内容.txt new file mode 100644 index 0000000..6a4351b --- /dev/null +++ b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/文章主题内容.txt @@ -0,0 +1,5 @@ +{ + "text": "**内容** [隐藏](#)\n\n[ 1) 豆粕基差崩盘:一场心照不宣的博弈? ](#dou_po_ji_cha_beng_pan_yi_chang_xin_zhao_bu_xuan_de_bo_yi)\n\n[ 1.1) 别再装了!是谁在压低豆粕价格? ](#bie_zai_zhuang_le_shi_shei_zai_ya_di_dou_po_jia_ge)\n\n[ 2) 所谓的“需求疲软”:不过是资本的遮羞布 ](#suo_wei_de_xu_qiu_pi_ruan_bu_guo_shi_zi_ben_de_zhe_xiu_bu)\n\n[ 2.1) 饲料配方调整?我看是利润的驱使! ](#si_liao_pei_fang_diao_zheng_wo_kan_shi_li_run_de_qu_shi)\n\n[ 2.2) 养殖户哭穷?产业链上谁没受损? ](#yang_zhi_hu_ku_qiong_chan_ye_lian_shang_shei_mei_shou_sun)\n\n[ 3) 开工率的谎言:数据背后隐藏的真相 ](#kai_gong_lu_de_huang_yan_shu_ju_bei_hou_yin_cang_de_zhen_xiang)\n\n[ 3.1) 停机检修?我看是变相控盘! ](#ting_ji_jian_xiu_wo_kan_shi_bian_xiang_kong_pan)\n\n[ 3.2) 进口大豆:救命稻草还是饮鸩止渴? ](#jin_kou_da_dou_jiu_ming_dao_cao_hai_shi_yin_zhen_zhi_ke)\n\n[ 4) 库存的猫腻:谁在囤积居奇? ](#ku_cun_de_mao_ni_shei_zai_dun_ji_ju_qi)\n\n[ 4.1) 缺豆不缺粕:这难道不是一场阴谋? ](#que_dou_bu_que_po_zhe_nan_dao_bu_shi_yi_chang_yin_mou)\n\n[ 4.2) 贸易商的伎俩:低买高卖,永恒的真理? ](#mao_yi_shang_de_ji_lia_di_mai_gao_mai_yong_heng_de_zhen_li)\n\n[ 5) 四月豆粕:昙花一现还是持续低迷? ](#si_yue_dou_po_tan_hua_yi_xian_hai_shi_chi_xu_di_mi)\n\n[ 5.1) 补库需求:下游最后的挣扎? ](#bu_ku_xu_qiu_xia_you_zui_hou_de_zheng_zha)\n\n[ 5.2) 卓创资讯的预测:是分析还是引导? ](#zhuo_chuang_zi_xun_de_yu_ce_shi_fen_xi_hai_shi_yin_dao)\n\n## 豆粕基差崩盘:一场心照不宣的博弈?\n\n### 别再装了!是谁在压低豆粕价格?\n\n最近豆粕市场的惨淡景象,真让人觉得空气里都弥漫着一股子铜臭味儿。所谓的“分析师”们,一口一个“供需关系”,仿佛把所有责任都推给了市场规律,但明眼人都看得出来,这背后绝对不是简单的市场波动,而是一场心照不宣的博弈,一场资本对散户的收割。\n\n卓创资讯的报告里说,3月山东豆粕现货基差价格持续回落,这“回落”两个字,轻描淡写,背后是多少养殖户、饲料商的血泪?别跟我扯什么“豆粕添加比例下调”、“上游豆粕库存累积”,这些都是表象!\n\n想想看,是谁掌握着豆粕的定价权?是那些手握大豆进口渠道、控制着压榨产能的巨头们!他们的一举一动,都能直接影响豆粕的价格走势。现在说“供应过剩”,难道不是他们前期盲目扩张、囤积居奇造成的?现在倒好,把锅甩给下游,自己拍拍屁股走人,吃相也太难看了吧?\n\n当然,下游也不是完全无辜。一些大型饲料企业,仗着自己体量大,就拼命压价,恨不得把豆粕价格压到土里。他们心里门儿清,知道上游不敢得罪他们这些大客户,所以就肆无忌惮地玩弄着价格游戏。\n\n所以说,这场豆粕基差的崩盘,根本不是什么“市场规律”,而是一场资本的狂欢,一场强者的游戏。散户们,你们的命运,早就被写在了他们的剧本里! \n\n## 所谓的“需求疲软”:不过是资本的遮羞布\n\n### 饲料配方调整?我看是利润的驱使!\n\n都说“需求决定价格”,但豆粕市场这出戏,演得实在太假了。什么“饲料中豆粕添加比例下滑”?说白了,还不是因为豆粕价格上涨,那些饲料厂为了保住自己的利润,才被迫调整配方,减少豆粕用量,增加玉米蛋白粉、棉粕、花生粕这些“杂粕”的替代。\n\n这就像你去饭馆吃饭,猪肉涨价了,老板就给你多加点萝卜白菜,少放点肉。味道肯定不一样了,营养也肯定打折扣了,但老板才不管这些,他要的是利润!同样的道理,饲料厂才不会真正关心牲畜的营养,他们只关心怎么用最便宜的原料,生产出利润最大的饲料。\n\n这种“配方调整”,与其说是“需求疲软”,不如说是“利润的驱使”。资本家们为了榨取更多的剩余价值,无所不用其极,连牲畜的口粮都要算计,简直是丧心病狂!\n\n### 养殖户哭穷?产业链上谁没受损?\n\n当然,饲料厂的“配方调整”,最终还是会传导到养殖户身上。豆粕添加比例降低,饲料的营养价值下降,牲畜的生长速度变慢,抗病能力减弱,养殖成本自然就上升了。\n\n再加上这两年猪周期下行,猪肉价格低迷,养殖户的日子本来就不好过。现在豆粕价格又这么不稳定,他们更是雪上加霜,苦不堪言。\n\n但话说回来,养殖户们真的那么无辜吗?他们难道没有为了追求更高的利润,盲目扩张,过度养殖?难道他们没有为了降低成本,使用各种违禁药物,导致食品安全问题频发?\n\n在这个产业链上,没有谁是完全无辜的。每个人都在为了自己的利益,拼命挣扎,互相倾轧。最终的结果,就是整个行业的混乱和衰败。 \n\n## 开工率的谎言:数据背后隐藏的真相\n\n### 停机检修?我看是变相控盘!\n\n卓创资讯的数据显示,3月底山东大豆压榨企业平均开工负荷率降至23.12%的阶段性低点,4月下旬预计升至68.02%。看到这组数据,我不禁要问:这开工率是真低,还是假低?这背后到底隐藏着什么不可告人的秘密?\n\n别跟我说什么“原料衔接问题”、“停机检修”,这些都是借口!那些大型压榨企业,哪个不是财大气粗,哪个不是渠道通天?他们会缺大豆?他们会因为一点小问题就停机?\n\n我看这所谓的“停机检修”,不过是他们变相控盘的手段罢了。通过降低开工率,减少豆粕的供应,人为制造“供应紧张”的假象,然后伺机抬高价格,从中渔利。\n\n这种把戏,他们玩得炉火纯青,早就不是什么新鲜事了。但可悲的是,我们这些小散户,却总是被他们玩弄于股掌之间,任人宰割。\n\n### 进口大豆:救命稻草还是饮鸩止渴?\n\n报告里提到,4月中旬开始巴西大豆将集中到港,上游供应将恢复正常水平。这巴西大豆,真的是我们的救命稻草吗?我看未必!\n\n首先,过度依赖进口大豆,会让我们在国际贸易中处于被动地位,受制于人。一旦国际市场出现波动,我们的豆粕价格就会跟着遭殃。\n\n其次,大量进口转基因大豆,会对我们的农业生态环境造成潜在的威胁。转基因作物对环境的影响,至今仍存在争议,我们不能为了眼前的利益,而牺牲长远的未来。\n\n更重要的是,过度依赖进口大豆,会扼杀我们自己的大豆产业。国内的大豆种植户,本来就利润微薄,如果再受到进口大豆的冲击,他们还有活路吗?\n\n所以说,这巴西大豆,看似是缓解供应紧张的“救命稻草”,实则是饮鸩止渴,后患无穷。我们不能为了眼前的利益,而牺牲我们自己的农业根基。 \n\n## 库存的猫腻:谁在囤积居奇?\n\n### 缺豆不缺粕:这难道不是一场阴谋?\n\n卓创资讯的数据显示,3月第三周,山东大豆压榨企业大豆库存为两年来低点,而豆粕库存却处于相对高位。这种“缺豆不缺粕”的诡异现象,简直让人细思极恐。\n\n正常情况下,大豆库存低,豆粕库存也应该跟着下降才对。但现在的情况却是,一边是原料紧缺,一边是产品滞销,这难道不是一场精心策划的阴谋?\n\n那些压榨企业,明明知道大豆供应紧张,为什么还要拼命生产豆粕?难道他们不知道这样会加剧豆粕的供过于求,压低价格吗?\n\n除非,他们是故意这么做的!他们先是囤积居奇,抬高大豆价格,然后再大量生产豆粕,压低豆粕价格。这样一来,他们就可以在原料和产品两端同时获利,把整个市场玩弄于股掌之间。\n\n### 贸易商的伎俩:低买高卖,永恒的真理?\n\n当然,除了压榨企业,那些贸易商也脱不了干系。他们利用自己的信息优势和资金优势,低买高卖,从中赚取差价。\n\n他们会故意散布虚假信息,制造市场恐慌,诱导散户们抛售豆粕。然后,他们再趁机低价收购,囤积起来,等待价格上涨时再高价卖出。\n\n这种“低买高卖”的伎俩,看似简单,实则蕴含着深刻的商业智慧。但这种智慧,却是建立在对散户的剥削之上的。\n\n在这个弱肉强食的市场里,散户们就像一群待宰的羔羊,没有任何反抗能力。他们只能眼睁睁地看着自己的财富被那些资本大鳄们一点点蚕食殆尽。\n\n可悲的是,很多散户还执迷不悟,以为自己可以通过“技术分析”、“消息面”来战胜市场。殊不知,他们所看到的一切,都是那些资本大鳄们精心设计的陷阱。 \n\n## 四月豆粕:昙花一现还是持续低迷?\n\n### 补库需求:下游最后的挣扎?\n\n卓创资讯预计,4月上旬日照大豆压榨企业开工水平仍处低位,下游存在刚性补库需求,豆粕现货基差价格或阶段性止跌。这“补库需求”,听起来像是下游最后的挣扎,但真的能扭转乾坤吗?\n\n我看不见得。下游的饲料厂和养殖户,经历了3月份的暴跌,早就被吓破了胆。他们现在的心态是,能少买就少买,能拖就拖,尽量减少损失。\n\n即使真的有“刚性补库需求”,他们也会选择观望,等待价格进一步下跌。毕竟,谁也不想在高位接盘,成为最后的韭菜。\n\n更何况,4月中旬巴西大豆就要大量到港,供应压力只会越来越大。下游的补库需求,恐怕只是杯水车薪,无法改变豆粕价格的整体颓势。\n\n### 卓创资讯的预测:是分析还是引导?\n\n卓创资讯的报告最后预测,4月下旬山东豆粕现货基差价格或重启下行通道。这个预测,看似客观,实则充满了引导性。\n\n作为一个行业咨询机构,卓创资讯的报告对市场有着重要的影响力。他们的预测,往往会被投资者视为风向标,从而影响他们的投资决策。\n\n那么,卓创资讯的预测,到底是基于客观分析,还是受到了某些利益集团的指使?我们不得而知。\n\n但有一点可以肯定的是,在这个充满利益纠葛的市场里,任何信息都不能完全相信。我们必须保持独立思考,做出自己的判断。\n\n不要被那些所谓的“专家”、“分析师”牵着鼻子走,更不要盲目跟风,成为别人的炮灰。只有这样,我们才能在这个残酷的市场里生存下去,并最终获得胜利。\n\n[ ](https://www.facebook.com/sharer.php?url=https://www.ethinvestmentlab.com/archives/8211) [ ](http://twitter.com/share?url=https://www.ethinvestmentlab.com/archives/8211&text=%E8%B1%86%E7%B2%95%E5%B4%A9%E7%9B%98%E6%83%8A%E5%A4%A9%E5%86%85%E5%B9%95%EF%BC%9A%E8%B0%81%E5%9C%A8%E8%83%8C%E5%90%8E%E6%93%8D%E7%9B%98%EF%BC%9F) [ ](https://www.linkedin.com/sharing/share-offsite/?url=https://www.ethinvestmentlab.com/archives/8211&title=%E8%B1%86%E7%B2%95%E5%B4%A9%E7%9B%98%E6%83%8A%E5%A4%A9%E5%86%85%E5%B9%95%EF%BC%9A%E8%B0%81%E5%9C%A8%E8%83%8C%E5%90%8E%E6%93%8D%E7%9B%98%EF%BC%9F) [ ](javascript:pinIt\\(\\);) [ ](https://t.me/share/url?url=https://www.ethinvestmentlab.com/archives/8211&title=%E8%B1%86%E7%B2%95%E5%B4%A9%E7%9B%98%E6%83%8A%E5%A4%A9%E5%86%85%E5%B9%95%EF%BC%9A%E8%B0%81%E5%9C%A8%E8%83%8C%E5%90%8E%E6%93%8D%E7%9B%98%EF%BC%9F) [ ](https://api.whatsapp.com/send?text=https://www.ethinvestmentlab.com/archives/8211&title=%E8%B1%86%E7%B2%95%E5%B4%A9%E7%9B%98%E6%83%8A%E5%A4%A9%E5%86%85%E5%B9%95%EF%BC%9A%E8%B0%81%E5%9C%A8%E8%83%8C%E5%90%8E%E6%93%8D%E7%9B%98%EF%BC%9F) [ ](https://www.reddit.com/submit?url=https://www.ethinvestmentlab.com/archives/8211&title=%E8%B1%86%E7%B2%95%E5%B4%A9%E7%9B%98%E6%83%8A%E5%A4%A9%E5%86%85%E5%B9%95%EF%BC%9A%E8%B0%81%E5%9C%A8%E8%83%8C%E5%90%8E%E6%93%8D%E7%9B%98%EF%BC%9F) [ ](javascript:window.print\\(\\))\n\n## 文章导航\n\n[ 苹果AI大跃进?隐私乌托邦的惊天骗局!](https://www.ethinvestmentlab.com/archives/8209)\n\n[《青春有我,钱包空空?佳能超广角“青春镜”背后的残酷真相》 ](https://www.ethinvestmentlab.com/archives/8213)\n", + "files": [], + "json": [] +} \ No newline at end of file diff --git a/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/获取网页内容.txt b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/获取网页内容.txt new file mode 100644 index 0000000..0142de9 --- /dev/null +++ b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/获取网页内容.txt @@ -0,0 +1,5 @@ +{ + "text": "[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [豆粕崩盘惊天内幕:谁在背后操盘?](https://www.ethinvestmentlab.com/archives/8211)\n\n豆粕基差崩盘:一场心照不宣的博...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [4 月 2, 2025](https://www.ethinvestmentlab.com/archives/date/2025/04)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [币圈大地震!IMF一锤定音:你的币,要凉?](https://www.ethinvestmentlab.com/archives/8198)\n\n虛擬貨幣:貨幣、商品還是待宰的...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 31, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [GameStop 豪赌比特币:是自救还是加速死亡?](https://www.ethinvestmentlab.com/archives/8194)\n\nGameStop 豪賭比特幣:...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 31, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [警惕!你的新能源车正在变成“定时炸弹”?](https://www.ethinvestmentlab.com/archives/8166)\n\n新能源汽车动力电池回收利用:潜...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 29, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[](https://www.ethinvestmentlab.com/archives/8151)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [突发!金市老王泄露3.24黄金暴富秘籍,错过血亏!](https://www.ethinvestmentlab.com/archives/8151)\n\n黄金交易的长期获利之道:老王3...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 28, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [金价末日狂欢?89天生死劫,传奇预言一语惊天!](https://www.ethinvestmentlab.com/archives/8137)\n\n金界传奇:黄金变盘时间窗口已至...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 26, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[](https://www.ethinvestmentlab.com/archives/8112)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [以太坊崩盘倒计时?专家警告:2024下半年或血流成河!](https://www.ethinvestmentlab.com/archives/8112)\n\n以太坊面临挑战:超卖与下跌风险...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 24, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[](https://www.ethinvestmentlab.com/archives/8106)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [《疯了!黄金冲破3000,还能涨到天上去?万锦晟紧急预警!》](https://www.ethinvestmentlab.com/archives/8106)\n\n引言:当前金价走势回顾与问题提...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 23, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [😱 没办转院手续?99%的人都不知道的保命绝招!](https://www.ethinvestmentlab.com/archives/8088)\n\n未办理转院手续的困境与应对 未...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 21, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n\n[](https://www.ethinvestmentlab.com/archives/8076)\n\n[ 加密资产分析 ](https://www.ethinvestmentlab.com/archives/category/%e5%8a%a0%e5%af%86%e8%b5%84%e4%ba%a7%e5%88%86%e6%9e%90)\n\n#### [樓市真相:99%的人都忽略的買房潛規則!](https://www.ethinvestmentlab.com/archives/8076)\n\n房產項目質量評估:全方位指南 ...\n\n[ ![](https://secure.gravatar.com/avatar/e8f82a489c84d4a85fedd072aa9a5616?s=150&d=identicon&r=g)Wolfgang ](https://www.ethinvestmentlab.com/archives/author/wolfgang) [3 月 19, 2025](https://www.ethinvestmentlab.com/archives/date/2025/03)\n", + "files": [], + "json": [] +} \ No newline at end of file diff --git a/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md new file mode 100644 index 0000000..167b577 --- /dev/null +++ b/0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md @@ -0,0 +1,6 @@ +这篇文章揭露了豆粕市场崩盘背后的资本博弈和行业乱象,核心内容包括: +1. **资本操控**:豆粕价格暴跌并非单纯市场供需所致,而是压榨巨头和饲料企业为争夺定价权进行的资本博弈,散户成为牺牲品。 +1. **需求疲软假象**:所谓的“需求疲软”实则是饲料企业为保利润调整配方,减少豆粕用量,而养殖户因成本上升和猪周期下行遭受重创。 +1. **开工率谎言**:压榨企业通过“停机检修”人为控制供应,制造紧张假象以操纵价格,同时过度依赖进口大豆威胁国内农业生态和产业安全。 +2. **库存猫腻**:“缺豆不缺粕”的异常现象暗示压榨企业和贸易商囤积居奇,通过信息不对称和低买高卖剥削散户。 +1. **未来预测争议**:卓创资讯对4月豆粕价格走势的预测被质疑可能受利益集团影响,提醒投资者保持独立判断,警惕市场陷阱。 \ No newline at end of file diff --git a/0-部署应用/Oracle-Cloud/将内存挂载为硬盘.sh b/0-部署应用/Oracle-Cloud/将内存挂载为硬盘.sh index 4f835b5..1d2d681 100644 --- a/0-部署应用/Oracle-Cloud/将内存挂载为硬盘.sh +++ b/0-部署应用/Oracle-Cloud/将内存挂载为硬盘.sh @@ -1,7 +1,7 @@ #!/bin/bash # 1GB 1048576 5G 1048576 8G 8388608 -sudo modprobe brd rd_nr=1 rd_size=8388608 max_part=1 +sudo modprobe brd rd_nr=1 rd_size=1048576 max_part=1 sudo mkfs.ext4 /dev/ram0 diff --git a/0-部署应用/Oracle-Cloud/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml b/0-部署应用/Oracle-Cloud/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml index 54e9f92..9557602 100644 --- a/0-部署应用/Oracle-Cloud/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml +++ b/0-部署应用/Oracle-Cloud/自建代码仓库-gitea/gitea-bitnami-docker-compose.yaml @@ -5,7 +5,7 @@ services: postgresql: image: docker.io/bitnami/postgresql:15 volumes: - - '/data/gitea/postgresql_data/:/bitnami/postgresql' + - '/var/lib/docker/wdd/gitea/postgresql_data/:/bitnami/postgresql' environment: - POSTGRESQL_DATABASE=gitea_db - POSTGRESQL_USERNAME=bn_gitea @@ -14,7 +14,7 @@ services: gitea: image: docker.io/bitnami/gitea:1.19.3-debian-11-r0 volumes: - - '/data/gitea/gitea_data:/bitnami/gitea' + - '/var/lib/docker/wdd/gitea/gitea_data:/bitnami/gitea' environment: - GITEA_DATABASE_HOST=postgresql - GITEA_DATABASE_NAME=gitea_db @@ -26,7 +26,7 @@ services: - GITEA_HTTP_PORT=3000 - GITEA_SSH_LISTEN_PORT=22222 - GITEA_APP_NAME=Gitea-闲下来就喝杯茶吧 - - GITEA_DOMAIN=192.168.35.70 + - GITEA_DOMAIN=192.168.35.80 - GITEA_PROTOCOL=http - GITEA_RUN_MODE=prod ports: diff --git a/0-部署应用/Phoneix-arm64-01/AI-Dify/docker-compose-modified.yaml b/0-部署应用/Phoneix-arm64-01/AI-Dify/docker-compose-modified.yaml index 53234bf..a752e39 100644 --- a/0-部署应用/Phoneix-arm64-01/AI-Dify/docker-compose-modified.yaml +++ b/0-部署应用/Phoneix-arm64-01/AI-Dify/docker-compose-modified.yaml @@ -410,11 +410,14 @@ x-shared-env: &shared-api-worker-env MARKETPLACE_ENABLED: ${MARKETPLACE_ENABLED:-true} MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai} FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true} + PLUGIN_PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120} + PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600} + PIP_MIRROR_URL: ${PIP_MIRROR_URL:-} services: # API service api: - image: langgenius/dify-api:0.15.3 + image: langgenius/dify-api:1.1.3 restart: always environment: # Use the shared environment variables. @@ -426,15 +429,19 @@ services: SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0} PLUGIN_MAX_PACKAGE_SIZE: ${PLUGIN_MAX_PACKAGE_SIZE:-52428800} INNER_API_KEY_FOR_PLUGIN: ${PLUGIN_DIFY_INNER_API_KEY:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1} + dns: + - 1.1.1.1 + - 8.8.8.8 volumes: # Mount the storage directory to the container, for storing user files. - /mnt/ramdisk/dify-api/storage:/app/api/storage + - /etc/resolv.conf:/etc/resolv.conf network_mode: "host" # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.15.3 + image: langgenius/dify-api:1.1.3 restart: always environment: # Use the shared environment variables. @@ -449,14 +456,16 @@ services: volumes: # Mount the storage directory to the container, for storing user files. - /mnt/ramdisk/dify-api/storage:/app/api/storage + - /etc/resolv.conf:/etc/resolv.conf + dns: + - 1.1.1.1 + - 8.8.8.8 network_mode: "host" # Frontend web application. web: - image: langgenius/dify-web:0.15.3 + image: langgenius/dify-web:1.1.3 restart: always - ports: - - '3000:3000' environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} APP_API_URL: ${APP_API_URL:-} @@ -468,10 +477,12 @@ services: MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai} TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-} INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-} + ports: + - 3000:3000 # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.10 + image: langgenius/dify-sandbox:0.2.11 restart: always environment: # The DifySandbox configurations @@ -486,14 +497,19 @@ services: SANDBOX_PORT: ${SANDBOX_PORT:-8194} volumes: - /mnt/ramdisk/sandbox/dependencies:/dependencies + - /etc/resolv.conf:/etc/resolv.conf + dns: + - 1.1.1.1 + - 8.8.8.8 healthcheck: test: [ 'CMD', 'curl', '-f', 'http://localhost:8194/health' ] - networks: - - default + network_mode: "host" - # plugin daemon + + + # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.0.2-local + image: langgenius/dify-plugin-daemon:0.0.6-local restart: always environment: # Use the shared environment variables. @@ -506,13 +522,19 @@ services: DIFY_INNER_API_URL: ${PLUGIN_DIFY_INNER_API_URL:-http://api:5001} DIFY_INNER_API_KEY: ${INNER_API_KEY_FOR_PLUGIN:-QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1} PLUGIN_REMOTE_INSTALLING_HOST: ${PLUGIN_REMOTE_INSTALL_HOST:-0.0.0.0} - PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_REMOTE_INSTALL_PORT:-5003} + PLUGIN_REMOTE_INSTALLING_PORT: ${PLUGIN_REMOTE_INSTALL_PORT:-5002} PLUGIN_WORKING_PATH: ${PLUGIN_WORKING_PATH:-/app/storage/cwd} FORCE_VERIFYING_SIGNATURE: ${FORCE_VERIFYING_SIGNATURE:-true} - ports: - - "${EXPOSE_PLUGIN_DEBUGGING_PORT:-5003}:${PLUGIN_DEBUGGING_PORT:-5003}" + PLUGIN_PYTHON_ENV_INIT_TIMEOUT: ${PLUGIN_PYTHON_ENV_INIT_TIMEOUT:-120} + PLUGIN_MAX_EXECUTION_TIMEOUT: ${PLUGIN_MAX_EXECUTION_TIMEOUT:-600} + PIP_MIRROR_URL: ${PIP_MIRROR_URL:-} + network_mode: "host" volumes: - /mnt/ramdisk/plugin_daemon:/app/storage + - /etc/resolv.conf:/etc/resolv.conf + dns: + - 1.1.1.1 + - 8.8.8.8 # ssrf_proxy server diff --git a/0-部署应用/Phoneix-arm64-01/AI-Dify/设置的环境.env b/0-部署应用/Phoneix-arm64-01/AI-Dify/设置的环境.env index 54a4643..1581f92 100644 --- a/0-部署应用/Phoneix-arm64-01/AI-Dify/设置的环境.env +++ b/0-部署应用/Phoneix-arm64-01/AI-Dify/设置的环境.env @@ -591,10 +591,12 @@ WORKFLOW_FILE_UPLOAD_LIMIT=10 HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760 HTTP_REQUEST_NODE_MAX_TEXT_SIZE=1048576 +# 指向 Amd64-02 +#SSRF_PROXY_ALL_URL=socks5://10.0.0.246:2234 # SSRF Proxy server HTTP URL -SSRF_PROXY_HTTP_URL=http://ssrf_proxy:3128 +SSRF_PROXY_HTTP_URL=http://10.0.0.246:1234 # SSRF Proxy server HTTPS URL -SSRF_PROXY_HTTPS_URL=http://ssrf_proxy:3128 +SSRF_PROXY_HTTPS_URL=http://10.0.0.246:2234 # ------------------------------ # Environment Variables for web Service @@ -716,7 +718,7 @@ DB_PLUGIN_DATABASE=dify_plugin EXPOSE_PLUGIN_DAEMON_PORT=5002 PLUGIN_DAEMON_PORT=5002 PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi -PLUGIN_DAEMON_URL=http://plugin_daemon:5002 +PLUGIN_DAEMON_URL=http://10.0.0.12:5002 PLUGIN_MAX_PACKAGE_SIZE=52428800 PLUGIN_PPROF_ENABLED=false @@ -726,7 +728,7 @@ EXPOSE_PLUGIN_DEBUGGING_HOST=localhost EXPOSE_PLUGIN_DEBUGGING_PORT=5003 PLUGIN_DIFY_INNER_API_KEY=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1 -PLUGIN_DIFY_INNER_API_URL=http://api:5001 +PLUGIN_DIFY_INNER_API_URL=http://10.0.0.12:5001 ENDPOINT_URL_TEMPLATE=http://localhost/e/{hook_id} @@ -734,3 +736,8 @@ MARKETPLACE_ENABLED=true MARKETPLACE_API_URL=https://marketplace.dify.ai FORCE_VERIFYING_SIGNATURE=true + +PLUGIN_PYTHON_ENV_INIT_TIMEOUT=120 +PLUGIN_MAX_EXECUTION_TIMEOUT=600 +# PIP_MIRROR_URL=https://pypi.tuna.tsinghua.edu.cn/simple +PIP_MIRROR_URL= diff --git a/0-部署应用/Phoneix-arm64-02/AI-Dify/docker-compose-modified.yaml b/0-部署应用/Phoneix-arm64-02/AI-Dify/docker-compose-modified.yaml index 452b234..3c390ff 100644 --- a/0-部署应用/Phoneix-arm64-02/AI-Dify/docker-compose-modified.yaml +++ b/0-部署应用/Phoneix-arm64-02/AI-Dify/docker-compose-modified.yaml @@ -52,8 +52,18 @@ services: AUTHORIZATION_ADMINLIST_USERS: ${WEAVIATE_AUTHORIZATION_ADMINLIST_USERS:-hello@dify.ai} ports: - 8080:8080 - - - - + redis: + image: redis:6-alpine + restart: always + environment: + REDISCLI_AUTH: ${REDIS_PASSWORD:-V2rayStrP@ss} + volumes: + # Mount the redis data directory to the container. + - /mnt/ramdisk/redis/data:/data + # Set the redis password when startup redis server. + command: redis-server --requirepass ${REDIS_PASSWORD:-V2rayStrP@ss} + healthcheck: + test: [ 'CMD', 'redis-cli', 'ping' ] + ports: + - 6379:6379 diff --git a/0-部署应用/证书申请/证书申请模板.sh b/0-部署应用/证书申请/证书申请模板.sh index 5d41a63..42cda6d 100644 --- a/0-部署应用/证书申请/证书申请模板.sh +++ b/0-部署应用/证书申请/证书申请模板.sh @@ -1,8 +1,14 @@ #!/bin/bash + +curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \ + -H "Authorization: Bearer T7LxBemfe8SNGWkT9uz2XIc1e22ifAbBv_POJvDP" \ + -H "Content-Type:application/json" + #export DOMAIN_NAME=chat.107421.xyz export DOMAIN_NAME=push.107421.xyz +# 可以操作DNS的API Token export CF_Token="oXJRP5XI8Zhipa_PtYtB_jy6qWL0I9BosrJEYE8p" export CF_Account_ID="dfaadeb83406ef5ad35da02617af9191" export CF_Zone_ID="511894a4f1357feb905e974e16241ebb" diff --git a/1-代理Xray/0-香港节点/0-xtls-reality的配置.json b/1-代理Xray/0-香港节点/0-xtls-reality的配置.json deleted file mode 100644 index e24610b..0000000 --- a/1-代理Xray/0-香港节点/0-xtls-reality的配置.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "listen": "0.0.0.0", - "port": 29999, - "protocol": "vless", - "settings": { - "clients": [ - { - "id": "RoMoH00dOl3zaQjdUKB6W0SS-wDYENgI3I7cREYwp1M", - "flow": "xtls-rprx-vision" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "tcp", - "security": "reality", - "realitySettings": { - "dest": "speed.cloudflare.com", - "serverNames": [ - "speed.cloudflare.com" - ], - "privateKey": "yNsDptp-3i-KqhLHA-RBLrVlJuiYeDUekirp-fkerQA", - "shortIds": [ - "abc124cc", - "666asdcd" - ] - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls", - "quic" - ], - "routeOnly": true - } - } -} \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/0-基础原生配置.json b/1-代理Xray/0-香港节点/0-基础原生配置.json new file mode 100644 index 0000000..566add5 --- /dev/null +++ b/1-代理Xray/0-香港节点/0-基础原生配置.json @@ -0,0 +1,82 @@ +{ + "log": { + "loglevel": "info" + }, + "inbounds": [ + { + "port": 24443, + "protocol": "vless", + "tag": "proxy", + "settings": { + "clients": [ + { + "id": "f8702759-f402-4e85-92a6-8540d577de22", + "flow": "xtls-rprx-vision", + "email": "cc@vless.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "proxy" + } + ], + "routing": { + "domainStrategy": "AsIs", + "domainMatcher": "hybrid", + "rules": [ + { + "type": "field", + "inboundTag": [ + "proxy" + ], + "outboundTag": "proxy" + } + ] + } + } \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json b/1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json new file mode 100644 index 0000000..9a52416 --- /dev/null +++ b/1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json @@ -0,0 +1,84 @@ +{ + "inbounds": [ + { + "port": 24444, + "protocol": "vless", + "tag": "fv-ge-frk", + "settings": { + "clients": [ + { + "id": "6055eac4-dee7-463b-b575-d30ea94bb768", + "flow": "xtls-rprx-vision", + "email": "franklin@vless.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fv-ge-frk", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "de-01.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fv-ge-frk" + ], + "outboundTag": "fv-ge-frk" + } + ] + } +} \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/2-FV-韩国-首尔.json b/1-代理Xray/0-香港节点/2-FV-韩国-首尔.json new file mode 100644 index 0000000..6c0c896 --- /dev/null +++ b/1-代理Xray/0-香港节点/2-FV-韩国-首尔.json @@ -0,0 +1,84 @@ +{ + "inbounds": [ + { + "port": 24445, + "protocol": "vless", + "tag": "fv-kr-sel", + "settings": { + "clients": [ + { + "id": "1cd284b2-d3d8-4165-b773-893f836c2b51", + "flow": "xtls-rprx-vision", + "email": "seoul@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fv-kr-sel", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "kr.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fv-kr-sel" + ], + "outboundTag": "fv-kr-sel" + } + ] + } +} \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/3-FV-日本-东京.json b/1-代理Xray/0-香港节点/3-FV-日本-东京.json new file mode 100644 index 0000000..621a1cf --- /dev/null +++ b/1-代理Xray/0-香港节点/3-FV-日本-东京.json @@ -0,0 +1,84 @@ +{ + "inbounds": [ + { + "port": 24446, + "protocol": "vless", + "tag": "fv-jp-tyk", + "settings": { + "clients": [ + { + "id": "bf0e9c35-84a9-460e-b5bf-2fa9f2fb3bca", + "flow": "xtls-rprx-vision", + "email": "seoul@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fv-jp-tyk", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "jpjp.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fv-jp-tyk" + ], + "outboundTag": "fv-jp-tyk" + } + ] + } + } \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/4-FV-英国-伦敦.json b/1-代理Xray/0-香港节点/4-FV-英国-伦敦.json new file mode 100644 index 0000000..cfd115c --- /dev/null +++ b/1-代理Xray/0-香港节点/4-FV-英国-伦敦.json @@ -0,0 +1,85 @@ +{ + "inbounds": [ + { + "port": 24447, + "protocol": "vless", + "tag": "fv-uk-lon", + "settings": { + "clients": [ + { + "id": "adc19390-373d-4dfc-b0f6-19fab1b6fbf6", + "flow": "xtls-rprx-vision", + "email": "london@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fv-uk-lon", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "uk-02.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fv-uk-lon" + ], + "outboundTag": "fv-uk-lon" + } + ] + } + } + \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/5-FV-新加坡.json b/1-代理Xray/0-香港节点/5-FV-新加坡.json new file mode 100644 index 0000000..4a07cb7 --- /dev/null +++ b/1-代理Xray/0-香港节点/5-FV-新加坡.json @@ -0,0 +1,85 @@ +{ + "inbounds": [ + { + "port": 24448, + "protocol": "vless", + "tag": "fv-sgp", + "settings": { + "clients": [ + { + "id": "e31bc28e-8ebd-4d72-a98e-9227f26dfac3", + "flow": "xtls-rprx-vision", + "email": "singapore@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fv-sgp", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "sg-01.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fv-sgp" + ], + "outboundTag": "fv-sgp" + } + ] + } + } + \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/6-FV-香港.json b/1-代理Xray/0-香港节点/6-FV-香港.json new file mode 100644 index 0000000..c92973d --- /dev/null +++ b/1-代理Xray/0-香港节点/6-FV-香港.json @@ -0,0 +1,85 @@ +{ + "inbounds": [ + { + "port": 24452, + "protocol": "vless", + "tag": "fastestvpm-hongkong", + "settings": { + "clients": [ + { + "id": "cdf0b19a-9524-48d5-b697-5f10bb567734", + "flow": "xtls-rprx-vision", + "email": "hongkong@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "wireguard", + "tag": "fastestvpm-hongkong", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": ["172.16.145.79/32"], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "hk.jumptoserver.com:51820" + } + ] + } + } + ], + "routing": { + "rules": [ + { + "type": "field", + "inboundTag": [ + "fastestvpm-hongkong" + ], + "outboundTag": "fastestvpm-hongkong" + } + ] + } + } + \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/9-Vless组合配置.json b/1-代理Xray/0-香港节点/9-Vless组合配置.json new file mode 100644 index 0000000..c08484c --- /dev/null +++ b/1-代理Xray/0-香港节点/9-Vless组合配置.json @@ -0,0 +1,861 @@ +{ + "log": { + "loglevel": "error" + }, + "inbounds": [ + { + "port": 24443, + "protocol": "vless", + "tag": "proxy", + "settings": { + "clients": [ + { + "id": "f8702759-f402-4e85-92a6-8540d577de22", + "flow": "xtls-rprx-vision", + "email": "cc@vless.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24444, + "protocol": "vless", + "tag": "fv-ge-frk", + "settings": { + "clients": [ + { + "id": "6055eac4-dee7-463b-b575-d30ea94bb768", + "flow": "xtls-rprx-vision", + "email": "franklin@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24445, + "protocol": "vless", + "tag": "fv-kr-sel", + "settings": { + "clients": [ + { + "id": "1cd284b2-d3d8-4165-b773-893f836c2b51", + "flow": "xtls-rprx-vision", + "email": "seoul@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24446, + "protocol": "vless", + "tag": "fv-jp-tyk", + "settings": { + "clients": [ + { + "id": "bf0e9c35-84a9-460e-b5bf-2fa9f2fb3bca", + "flow": "xtls-rprx-vision", + "email": "tokyo@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24447, + "protocol": "vless", + "tag": "fv-uk-lon", + "settings": { + "clients": [ + { + "id": "adc19390-373d-4dfc-b0f6-19fab1b6fbf6", + "flow": "xtls-rprx-vision", + "email": "london@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24448, + "protocol": "vless", + "tag": "fv-sgp", + "settings": { + "clients": [ + { + "id": "e31bc28e-8ebd-4d72-a98e-9227f26dfac3", + "flow": "xtls-rprx-vision", + "email": "singapore@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24449, + "protocol": "vless", + "tag": "oracle-seoul-amd04", + "settings": { + "clients": [ + { + "id": "7e27da0c-3013-4ed4-817b-50cc76a0bf81", + "flow": "xtls-rprx-vision", + "email": "seoul@oracle.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24450, + "protocol": "vless", + "tag": "fv-usa-losangles", + "settings": { + "clients": [ + { + "id": "56fb312c-bdb0-48ca-bf66-4a2dd34040c6", + "flow": "xtls-rprx-vision", + "email": "losangles@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24451, + "protocol": "vless", + "tag": "care-germany-dusseldorf", + "settings": { + "clients": [ + { + "id": "9fa9b4e7-d76d-4890-92cf-ce9251a76f59", + "flow": "xtls-rprx-vision", + "email": "dusseldorf@care.io", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24452, + "protocol": "vless", + "tag": "fastestvpn-hongkong", + "settings": { + "clients": [ + { + "id": "cdf0b19a-9524-48d5-b697-5f10bb567734", + "flow": "xtls-rprx-vision", + "email": "hongkong@fastestvpn.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + }, + { + "port": 24453, + "protocol": "vless", + "tag": "cloudflare-hongkong", + "settings": { + "clients": [ + { + "id": "93be1d17-8e02-449d-bb99-683ed46fbe50", + "flow": "xtls-rprx-vision", + "email": "hongkong@cloudflare.com", + "level": 0 + } + ], + "decryption": "none", + "fallbacks": [ + { + "dest": "/dev/shm/h2c.sock", + "xver": 2, + "alpn": "h2" + }, + { + "dest": "/dev/shm/h1.sock", + "xver": 2 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "certificates": [ + { + "ocspStapling": 3600, + "certificateFile": "/root/.acme.sh/book.107421.xyz_ecc/fullchain.cer", + "keyFile": "/root/.acme.sh/book.107421.xyz_ecc/book.107421.xyz.key" + } + ], + "minVersion": "1.2", + "cipherSuites": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "alpn": [ + "h2", + "http/1.1" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls" + ] + } + } + ], + "outbounds": [ + { + "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "proxy" + }, + { + "protocol": "wireguard", + "tag": "fv-ge-frk", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "de-01.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fv-kr-sel", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "kr.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fv-jp-tyk", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "jpjp.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fv-uk-lon", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "uk-02.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fv-sgp", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "sg-pro.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fv-usa-losangles", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "us-la-pro.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "wireguard", + "tag": "fastestvpn-hongkong", + "settings": { + "secretKey": "2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY=", + "address": [ + "172.16.145.79/32" + ], + "peers": [ + { + "publicKey": "658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0=", + "endpoint": "hk.jumptoserver.com:51820" + } + ] + } + }, + { + "protocol": "socks", + "tag": "cloudflare-hongkong", + "settings":{ + "servers": [ + { + "address": "127.0.0.1", + "port": 7990, + "level": 0 + } + ] + } + }, + { + "protocol": "vless", + "tag": "oracle-seoul-amd04", + "settings": { + "vnext": [ + { + "address": "140.238.14.103", + "port": 443, + "users": [ + { + "id": "1089cc14-557e-47ac-ac85-c07957b3cce3", + "encryption": "none", + "flow": "xtls-rprx-vision", + "level": 0 + } + ] + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "xx.s4.cc.hh.107421.xyz" + } + } + }, + { + "protocol": "vless", + "tag": "care-germany-dusseldorf", + "settings": { + "vnext": [ + { + "address": "45.134.50.233", + "port": 443, + "users": [ + { + "id": "b1417d92-998d-410b-a5f3-cf144b6f043e", + "encryption": "none", + "flow": "xtls-rprx-vision", + "level": 0 + } + ] + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "serverName": "bingo.107421.xyz" + } + } + } + ], + "routing": { + "domainStrategy": "AsIs", + "domainMatcher": "hybrid", + "rules": [ + { + "type": "field", + "inboundTag": [ + "proxy" + ], + "outboundTag": "proxy" + }, + { + "type": "field", + "inboundTag": [ + "cloudflare-hongkong" + ], + "outboundTag": "cloudflare-hongkong" + }, + { + "type": "field", + "inboundTag": [ + "fv-ge-frk" + ], + "outboundTag": "fv-ge-frk" + }, + { + "type": "field", + "inboundTag": [ + "fv-kr-sel" + ], + "outboundTag": "fv-kr-sel" + }, + { + "type": "field", + "inboundTag": [ + "fv-jp-tyk" + ], + "outboundTag": "fv-jp-tyk" + }, + { + "type": "field", + "inboundTag": [ + "fv-uk-lon" + ], + "outboundTag": "fv-uk-lon" + }, + { + "type": "field", + "inboundTag": [ + "fv-sgp" + ], + "outboundTag": "fv-sgp" + }, + { + "type": "field", + "inboundTag": [ + "fv-usa-losangles" + ], + "outboundTag": "fv-usa-losangles" + }, + { + "type": "field", + "inboundTag": [ + "fastestvpn-hongkong" + ], + "outboundTag": "fastestvpn-hongkong" + }, + { + "type": "field", + "inboundTag": [ + "oracle-seoul-amd04" + ], + "outboundTag": "oracle-seoul-amd04" + }, + { + "type": "field", + "inboundTag": [ + "care-germany-dusseldorf" + ], + "outboundTag": "care-germany-dusseldorf" + } + ] + } +} \ No newline at end of file diff --git a/1-代理Xray/0-香港节点/0-分层代理回落.json b/1-代理Xray/0-香港节点/9-汇总+fvpn的配置-失败.json similarity index 82% rename from 1-代理Xray/0-香港节点/0-分层代理回落.json rename to 1-代理Xray/0-香港节点/9-汇总+fvpn的配置-失败.json index 10495df..a543959 100644 --- a/1-代理Xray/0-香港节点/0-分层代理回落.json +++ b/1-代理Xray/0-香港节点/9-汇总+fvpn的配置-失败.json @@ -6,6 +6,7 @@ { "port": 24443, "protocol": "vless", + "tag": "proxy", "settings": { "clients": [ { @@ -59,6 +60,23 @@ "outbounds": [ { "protocol": "freedom" + }, + { + "protocol": "freedom", + "tag": "proxy" } - ] + ], + "routing": { + "domainStrategy": "AsIs", + "domainMatcher": "hybrid", + "rules": [ + { + "type": "field", + "inboundTag": [ + "proxy" + ], + "outboundTag": "proxy" + } + ] + } } \ No newline at end of file diff --git a/1-代理Xray/4-凤凰城-amd02节点/普通代理.json b/1-代理Xray/4-凤凰城-amd02节点/普通代理.json new file mode 100644 index 0000000..f10c335 --- /dev/null +++ b/1-代理Xray/4-凤凰城-amd02节点/普通代理.json @@ -0,0 +1,72 @@ +{ + "inbounds": [ + { + "protocol": "http", + "port": 2234, + "listen": "0.0.0.0", + "tag": "proxy-http" + }, + { + "tag": "proxy", + "protocol": "socks", + "listen": "0.0.0.0", + "port": 1234, + "settings": { + "auth": "noauth", + "udp": true, + "ip": "127.0.0.1", + "userLevel": 0 + } + }, + { + "protocol": "socks", + "tag": "cloudflare", + "listen": "0.0.0.0", + "port": 1235, + "settings": { + "auth": "noauth", + "udp": true, + "userLevel": 0 + } + } + ], + "outbounds": [ + { + "tag": "cloudflare", + "protocol": "socks", + "settings": { + "servers": [ + { + "address": "127.0.0.1", + "port": 40000, + "level": 0 + } + ] + } + }, + { + "tag": "proxy", + "protocol": "freedom" + } + ], + "routing": { + "domainStrategy": "IPIfNonMatch", + "rules": [ + { + "type": "field", + "inboundTag": [ + "cloudflare", + "proxy-http" + ], + "outboundTag": "cloudflare" + }, + { + "type": "field", + "inboundTag": [ + "proxy" + ], + "outboundTag": "proxy" + } + ] + } +} \ No newline at end of file diff --git a/1-代理Xray/98-subscribe-clash.yaml b/1-代理Xray/98-subscribe-clash.yaml index a25c14d..ef85737 100644 --- a/1-代理Xray/98-subscribe-clash.yaml +++ b/1-代理Xray/98-subscribe-clash.yaml @@ -53,40 +53,260 @@ dns: '+.ops.uavcmlc.com': '192.168.34.40' proxies: - - {"type":"vmess","name":"us-central-free","ws-opts":{"path":"/vmess"},"server":"northflank.107421.xyz","port":443,"uuid":"de04add9-5c68-8bab-950c-08cd5320df18","alterId":0,"cipher":"auto","network":"ws","tls":true} + + - type: vless + name: TC-HongKong + server: 43.154.83.213 + port: 24443 + uuid: f8702759-f402-4e85-92a6-8540d577de22 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: CF-HongKong-R-TCHK + server: 43.154.83.213 + port: 24453 + uuid: 93be1d17-8e02-449d-bb99-683ed46fbe50 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-HongKong + server: 43.154.83.213 + port: 24452 + uuid: cdf0b19a-9524-48d5-b697-5f10bb567734 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: Care-DEU-Dusseldorf-R-TCHK + server: 43.154.83.213 + port: 24451 + uuid: 9fa9b4e7-d76d-4890-92cf-ce9251a76f59 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: Care-DEU-Dusseldorf + server: 45.134.50.233 + port: 443 + uuid: b1417d92-998d-410b-a5f3-cf144b6f043e + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: bingo.107421.xyz + tls: true + udp: true + + - type: vless + name: Oracle-KOR-Seoul + server: 140.238.14.103 + port: 443 + uuid: 1089cc14-557e-47ac-ac85-c07957b3cce3 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: xx.s4.cc.hh.107421.xyz + tls: true + udp: true + + - name: CF_VIDEO_1 + type: vless + server: bingo.pp.icederce.ip-ddns.com + port: 8443 + uuid: 86c50e3a-5b87-49dd-bd20-03c7f2735e40 + udp: false + tls: true + network: ws + servername: pp.icederce.ip-ddns.com + ws-opts: + path: "/?ed=2560" + headers: + Host: pp.icederce.ip-ddns.com + + - name: CF_VIDEO_2 + type: vless + server: bingo.icederce.ip-ddns.com + port: 8443 + uuid: 86c50e3a-5b87-49dd-bd20-03c7f2735e40 + udp: false + tls: true + network: ws + servername: pp.icederce.ip-ddns.com + ws-opts: + path: "/?ed=2560" + headers: + Host: pp.icederce.ip-ddns.com + + - type: vless + name: FV-DEU-Frankfurt + server: 43.154.83.213 + port: 24444 + uuid: 6055eac4-dee7-463b-b575-d30ea94bb768 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-KOR-Seoul + server: 43.154.83.213 + port: 24445 + uuid: 1cd284b2-d3d8-4165-b773-893f836c2b51 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-JPN-Tokyo + server: 43.154.83.213 + port: 24446 + uuid: bf0e9c35-84a9-460e-b5bf-2fa9f2fb3bca + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-GBR-London + server: 43.154.83.213 + port: 24447 + uuid: adc19390-373d-4dfc-b0f6-19fab1b6fbf6 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-SGP + server: 43.154.83.213 + port: 24448 + uuid: e31bc28e-8ebd-4d72-a98e-9227f26dfac3 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: Oracle-KOR-Seoul-R-TCHK + server: 43.154.83.213 + port: 24449 + uuid: 7e27da0c-3013-4ed4-817b-50cc76a0bf81 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: vless + name: FV-USA-LosAngles + server: 43.154.83.213 + port: 24450 + uuid: 56fb312c-bdb0-48ca-bf66-4a2dd34040c6 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: book.107421.xyz + tls: true + udp: true + + - type: socks5 + name: TC-CHN-Shanghai + server: 42.192.52.227 + port: 22887 + username: zeaslity + password: a1f090ea-e39c-49e7-a3be-9af26b6ce563 + udp: true + + - type: vless + name: Oracle-JPN-Tokyo-R-OSel + server: 140.238.14.103 + port: 20443 + uuid: 21dab95b-088e-47bd-8351-609fd23cb33c + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: xx.t2.ll.c0.107421.xyz + tls: true + udp: true + + - type: vless + name: Oracle-JPN-Osaka-R-OSel + server: 140.238.14.103 + port: 21443 + uuid: 4c2dd763-56e5-408f-bc8f-dbf4c1fe41f9 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: xx.o1.vl.s4.107421.xyz + tls: true + udp: true + + - type: vless + name: Oracle-USA-Phoneix-R-OSel + server: 140.238.14.103 + port: 22443 + uuid: de576486-e254-4d9d-949a-37088358ec23 + skip-cert-verify: false + network: tcp + flow: xtls-rprx-vision + servername: xx.p2.vl.s4.107421.xyz + tls: true + udp: true + - {"type":"socks5","name":"onetools-35-71","server":"192.168.35.71","port":22888,"username":"zeaslity","password":"password","udp":true} - - {"type":"socks5","name":"TC-SH","server":"42.192.52.227","port":22887,"username":"zeaslity","password":"a1f090ea-e39c-49e7-a3be-9af26b6ce563","udp":true} - - {"type":"socks5","name":"TC-SH-LosA-BanH","server":"42.192.52.227","port":22888,"username":"zeaslity","password":"a1f090ea-e39c-49e7-a3be-9af26b6ce563","udp":true} - - {"type":"socks5","name":"TC-SH-Germany","server":"42.192.52.227","port":22889,"username":"zeaslity","password":"a1f090ea-e39c-49e7-a3be-9af26b6ce563","udp":true} - - {"type":"vless","name":"TC-HK-Vless","server":"43.154.83.213","port":24443,"uuid":"f8702759-f402-4e85-92a6-8540d577de22","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"book.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Care-Germany-Vless","server":"45.134.50.233","port":443,"uuid":"b1417d92-998d-410b-a5f3-cf144b6f043e","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"bingo.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Oracle-Seoul-ARM01-Vless","server":"132.145.87.10","port":443,"uuid":"1089cc14-557e-47ac-ac85-c07957b3cce3","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"xx.s0.yy.ac.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Oracle-Seoul-Vless","server":"140.238.14.103","port":443,"uuid":"1089cc14-557e-47ac-ac85-c07957b3cce3","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"xx.s4.cc.hh.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"BanH-LosA-Vless","server":"89.208.251.209","port":443,"uuid":"0c5741d0-76a9-4945-9c1d-14647afcce24","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"octopus.107421.xyz","tls":true,"udp":true} - - {"type":"trojan","name":"BanH-LosA-Trojan","server":"89.208.251.209","port":443,"password":"Vad3.123acasd-1234-as.dAsd.asdazzS.123","udp":true,"skip-cert-verify":false,"sni":"xx.l4.cc.nn.107421.xyz","network":"h2","ws-opts":{"path":"status","headers":{"host":"xx.l4.cc.nn.107421.xyz"}}} - - {"type":"vless","name":"Oracle-Tokyo-By-Seoul-Vless","server":"140.238.14.103","port":20443,"uuid":"21dab95b-088e-47bd-8351-609fd23cb33c","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"xx.t2.ll.c0.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Oracle-Osaka-By-Seoul-Vless","server":"140.238.14.103","port":21443,"uuid":"4c2dd763-56e5-408f-bc8f-dbf4c1fe41f9","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"xx.o1.vl.s4.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Oracle-Phoneix-By-Seoul-Vless","server":"140.238.14.103","port":22443,"uuid":"de576486-e254-4d9d-949a-37088358ec23","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"xx.p2.vl.s4.107421.xyz","tls":true,"udp":true} - - {"type":"vless","name":"Oracle-Pheonix-ARM02-Vless","server":"129.146.57.94","port":443,"uuid":"12491d80-745c-4e26-a58b-edf584afb208","skip-cert-verify":false,"network":"tcp","flow":"xtls-rprx-vision","servername":"zc.p4.cc.xx.107421.xyz","tls":true,"udp":true} + proxy-groups: - name: 🚀 节点选择 type: select proxies: - - TC-HK-Vless - - BanH-LosA-Vless - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-ARM01-Vless - - Care-Germany-Vless - - TC-SH - - TC-SH-LosA-BanH - - TC-SH-Germany - - Oracle-Seoul-Vless - - Oracle-Tokyo-By-Seoul-Vless - - Oracle-Osaka-By-Seoul-Vless - - Oracle-Phoneix-By-Seoul-Vless - - Oracle-Pheonix-ARM02-Vless - - onetools-35-71 + - TC-HongKong + - CF-HongKong-R-TCHK + - FV-HongKong + - CF_VIDEO_1 + - CF_VIDEO_2 + - Care-DEU-Dusseldorf-R-TCHK + - Oracle-KOR-Seoul-R-TCHK + - Care-DEU-Dusseldorf + - Oracle-KOR-Seoul + - FV-DEU-Frankfurt + - FV-KOR-Seoul + - FV-JPN-Tokyo + - FV-GBR-London + - FV-USA-LosAngles + - FV-SGP + - Oracle-JPN-Tokyo-R-OSel + - Oracle-JPN-Osaka-R-OSel + - Oracle-USA-Phoneix-R-OSel + - TC-CHN-Shanghai - ♻️ 自动选择 - DIRECT - name: ♻️ 自动选择 @@ -95,74 +315,55 @@ proxy-groups: interval: 300 tolerance: 50 proxies: - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-Vless - - Oracle-Seoul-ARM01-Vless - - Care-Germany-Vless - - Oracle-Tokyo-By-Seoul-Vless - - Oracle-Osaka-By-Seoul-Vless - - Oracle-Phoneix-By-Seoul-Vless - - Oracle-Pheonix-ARM02-Vless - - BanH-LosA-Vless - - TC-HK-Vless - - TC-SH-LosA-BanH + - TC-HongKong + - Oracle-KOR-Seoul + - Care-DEU-Dusseldorf + - Oracle-JPN-Tokyo-R-OSel + - Oracle-JPN-Osaka-R-OSel + - Oracle-USA-Phoneix-R-OSel - name: 🌍 国外媒体 type: select proxies: - 🚀 节点选择 - ♻️ 自动选择 - 🎯 全球直连 - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-Vless - - Oracle-Seoul-ARM01-Vless - - Care-Germany-Vless - - BanH-LosA-Vless - - TC-HK-Vless - - Oracle-Tokyo-By-Seoul-Vless - - Oracle-Osaka-By-Seoul-Vless - - Oracle-Phoneix-By-Seoul-Vless - - Oracle-Pheonix-ARM02-Vless + - Oracle-KOR-Seoul + - Care-DEU-Dusseldorf + - TC-HongKong + - Oracle-JPN-Tokyo-R-OSel + - Oracle-JPN-Osaka-R-OSel + - Oracle-USA-Phoneix-R-OSel - name: 📲 电报信息 type: select proxies: - 🚀 节点选择 - - 🎯 全球直连 - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-Vless - - Oracle-Seoul-ARM01-Vless - - TC-HK-Vless + - 🎯 全球直连 + - Oracle-KOR-Seoul + - TC-HongKong - name: Ⓜ️ 微软服务 type: select proxies: - 🎯 全球直连 - 🚀 节点选择 - - BanH-LosA-Trojan - - Oracle-Seoul-Vless - - us-central-free - - Oracle-Seoul-ARM01-Vless - - TC-HK-Vless + - Oracle-KOR-Seoul + - TC-HongKong - name: 🍎 苹果服务 type: select proxies: - 🚀 节点选择 - 🎯 全球直连 - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-Vless - - Oracle-Seoul-ARM01-Vless - - TC-HK-Vless + - Oracle-KOR-Seoul + - TC-HongKong - name: 💩 工作直连 type: select proxies: - DIRECT + - onetools-35-71 - name: 💩 工作代理 type: select proxies: - - DIRECT - onetools-35-71 + - DIRECT - name: 🎯 全球直连 type: select proxies: @@ -185,12 +386,8 @@ proxy-groups: - 🚀 节点选择 - 🎯 全球直连 - ♻️ 自动选择 - - TC-HK-Vless - - BanH-LosA-Trojan - - us-central-free - - Oracle-Seoul-Vless - - Oracle-Seoul-ARM01-Vless - + - TC-HongKong + - Oracle-KOR-Seoul rules: - DOMAIN-SUFFIX,cdcyy.cn,💩 工作直连 - DOMAIN-SUFFIX,hq.cmcc,💩 工作直连 @@ -203,6 +400,7 @@ rules: - DOMAIN-SUFFIX,ip6-loopback,🎯 全球直连 - DOMAIN-SUFFIX,local,🎯 全球直连 - DOMAIN-SUFFIX,localhost,🎯 全球直连 + - DOMAIN-SUFFIX,amap.com,🎯 全球直连 - IP-CIDR,10.0.0.0/8,🎯 全球直连,no-resolve - IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolve - IP-CIDR,127.0.0.0/8,🎯 全球直连,no-resolve diff --git a/1-代理Xray/99-subscribe-octopus-latest.txt b/1-代理Xray/99-subscribe-octopus-latest.txt index 8c5a134..6a00072 100644 --- a/1-代理Xray/99-subscribe-octopus-latest.txt +++ b/1-代理Xray/99-subscribe-octopus-latest.txt @@ -1,12 +1,30 @@ -vmess://eyJ2IjoiMiIsInBzIjoidXMtY2VudGUtZnJlZSIsImFkZCI6Im5vcnRoZmxhbmsuMTA3NDIxLnh5eiIsInBvcnQiOjQ0MywiaWQiOiJkZTA0YWRkOS01YzY4LThiYWItOTUwYy0wOGNkNTMyMGRmMTgiLCJhaWQiOjAsInNjeSI6ImF1dG8iLCJuZXQiOiJ3cyIsInBhdGgiOiIvdm1lc3MiLCJ0bHMiOiJ0bHMifQ== -trojan://VaC3.123a-asd1234-asdasd.aAsDazzS.123@43.154.83.213:443?flow=xtls-rprx-vision&security=tls&sni=xx.tc.hk.go.107421.xyz&alpn=h2&fp=firefox&type=http&path=status#TC-HK-Trojan -vless://8c1b580b-c59d-4b89-b020-980fa947539f@43.154.83.213:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=book.107421.xyz&alpn=h2%2Chttp%2F1.1&fp=firefox&type=tcp&headerType=none#TC-HK-Vless -vless://b1417d92-998d-410b-a5f3-cf144b6f043e@45.134.50.233:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=bingo.107421.xyz&alpn=h2%2Chttp%2F1.1&fp=firefox&type=tcp&headerType=none#Care-Germany-Vless -vless://1089cc14-557e-47ac-ac85-c07957b3cce3@140.238.14.103:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=xx.s4.cc.hh.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none&host=xx.s4.cc.hh.107421.xyz#Oracle-Seoul-Vless -vless://0c5741d0-76a9-4945-9c1d-14647afcce24@89.208.251.209:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=octopus.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none#BanH-LosA-Vless -trojan://Vad3.123acasd-1234-as.dAsd.asdazzS.123@89.208.251.209:443?flow=xtls-rprx-vision&security=tls&sni=xx.l4.cc.nn.107421.xyz&alpn=h2&fp=firefox&type=http&host=xx.l4.cc.nn.107421.xyz&path=status#BanH-LosA-Trojan -vless://21dab95b-088e-47bd-8351-609fd23cb33c@140.238.14.103:20443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=xx.t2.ll.c0.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none&host=xx.t2.ll.c0.107421.xyz#Oracle-Tokyo-By-Seoul-Vless -vless://4c2dd763-56e5-408f-bc8f-dbf4c1fe41f9@140.238.14.103:21443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=xx.o1.vl.s4.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none&host=xx.o1.vl.s4.107421.xyz#Oracle-Osaka-By-Seoul-Vless -vless://de576486-e254-4d9d-949a-37088358ec23@140.238.14.103:22443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=xx.p2.vl.s4.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none&host=xx.p2.vl.s4.107421.xyz#Oracle-Phoneix-By-Seoul-Vless -vless://12491d80-745c-4e26-a58b-edf584afb208@129.146.57.94:443?encryption=none&flow=xtls-rprx-vision&security=tls&sni=zc.p4.cc.xx.107421.xyz&alpn=h2&fp=firefox&type=tcp&headerType=none#Oracle-Pheonix-ARM02-Vless +socks5://zeaslity:a1f090ea-e39c-49e7-a3be-9af26b6ce563@42.192.52.227:22887 +socks5://zeaslity:a1f090ea-e39c-49e7-a3be-9af26b6ce563@42.192.52.227:22888 +socks5://zeaslity:a1f090ea-e39c-49e7-a3be-9af26b6ce563@42.192.52.227:22889 +vless://f8702759-f402-4e85-92a6-8540d577de22@43.154.83.213:24443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#TC-HongKong +vless://93be1d17-8e02-449d-bb99-683ed46fbe50@43.154.83.213:24453?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#CF-HongKong-R-TCHK +vless://cdf0b19a-9524-48d5-b697-5f10bb567734@43.154.83.213:24452?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-HongKong + +vless://86c50e3a-5b87-49dd-bd20-03c7f2735e40@bingo.pp.icederce.ip-ddns.com:8443?encryption=none&security=tls&type=ws&sni=pp.icederce.ip-ddns.com&host=pp.icederce.ip-ddns.com&path=/?ed=2560#CF_VIDEO_1 +vless://86c50e3a-5b87-49dd-bd20-03c7f2735e40@bingo.icederce.ip-ddns.com:8443?encryption=none&security=tls&type=ws&sni=pp.icederce.ip-ddns.com&host=pp.icederce.ip-ddns.com&path=/?ed=2560#CF_VIDEO_2 + +vless://7e27da0c-3013-4ed4-817b-50cc76a0bf81@43.154.83.213:24449?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#Oracle-KOR-Seoul-R-TCHK +vless://9fa9b4e7-d76d-4890-92cf-ce9251a76f59@43.154.83.213:24451?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#Care-DEU-Dusseldorf-R-TCHK + + +vless://b1417d92-998d-410b-a5f3-cf144b6f043e@45.134.50.233:443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=bingo.107421.xyz#Care-DEU-Dusseldorf +vless://1089cc14-557e-47ac-ac85-c07957b3cce3@140.238.14.103:443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=xx.s4.cc.hh.107421.xyz#Oracle-KOR-Seoul + + +vless://6055eac4-dee7-463b-b575-d30ea94bb768@43.154.83.213:24444?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-DEU-Frankfurt +vless://1cd284b2-d3d8-4165-b773-893f836c2b51@43.154.83.213:24445?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-KOR-Seoul +vless://bf0e9c35-84a9-460e-b5bf-2fa9f2fb3bca@43.154.83.213:24446?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-JPN-Tokyo +vless://adc19390-373d-4dfc-b0f6-19fab1b6fbf6@43.154.83.213:24447?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-GBR-London +vless://e31bc28e-8ebd-4d72-a98e-9227f26dfac3@43.154.83.213:24448?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-SGP +vless://56fb312c-bdb0-48ca-bf66-4a2dd34040c6@43.154.83.213:24450?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=book.107421.xyz#FV-USA-LosAngles + + +vless://21dab95b-088e-47bd-8351-609fd23cb33c@140.238.14.103:20443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=xx.t2.ll.c0.107421.xyz#Oracle-JPN-Tokyo-R-OSel +vless://4c2dd763-56e5-408f-bc8f-dbf4c1fe41f9@140.238.14.103:21443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=xx.o1.vl.s4.107421.xyz#Oracle-JPN-Osaka-R-OSel +vless://de576486-e254-4d9d-949a-37088358ec23@140.238.14.103:22443?type=tcp&encryption=none&security=tls&path=%2f&flow=xtls-rprx-vision&sni=xx.p2.vl.s4.107421.xyz#Oracle-USA-Phoneix-R-OSel diff --git a/1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml b/1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml new file mode 100644 index 0000000..631b94f --- /dev/null +++ b/1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml @@ -0,0 +1,27 @@ +- name: CF_TEST_1 + type: vless + server: gur.gov.ua + port: 8443 + uuid: 86c50e3a-5b87-49dd-bd20-03c7f2735e40 + udp: false + tls: true + network: ws + servername: pp.icederce.ip-ddns.com + ws-opts: + path: "/?ed=2560" + headers: + Host: pp.icederce.ip-ddns.com + +- name: CF_TEST_2 + type: vless + server: www.csgo.com + port: 443 + uuid: 86c50e3a-5b87-49dd-bd20-03c7f2735e40 + udp: false + tls: true + network: ws + servername: pp.icederce.ip-ddns.com + ws-opts: + path: "/?ed=2560" + headers: + Host: pp.icederce.ip-ddns.com \ No newline at end of file diff --git a/1-代理Xray/cloudflare-机场/cmliu-vless-worker.js b/1-代理Xray/cloudflare-机场/cmliu-vless-worker.js new file mode 100644 index 0000000..608f81f --- /dev/null +++ b/1-代理Xray/cloudflare-机场/cmliu-vless-worker.js @@ -0,0 +1,772 @@ + +import { connect } from 'cloudflare:sockets'; + +let userID = '86c50e3a-5b87-49dd-bd20-03c7f2735e40'; +let proxyIP = ''; +// let socks5Address = 'zeaslity:cd28a746-283e-47cc-88f7-bb43d7f6b53a@140.238.8.73:28888'; +let sock5User = "zeaslity" +let sock5Pass = "cd28a746-283e-47cc-88f7-bb43d7f6b53a" +let sock5Host = "140.238.8.73" +let sock5Port = 28888 +let enableSocks = true; + +let go2Socks5s = [ + '*ttvnw.net', + '*tapecontent.net', + '*cloudatacdn.com', + '*.loadshare.org', + "whoer.net", + "whatismyipaddress.com", + "*.cloudflare.com", + "*.cloudflare.net", + "*.cloudflare.workers.dev", + "dnschecker.org", + "ip.sb", + "ipinfo.io" +]; + +const httpPorts = ["8080", "8880", "2052", "2082", "2086", "2095"]; +let httpsPorts = ["2053", "2083", "2087", "2096", "8443"]; + +export default { + async fetch(request, env, ctx) { + try { + const UA = request.headers.get('User-Agent') || 'null'; + + + const upgradeHeader = request.headers.get('Upgrade'); + const url = new URL(request.url); + + if (!upgradeHeader || upgradeHeader !== 'websocket') { + return new Response('Hello World! to ' + url); + } + + // handle 请求 + return await WddGoOverWSHandler(request); + + } catch (err) { + let e = err; + return new Response(e.toString()); + } + }, +}; + +async function WddGoOverWSHandler(request) { + + // @ts-ignore + const webSocketPair = new WebSocketPair(); + const [client, webSocket] = Object.values(webSocketPair); + + // 接受 WebSocket 连接 + webSocket.accept(); + + let address = ''; + let portWithRandomLog = ''; + // 日志函数,用于记录连接信息 + const log = (/** @type {string} */ info, /** @type {string | undefined} */ event) => { + console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ''); + }; + // 获取早期数据头部,可能包含了一些初始化数据 + const earlyDataHeader = request.headers.get('sec-websocket-protocol') || ''; + + // 创建一个可读的 WebSocket 流,用于接收客户端数据 + const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log); + + // 用于存储远程 Socket 的包装器 + let remoteSocketWapper = { + value: null, + }; + // 标记是否为 DNS 查询 + let isDns = false; + + // WebSocket 数据流向远程服务器的管道 + readableWebSocketStream.pipeTo(new WritableStream({ + async write(chunk, controller) { + if (isDns) { + // 如果是 DNS 查询,调用 DNS 处理函数 + return await handleDNSQuery(chunk, webSocket, null, log); + } + if (remoteSocketWapper.value) { + // 如果已有远程 Socket,直接写入数据 + const writer = remoteSocketWapper.value.writable.getWriter() + await writer.write(chunk); + writer.releaseLock(); + return; + } + + // 处理 WddGo 协议头部 + const { + hasError, + message, + addressType, + portRemote = 443, + addressRemote = '', + rawDataIndex, + WddGoVersion = new Uint8Array([0, 0]), + isUDP, + } = processWddGoHeader(chunk, userID); + // 设置地址和端口信息,用于日志 + address = addressRemote; + portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? 'udp ' : 'tcp '} `; + if (hasError) { + // 如果有错误,抛出异常 + throw new Error(message); + return; + } + // 如果是 UDP 且端口不是 DNS 端口(53),则关闭连接 + if (isUDP) { + if (portRemote === 53) { + isDns = true; + } else { + throw new Error('UDP 代理仅对 DNS(53 端口)启用'); + return; + } + } + // 构建 WddGo 响应头部 + const WddGoResponseHeader = new Uint8Array([WddGoVersion[0], 0]); + // 获取实际的客户端数据 + const rawClientData = chunk.slice(rawDataIndex); + + if (isDns) { + // 如果是 DNS 查询,调用 DNS 处理函数 + return handleDNSQuery(rawClientData, webSocket, WddGoResponseHeader, log); + } + // 处理 TCP 出站连接 + log(`处理 TCP 出站连接 ${addressRemote}:${portRemote}`); + handleTCPOutBound(remoteSocketWapper, addressType, addressRemote, portRemote, rawClientData, webSocket, WddGoResponseHeader, log); + }, + close() { + log(`readableWebSocketStream 已关闭`); + }, + abort(reason) { + log(`readableWebSocketStream 已中止`, JSON.stringify(reason)); + }, + })).catch((err) => { + log('readableWebSocketStream 管道错误', err); + }); + + // 返回一个 WebSocket 升级的响应 + return new Response(null, { + status: 101, + // @ts-ignore + webSocket: client, + }); +} + +async function handleTCPOutBound(remoteSocket, addressType, addressRemote, portRemote, rawClientData, webSocket, WddGoResponseHeader, log,) { + + async function useSocks5Pattern(address) { + if (go2Socks5s.includes(address) || go2Socks5s.includes(address)) return true; + return go2Socks5s.some(pattern => { + let regexPattern = pattern.replace(/\*/g, '.*'); + let regex = new RegExp(`^${regexPattern}$`, 'i'); + return regex.test(address); + }); + } + + async function connectAndWrite(address, port, socks = false) { + log(`connected to ${address}:${port}`); + //if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) address = `${atob('d3d3Lg==')}${address}${atob('LmlwLjA5MDIyNy54eXo=')}`; + // 如果指定使用 SOCKS5 代理,则通过 SOCKS5 协议连接;否则直接连接 + const tcpSocket = socks ? await socks5Connect(addressType, address, port, log) + : connect({ + hostname: address, + port: port, + }); + remoteSocket.value = tcpSocket; + //log(`connected to ${address}:${port}`); + const writer = tcpSocket.writable.getWriter(); + // 首次写入,通常是 TLS 客户端 Hello 消息 + await writer.write(rawClientData); + writer.releaseLock(); + return tcpSocket; + } + + /** + * 重试函数:当 Cloudflare 的 TCP Socket 没有传入数据时,我们尝试重定向 IP + * 这可能是因为某些网络问题导致的连接失败 + */ + async function retry() { + if (enableSocks) { + // 如果启用了 SOCKS5,通过 SOCKS5 代理重试连接 + tcpSocket = await connectAndWrite(addressRemote, portRemote, true); + } else { + // 使用代理 IP + + proxyIP = '[2603:c022:8008:8923:88a0:5c7d:2bb6:6ed5]' + portRemote = 27443 + tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote); + } + // 无论重试是否成功,都要关闭 WebSocket(可能是为了重新建立连接) + tcpSocket.closed.catch(error => { + console.log('retry tcpSocket closed error', error); + }).finally(() => { + safeCloseWebSocket(webSocket); + }) + + // 建立从远程 Socket 到 WebSocket 的数据流 + remoteSocketToWS(tcpSocket, webSocket, WddGoResponseHeader, null, log); + } + + let useSocks = false; + if (go2Socks5s.length > 0 && enableSocks) useSocks = await useSocks5Pattern(addressRemote); + + // 首次尝试连接远程服务器 + let tcpSocket = await connectAndWrite(addressRemote, portRemote, useSocks); + + // 当远程 Socket 就绪时,将其传递给 WebSocket + // 建立从远程服务器到 WebSocket 的数据流,用于将远程服务器的响应发送回客户端 + // 如果连接失败或无数据,retry 函数将被调用进行重试 + remoteSocketToWS(tcpSocket, webSocket, WddGoResponseHeader, retry, log); +} + +function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) { + // 标记可读流是否已被取消 + let readableStreamCancel = false; + + // 创建一个新的可读流 + const stream = new ReadableStream({ + // 当流开始时的初始化函数 + start(controller) { + // 监听 WebSocket 的消息事件 + webSocketServer.addEventListener('message', (event) => { + // 如果流已被取消,不再处理新消息 + if (readableStreamCancel) { + return; + } + const message = event.data; + // 将消息加入流的队列中 + controller.enqueue(message); + }); + + // 监听 WebSocket 的关闭事件 + // 注意:这个事件意味着客户端关闭了客户端 -> 服务器的流 + // 但是,服务器 -> 客户端的流仍然打开,直到在服务器端调用 close() + // WebSocket 协议要求在每个方向上都要发送单独的关闭消息,以完全关闭 Socket + webSocketServer.addEventListener('close', () => { + // 客户端发送了关闭信号,需要关闭服务器端 + safeCloseWebSocket(webSocketServer); + // 如果流未被取消,则关闭控制器 + if (readableStreamCancel) { + return; + } + controller.close(); + }); + + // 监听 WebSocket 的错误事件 + webSocketServer.addEventListener('error', (err) => { + log('WebSocket 服务器发生错误'); + // 将错误传递给控制器 + controller.error(err); + }); + + // 处理 WebSocket 0-RTT(零往返时间)的早期数据 + // 0-RTT 允许在完全建立连接之前发送数据,提高了效率 + const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); + if (error) { + // 如果解码早期数据时出错,将错误传递给控制器 + controller.error(error); + } else if (earlyData) { + // 如果有早期数据,将其加入流的队列中 + controller.enqueue(earlyData); + } + }, + + // 当使用者从流中拉取数据时调用 + pull(controller) { + // 这里可以实现反压机制 + // 如果 WebSocket 可以在流满时停止读取,我们就可以实现反压 + // 参考:https://streams.spec.whatwg.org/#example-rs-push-backpressure + }, + + // 当流被取消时调用 + cancel(reason) { + // 流被取消的几种情况: + // 1. 当管道的 WritableStream 有错误时,这个取消函数会被调用,所以在这里处理 WebSocket 服务器的关闭 + // 2. 如果 ReadableStream 被取消,所有 controller.close/enqueue 都需要跳过 + // 3. 但是经过测试,即使 ReadableStream 被取消,controller.error 仍然有效 + if (readableStreamCancel) { + return; + } + log(`可读流被取消,原因是 ${reason}`); + readableStreamCancel = true; + // 安全地关闭 WebSocket + safeCloseWebSocket(webSocketServer); + } + }); + + return stream; +} + +/** + * 解析 WddGo 协议的头部数据 + * @param { ArrayBuffer} WddGoBuffer WddGo 协议的原始头部数据 + * @param {string} userID 用于验证的用户 ID + * @returns {Object} 解析结果,包括是否有错误、错误信息、远程地址信息等 + */ +function processWddGoHeader(WddGoBuffer, userID) { + // 检查数据长度是否足够(至少需要 24 字节) + if (WddGoBuffer.byteLength < 24) { + return { + hasError: true, + message: 'invalid data', + }; + } + + // 解析 WddGo 协议版本(第一个字节) + const version = new Uint8Array(WddGoBuffer.slice(0, 1)); + + let isValidUser = false; + let isUDP = false; + + // 验证用户 ID(接下来的 16 个字节) + function isUserIDValid(userID, buffer) { + const userIDArray = new Uint8Array(buffer.slice(1, 17)); + const userIDString = stringify(userIDArray); + return userIDString === userID + } + + // 使用函数验证 + isValidUser = isUserIDValid(userID, WddGoBuffer); + + // 如果用户 ID 无效,返回错误 + if (!isValidUser) { + return { + hasError: true, + message: `invalid user ${(new Uint8Array(WddGoBuffer.slice(1, 17)))}`, + }; + } + + // 获取附加选项的长度(第 17 个字节) + const optLength = new Uint8Array(WddGoBuffer.slice(17, 18))[0]; + // 暂时跳过附加选项 + + // 解析命令(紧跟在选项之后的 1 个字节) + // 0x01: TCP, 0x02: UDP, 0x03: MUX(多路复用) + const command = new Uint8Array( + WddGoBuffer.slice(18 + optLength, 18 + optLength + 1) + )[0]; + + // 0x01 TCP + // 0x02 UDP + // 0x03 MUX + if (command === 1) { + // TCP 命令,不需特殊处理 + } else if (command === 2) { + // UDP 命令 + isUDP = true; + } else { + // 不支持的命令 + return { + hasError: true, + message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`, + }; + } + + // 解析远程端口(大端序,2 字节) + const portIndex = 18 + optLength + 1; + const portBuffer = WddGoBuffer.slice(portIndex, portIndex + 2); + // port is big-Endian in raw data etc 80 == 0x005d + const portRemote = new DataView(portBuffer).getUint16(0); + + // 解析地址类型和地址 + let addressIndex = portIndex + 2; + const addressBuffer = new Uint8Array( + WddGoBuffer.slice(addressIndex, addressIndex + 1) + ); + + // 地址类型:1-IPv4(4字节), 2-域名(可变长), 3-IPv6(16字节) + const addressType = addressBuffer[0]; + let addressLength = 0; + let addressValueIndex = addressIndex + 1; + let addressValue = ''; + + switch (addressType) { + case 1: + // IPv4 地址 + addressLength = 4; + // 将 4 个字节转为点分十进制格式 + addressValue = new Uint8Array( + WddGoBuffer.slice(addressValueIndex, addressValueIndex + addressLength) + ).join('.'); + break; + case 2: + // 域名 + // 第一个字节是域名长度 + addressLength = new Uint8Array( + WddGoBuffer.slice(addressValueIndex, addressValueIndex + 1) + )[0]; + addressValueIndex += 1; + // 解码域名 + addressValue = new TextDecoder().decode( + WddGoBuffer.slice(addressValueIndex, addressValueIndex + addressLength) + ); + break; + case 3: + // IPv6 地址 + addressLength = 16; + const dataView = new DataView( + WddGoBuffer.slice(addressValueIndex, addressValueIndex + addressLength) + ); + // 每 2 字节构成 IPv6 地址的一部分 + const ipv6 = []; + for (let i = 0; i < 8; i++) { + ipv6.push(dataView.getUint16(i * 2).toString(16)); + } + addressValue = ipv6.join(':'); + // seems no need add [] for ipv6 + break; + default: + // 无效的地址类型 + return { + hasError: true, + message: `invild addressType is ${addressType}`, + }; + } + + // 确保地址不为空 + if (!addressValue) { + return { + hasError: true, + message: `addressValue is empty, addressType is ${addressType}`, + }; + } + + // 返回解析结果 + return { + hasError: false, + addressRemote: addressValue, // 解析后的远程地址 + addressType, // 地址类型 + portRemote, // 远程端口 + rawDataIndex: addressValueIndex + addressLength, // 原始数据的实际起始位置 + WddGoVersion: version, // WddGo 协议版本 + isUDP, // 是否是 UDP 请求 + }; +} + +async function remoteSocketToWS(remoteSocket, webSocket, WddGoResponseHeader, retry, log) { + // 将数据从远程服务器转发到 WebSocket + let remoteChunkCount = 0; + let chunks = []; + /** @type {ArrayBuffer | null} */ + let WddGoHeader = WddGoResponseHeader; + let hasIncomingData = false; // 检查远程 Socket 是否有传入数据 + + // 使用管道将远程 Socket 的可读流连接到一个可写流 + await remoteSocket.readable + .pipeTo( + new WritableStream({ + start() { + // 初始化时不需要任何操作 + }, + /** + * 处理每个数据块 + * @param {Uint8Array} chunk 数据块 + * @param {*} controller 控制器 + */ + async write(chunk, controller) { + hasIncomingData = true; // 标记已收到数据 + // remoteChunkCount++; // 用于流量控制,现在似乎不需要了 + + // 检查 WebSocket 是否处于开放状态 + if (webSocket.readyState !== WS_READY_STATE_OPEN) { + controller.error( + 'webSocket.readyState is not open, maybe close' + ); + } + + if (WddGoHeader) { + // 如果有 WddGo 响应头部,将其与第一个数据块一起发送 + webSocket.send(await new Blob([WddGoHeader, chunk]).arrayBuffer()); + WddGoHeader = null; // 清空头部,之后不再发送 + } else { + // 直接发送数据块 + // 以前这里有流量控制代码,限制大量数据的发送速率 + // 但现在 Cloudflare 似乎已经修复了这个问题 + // if (remoteChunkCount > 20000) { + // // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M + // await delay(1); + // } + webSocket.send(chunk); + } + }, + close() { + // 当远程连接的可读流关闭时 + log(`remoteConnection!.readable is close with hasIncomingData is ${hasIncomingData}`); + // 不需要主动关闭 WebSocket,因为这可能导致 HTTP ERR_CONTENT_LENGTH_MISMATCH 问题 + // 客户端无论如何都会发送关闭事件 + // safeCloseWebSocket(webSocket); + }, + abort(reason) { + // 当远程连接的可读流中断时 + console.error(`remoteConnection!.readable abort`, reason); + }, + }) + ) + .catch((error) => { + // 捕获并记录任何异常 + console.error( + `remoteSocketToWS has exception `, + error.stack || error + ); + // 发生错误时安全地关闭 WebSocket + safeCloseWebSocket(webSocket); + }); + + // 处理 Cloudflare 连接 Socket 的特殊错误情况 + // 1. Socket.closed 将有错误 + // 2. Socket.readable 将关闭,但没有任何数据 + if (hasIncomingData === false && retry) { + log(`retry`); + retry(); // 调用重试函数,尝试重新建立连接 + } +} + +/** + * 将 Base64 编码的字符串转换为 ArrayBuffer + * + * @param {string} base64Str Base64 编码的输入字符串 + * @returns {{ earlyData: ArrayBuffer | undefined, error: Error | null }} 返回解码后的 ArrayBuffer 或错误 + */ +function base64ToArrayBuffer(base64Str) { + // 如果输入为空,直接返回空结果 + if (!base64Str) { + return { earlyData: undefined, error: null }; + } + try { + // Go 语言使用了 URL 安全的 Base64 变体(RFC 4648) + // 这种变体使用 '-' 和 '_' 来代替标准 Base64 中的 '+' 和 '/' + // JavaScript 的 atob 函数不直接支持这种变体,所以我们需要先转换 + base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/'); + + // 使用 atob 函数解码 Base64 字符串 + // atob 将 Base64 编码的 ASCII 字符串转换为原始的二进制字符串 + const decode = atob(base64Str); + + // 将二进制字符串转换为 Uint8Array + // 这是通过遍历字符串中的每个字符并获取其 Unicode 编码值(0-255)来完成的 + const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); + + // 返回 Uint8Array 的底层 ArrayBuffer + // 这是实际的二进制数据,可以用于网络传输或其他二进制操作 + return { earlyData: arryBuffer.buffer, error: null }; + } catch (error) { + // 如果在任何步骤中出现错误(如非法 Base64 字符),则返回错误 + return { earlyData: undefined, error }; + } +} + +/** + * 这不是真正的 UUID 验证,而是一个简化的版本 + * @param {string} uuid 要验证的 UUID 字符串 + * @returns {boolean} 如果字符串匹配 UUID 格式则返回 true,否则返回 false + */ +function isValidUUID(uuid) { + // 定义一个正则表达式来匹配 UUID 格式 + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + + // 使用正则表达式测试 UUID 字符串 + return uuidRegex.test(uuid); +} + +// WebSocket 的两个重要状态常量 +const WS_READY_STATE_OPEN = 1; // WebSocket 处于开放状态,可以发送和接收消息 +const WS_READY_STATE_CLOSING = 2; // WebSocket 正在关闭过程中 + +function safeCloseWebSocket(socket) { + try { + // 只有在 WebSocket 处于开放或正在关闭状态时才调用 close() + // 这避免了在已关闭或连接中的 WebSocket 上调用 close() + if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) { + socket.close(); + } + } catch (error) { + // 记录任何可能发生的错误,虽然按照规范不应该有错误 + console.error('safeCloseWebSocket error', error); + } +} + +// 预计算 0-255 每个字节的十六进制表示 +const byteToHex = []; +for (let i = 0; i < 256; ++i) { + // (i + 256).toString(16) 确保总是得到两位数的十六进制 + // .slice(1) 删除前导的 "1",只保留两位十六进制数 + byteToHex.push((i + 256).toString(16).slice(1)); +} + +/** + * 快速地将字节数组转换为 UUID 字符串,不进行有效性检查 + * 这是一个底层函数,直接操作字节,不做任何验证 + * @param {Uint8Array} arr 包含 UUID 字节的数组 + * @param {number} offset 数组中 UUID 开始的位置,默认为 0 + * @returns {string} UUID 字符串 + */ +function unsafeStringify(arr, offset = 0) { + // 直接从查找表中获取每个字节的十六进制表示,并拼接成 UUID 格式 + // 8-4-4-4-12 的分组是通过精心放置的连字符 "-" 实现的 + // toLowerCase() 确保整个 UUID 是小写的 + return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); +} + +/** + * 将字节数组转换为 UUID 字符串,并验证其有效性 + * 这是一个安全的函数,它确保返回的 UUID 格式正确 + * @param {Uint8Array} arr 包含 UUID 字节的数组 + * @param {number} offset 数组中 UUID 开始的位置,默认为 0 + * @returns {string} 有效的 UUID 字符串 + * @throws {TypeError} 如果生成的 UUID 字符串无效 + */ +function stringify(arr, offset = 0) { + // 使用不安全的函数快速生成 UUID 字符串 + const uuid = unsafeStringify(arr, offset); + // 验证生成的 UUID 是否有效 + if (!isValidUUID(uuid)) { + // 原:throw TypeError("Stringified UUID is invalid"); + throw TypeError(`生成的 UUID 不符合规范 ${uuid}`); + //uuid = userID; + } + return uuid; +} + +/** + * 处理 DNS 查询的函数 + * @param {ArrayBuffer} udpChunk - 客户端发送的 DNS 查询数据 + * @param {ArrayBuffer} WddGoResponseHeader - WddGo 协议的响应头部数据 + * @param {(string)=> void} log - 日志记录函数 + */ +async function handleDNSQuery(udpChunk, webSocket, WddGoResponseHeader, log) { + // 无论客户端发送到哪个 DNS 服务器,我们总是使用硬编码的服务器 + // 因为有些 DNS 服务器不支持 DNS over TCP + try { + // 选用 Google 的 DNS 服务器(注:后续可能会改为 Cloudflare 的 1.1.1.1) + const dnsServer = '8.8.4.4'; // 在 Cloudflare 修复连接自身 IP 的 bug 后,将改为 1.1.1.1 + const dnsPort = 53; // DNS 服务的标准端口 + + let WddGoHeader = WddGoResponseHeader; // 保存 WddGo 响应头部,用于后续发送 + + // 与指定的 DNS 服务器建立 TCP 连接 + const tcpSocket = connect({ + hostname: dnsServer, + port: dnsPort, + }); + + log(`连接到 ${dnsServer}:${dnsPort}`); // 记录连接信息 + const writer = tcpSocket.writable.getWriter(); + await writer.write(udpChunk); // 将客户端的 DNS 查询数据发送给 DNS 服务器 + writer.releaseLock(); // 释放写入器,允许其他部分使用 + + // 将从 DNS 服务器接收到的响应数据通过 WebSocket 发送回客户端 + await tcpSocket.readable.pipeTo(new WritableStream({ + async write(chunk) { + if (webSocket.readyState === WS_READY_STATE_OPEN) { + if (WddGoHeader) { + // 如果有 WddGo 头部,则将其与 DNS 响应数据合并后发送 + webSocket.send(await new Blob([WddGoHeader, chunk]).arrayBuffer()); + WddGoHeader = null; // 头部只发送一次,之后置为 null + } else { + // 否则直接发送 DNS 响应数据 + webSocket.send(chunk); + } + } + }, + close() { + log(`DNS 服务器(${dnsServer}) TCP 连接已关闭`); // 记录连接关闭信息 + }, + abort(reason) { + console.error(`DNS 服务器(${dnsServer}) TCP 连接异常中断`, reason); // 记录异常中断原因 + }, + })); + } catch (error) { + // 捕获并记录任何可能发生的错误 + console.error( + `handleDNSQuery 函数发生异常,错误信息: ${error.message}` + ); + } +} + + +async function socks5Connect(addressType, addressRemote, portRemote, log) { + // 从环境变量获取认证信息(假设在运行环境中已定义) + const username = sock5User + const password = sock5Pass + const hostname = sock5Host + const port = sock5Port + + // 直连代理服务器 + const socket = connect({ hostname, port }); + const writer = socket.writable.getWriter(); + const reader = socket.readable.getReader(); + const encoder = new TextEncoder(); + + // 精简握手流程:直接声明需要用户名密码认证 + await writer.write(new Uint8Array([5, 1, 2])); // 只支持 0x02 方法 + log('SOCKS5 认证方法协商'); + + // 处理认证响应 + let res = (await reader.read()).value; + if (res[0] !== 0x05 || res[1] !== 0x02) { + res[1] === 0xff && log("不支持的认证方式"); + return; + } + + // 构造认证数据包(提前计算长度避免重复编码) + const userBytes = encoder.encode(username); + const passBytes = encoder.encode(password); + const authHeader = new Uint8Array(3 + userBytes.length + passBytes.length); + authHeader.set([1, userBytes.length, ...userBytes, passBytes.length], 0); + authHeader.set(passBytes, 2 + userBytes.length); // 优化内存拷贝 + + await writer.write(authHeader); + res = (await reader.read()).value; + if (res[0] !== 0x01 || res[1] !== 0x00) { + log(`认证失败 code: 0x${res[1].toString(16)}`); + return; + } + + // 构造目标地址(优化二进制操作) + const header = new Uint8Array([5, 1, 0]); + const addrBuffer = new Uint8Array( + addressType === 3 ? 16 + 1 : // IPv6 + addressType === 2 ? encoder.encode(addressRemote).length + 2 : // 域名 + 4 + 1 // IPv4 + ); + + let offset = 0; + addrBuffer[offset++] = addressType === 3 ? 4 : addressType; + if (addressType === 2) { + addrBuffer[offset++] = addressRemote.length; + encoder.encodeInto(addressRemote, addrBuffer.subarray(offset)); + } else { + const octets = addressType === 3 ? + new Uint16Array(addressRemote.split(':').flatMap(p => + [parseInt(p.substring(0,4),16), parseInt(p.substring(4),16)])) : + addressRemote.split('.').map(Number); + addrBuffer.set(new Uint8Array(octets.buffer || octets), offset); + } + + // 合并数据包并发送 + const finalPacket = new Uint8Array([ + ...header, + ...addrBuffer, + portRemote >> 8, portRemote & 0xff + ]); + await writer.write(finalPacket); + log('SOCKS5 连接请求已发送'); + + // 验证最终响应 + res = (await reader.read()).value; + if (res[1] !== 0x00) { + log(`连接失败 code: 0x${res[1].toString(16)}`); + return; + } + + writer.releaseLock(); + reader.releaseLock(); + return socket; +} + diff --git a/1-代理Xray/cloudflare-机场/yonge_cf_worker.js b/1-代理Xray/cloudflare-机场/yonge_cf_worker.js new file mode 100644 index 0000000..e7491c4 --- /dev/null +++ b/1-代理Xray/cloudflare-机场/yonge_cf_worker.js @@ -0,0 +1,996 @@ +// @ts-ignore +import { connect } from "cloudflare:sockets"; + +let userID = "86c50e3a-5b87-49dd-bd20-03c7f2735e40"; + +const proxyIPs = ["ts.hpc.tw","47.254.66.75","146.70.175.98","146.70.175.99","146.70.175.100","146.70.175.101","146.70.175.102","146.70.175.103","146.70.175.104","146.70.175.106","cdn-all.xn--b6gac.eu.org","cdn.xn--b6gac.eu.org"]; +const cn_hostnames = ['']; +let CDNIP = 'cdn-all.xijingping.link' + +// http_ip +let IP1 = 'www.visa.com' +let IP2 = 'cis.visa.com' +let IP3 = 'africa.visa.com' +let IP4 = 'www.visa.com.sg' +let IP5 = 'www.visaeurope.at' +let IP6 = 'www.visa.com.mt' +let IP7 = 'qa.visamiddleeast.com' + +// https_ip +let IP8 = 'usa.visa.com' +let IP9 = 'malaysia.com' +let IP10 = 'www.visa.co.jp' +let IP11 = 'www.digitalocean.com' +let IP12 = 'japan.com' +let IP13 = 'cdn-b100.xn--b6gac.eu.org' + +// http_port +let PT1 = '80' +let PT2 = '8080' +let PT3 = '8880' +let PT4 = '2052' +let PT5 = '2082' +let PT6 = '2086' +let PT7 = '2095' + +// https_port +let PT8 = '443' +let PT9 = '8443' +let PT10 = '2053' +let PT11 = '2083' +let PT12 = '2087' +let PT13 = '2096' + +let proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; +let proxyPort = proxyIP.includes(':') ? proxyIP.split(':')[1] : '443'; + +if (!isValidUUID(userID)) { + throw new Error("uuid is not valid"); +} + +export default { + /** + * @param {import("@cloudflare/workers-types").Request} request + * @param {uuid: string, proxyip: string, cdnip: string, ip1: string, ip2: string, ip3: string, ip4: string, ip5: string, ip6: string, ip7: string, ip8: string, ip9: string, ip10: string, ip11: string, ip12: string, ip13: string, pt1: string, pt2: string, pt3: string, pt4: string, pt5: string, pt6: string, pt7: string, pt8: string, pt9: string, pt10: string, pt11: string, pt12: string, pt13: string} env + * @param {import("@cloudflare/workers-types").ExecutionContext} ctx + * @returns {Promise} + */ + async fetch(request, env, ctx) { + try { + const { proxyip } = env; + userID = env.uuid || userID; + if (proxyip) { + if (proxyip.includes(']:')) { + let lastColonIndex = proxyip.lastIndexOf(':'); + proxyPort = proxyip.slice(lastColonIndex + 1); + proxyIP = proxyip.slice(0, lastColonIndex); + + } else if (!proxyip.includes(']:') && !proxyip.includes(']')) { + [proxyIP, proxyPort = '443'] = proxyip.split(':'); + } else { + proxyPort = '443'; + proxyIP = proxyip; + } + } else { + if (proxyIP.includes(']:')) { + let lastColonIndex = proxyIP.lastIndexOf(':'); + proxyPort = proxyIP.slice(lastColonIndex + 1); + proxyIP = proxyIP.slice(0, lastColonIndex); + } else if (!proxyIP.includes(']:') && !proxyIP.includes(']')) { + [proxyIP, proxyPort = '443'] = proxyIP.split(':'); + } else { + proxyPort = '443'; + } + } + console.log('ProxyIP:', proxyIP); + console.log('ProxyPort:', proxyPort); + CDNIP = env.cdnip || CDNIP; + IP1 = env.ip1 || IP1; + IP2 = env.ip2 || IP2; + IP3 = env.ip3 || IP3; + IP4 = env.ip4 || IP4; + IP5 = env.ip5 || IP5; + IP6 = env.ip6 || IP6; + IP7 = env.ip7 || IP7; + IP8 = env.ip8 || IP8; + IP9 = env.ip9 || IP9; + IP10 = env.ip10 || IP10; + IP11 = env.ip11 || IP11; + IP12 = env.ip12 || IP12; + IP13 = env.ip13 || IP13; + PT1 = env.pt1 || PT1; + PT2 = env.pt2 || PT2; + PT3 = env.pt3 || PT3; + PT4 = env.pt4 || PT4; + PT5 = env.pt5 || PT5; + PT6 = env.pt6 || PT6; + PT7 = env.pt7 || PT7; + PT8 = env.pt8 || PT8; + PT9 = env.pt9 || PT9; + PT10 = env.pt10 || PT10; + PT11 = env.pt11 || PT11; + PT12 = env.pt12 || PT12; + PT13 = env.pt13 || PT13; + const upgradeHeader = request.headers.get("Upgrade"); + const url = new URL(request.url); + if (!upgradeHeader || upgradeHeader !== "websocket") { + // return new Response('Not found', { status: 404 }); + // For any other path, reverse proxy to 'ramdom website' and return the original response, caching it in the process + if (cn_hostnames.includes('')) { + return new Response(JSON.stringify(request.cf, null, 4), { + status: 200, + headers: { + "Content-Type": "application/json;charset=utf-8", + }, + }); + } + const randomHostname = cn_hostnames[Math.floor(Math.random() * cn_hostnames.length)]; + const newHeaders = new Headers(request.headers); + newHeaders.set("cf-connecting-ip", "1.2.3.4"); + newHeaders.set("x-forwarded-for", "1.2.3.4"); + newHeaders.set("x-real-ip", "1.2.3.4"); + newHeaders.set("referer", "https://www.google.com/search?q=edtunnel"); + // Use fetch to proxy the request to 15 different domains + const proxyUrl = "https://" + randomHostname + url.pathname + url.search; + let modifiedRequest = new Request(proxyUrl, { + method: request.method, + headers: newHeaders, + body: request.body, + redirect: "manual", + }); + const proxyResponse = await fetch(modifiedRequest, { redirect: "manual" }); + // Check for 302 or 301 redirect status and return an error response + if ([301, 302].includes(proxyResponse.status)) { + return new Response(`Redirects to ${randomHostname} are not allowed.`, { + status: 403, + statusText: "Forbidden", + }); + } + // Return the response from the proxy server + return proxyResponse; + } else { + return await vlessOverWSHandler(request); + } + } catch (err) { + /** @type {Error} */ let e = err; + return new Response(e.toString()); + } + }, +}; + +function isValidIP(ip) { + var reg = /^[\s\S]*$/; + return reg.test(ip); +} + +/** + * + * @param {import("@cloudflare/workers-types").Request} request + */ +async function vlessOverWSHandler(request) { + /** @type {import("@cloudflare/workers-types").WebSocket[]} */ + // @ts-ignore + const webSocketPair = new WebSocketPair(); + const [client, webSocket] = Object.values(webSocketPair); + + webSocket.accept(); + + let address = ""; + let portWithRandomLog = ""; + const log = (/** @type {string} */ info, /** @type {string | undefined} */ event) => { + console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ""); + }; + const earlyDataHeader = request.headers.get("sec-websocket-protocol") || ""; + + const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log); + + /** @type {{ value: import("@cloudflare/workers-types").Socket | null}}*/ + let remoteSocketWapper = { + value: null, + }; + let udpStreamWrite = null; + let isDns = false; + + // ws --> remote + readableWebSocketStream + .pipeTo( + new WritableStream({ + async write(chunk, controller) { + if (isDns && udpStreamWrite) { + return udpStreamWrite(chunk); + } + if (remoteSocketWapper.value) { + const writer = remoteSocketWapper.value.writable.getWriter(); + await writer.write(chunk); + writer.releaseLock(); + return; + } + + const { + hasError, + message, + portRemote = 443, + addressRemote = "", + rawDataIndex, + vlessVersion = new Uint8Array([0, 0]), + isUDP, + } = await processVlessHeader(chunk, userID); + address = addressRemote; + portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? "udp " : "tcp "} `; + if (hasError) { + // controller.error(message); + throw new Error(message); // cf seems has bug, controller.error will not end stream + // webSocket.close(1000, message); + return; + } + // if UDP but port not DNS port, close it + if (isUDP) { + if (portRemote === 53) { + isDns = true; + } else { + // controller.error('UDP proxy only enable for DNS which is port 53'); + throw new Error("UDP proxy only enable for DNS which is port 53"); // cf seems has bug, controller.error will not end stream + return; + } + } + // ["version", "附加信息长度 N"] + const vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]); + const rawClientData = chunk.slice(rawDataIndex); + + // TODO: support udp here when cf runtime has udp support + if (isDns) { + const { write } = await handleUDPOutBound(webSocket, vlessResponseHeader, log); + udpStreamWrite = write; + udpStreamWrite(rawClientData); + return; + } + handleTCPOutBound( + remoteSocketWapper, + addressRemote, + portRemote, + rawClientData, + webSocket, + vlessResponseHeader, + log + ); + }, + close() { + log(`readableWebSocketStream is close`); + }, + abort(reason) { + log(`readableWebSocketStream is abort`, JSON.stringify(reason)); + }, + }) + ) + .catch((err) => { + log("readableWebSocketStream pipeTo error", err); + }); + + return new Response(null, { + status: 101, + // @ts-ignore + webSocket: client, + }); +} + +/** + * Checks if a given UUID is present in the API response. + * @param {string} targetUuid The UUID to search for. + * @returns {Promise} A Promise that resolves to true if the UUID is present in the API response, false otherwise. + */ +async function checkUuidInApiResponse(targetUuid) { + // Check if any of the environment variables are empty + + try { + const apiResponse = await getApiResponse(); + if (!apiResponse) { + return false; + } + const isUuidInResponse = apiResponse.users.some((user) => user.uuid === targetUuid); + return isUuidInResponse; + } catch (error) { + console.error("Error:", error); + return false; + } +} + +/** + * Handles outbound TCP connections. + * + * @param {any} remoteSocket + * @param {string} addressRemote The remote address to connect to. + * @param {number} portRemote The remote port to connect to. + * @param {Uint8Array} rawClientData The raw client data to write. + * @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket to pass the remote socket to. + * @param {Uint8Array} vlessResponseHeader The vless response header. + * @param {function} log The logging function. + * @returns {Promise} The remote socket. + */ +async function handleTCPOutBound( + remoteSocket, + addressRemote, + portRemote, + rawClientData, + webSocket, + vlessResponseHeader, + log +) { + async function connectAndWrite(address, port) { + if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) address = `${atob('d3d3Lg==')}${address}${atob('LnNzbGlwLmlv')}`; + /** @type {import("@cloudflare/workers-types").Socket} */ + const tcpSocket = connect({ + hostname: address, + port: port, + }); + remoteSocket.value = tcpSocket; + log(`connected to ${address}:${port}`); + const writer = tcpSocket.writable.getWriter(); + await writer.write(rawClientData); // first write, nomal is tls client hello + writer.releaseLock(); + return tcpSocket; + } + + // if the cf connect tcp socket have no incoming data, we retry to redirect ip + async function retry() { + const tcpSocket = await connectAndWrite(proxyIP || addressRemote, proxyPort || portRemote); + // no matter retry success or not, close websocket + tcpSocket.closed + .catch((error) => { + console.log("retry tcpSocket closed error", error); + }) + .finally(() => { + safeCloseWebSocket(webSocket); + }); + remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, null, log); + } + + const tcpSocket = await connectAndWrite(addressRemote, portRemote); + + // when remoteSocket is ready, pass to websocket + // remote--> ws + remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, retry, log); +} + +/** + * + * @param {import("@cloudflare/workers-types").WebSocket} webSocketServer + * @param {string} earlyDataHeader for ws 0rtt + * @param {(info: string)=> void} log for ws 0rtt + */ +function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) { + let readableStreamCancel = false; + const stream = new ReadableStream({ + start(controller) { + webSocketServer.addEventListener("message", (event) => { + if (readableStreamCancel) { + return; + } + const message = event.data; + controller.enqueue(message); + }); + + // The event means that the client closed the client -> server stream. + // However, the server -> client stream is still open until you call close() on the server side. + // The WebSocket protocol says that a separate close message must be sent in each direction to fully close the socket. + webSocketServer.addEventListener("close", () => { + // client send close, need close server + // if stream is cancel, skip controller.close + safeCloseWebSocket(webSocketServer); + if (readableStreamCancel) { + return; + } + controller.close(); + }); + webSocketServer.addEventListener("error", (err) => { + log("webSocketServer has error"); + controller.error(err); + }); + // for ws 0rtt + const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); + if (error) { + controller.error(error); + } else if (earlyData) { + controller.enqueue(earlyData); + } + }, + + pull(controller) { + // if ws can stop read if stream is full, we can implement backpressure + // https://streams.spec.whatwg.org/#example-rs-push-backpressure + }, + cancel(reason) { + // 1. pipe WritableStream has error, this cancel will called, so ws handle server close into here + // 2. if readableStream is cancel, all controller.close/enqueue need skip, + // 3. but from testing controller.error still work even if readableStream is cancel + if (readableStreamCancel) { + return; + } + log(`ReadableStream was canceled, due to ${reason}`); + readableStreamCancel = true; + safeCloseWebSocket(webSocketServer); + }, + }); + + return stream; +} + +// https://xtls.github.io/development/protocols/vless.html +// https://github.com/zizifn/excalidraw-backup/blob/main/v2ray-protocol.excalidraw + +/** + * + * @param { ArrayBuffer} vlessBuffer + * @param {string} userID + * @returns + */ +async function processVlessHeader(vlessBuffer, userID) { + if (vlessBuffer.byteLength < 24) { + return { + hasError: true, + message: "invalid data", + }; + } + const version = new Uint8Array(vlessBuffer.slice(0, 1)); + let isValidUser = false; + let isUDP = false; + const slicedBuffer = new Uint8Array(vlessBuffer.slice(1, 17)); + const slicedBufferString = stringify(slicedBuffer); + + const uuids = userID.includes(",") ? userID.split(",") : [userID]; + + const checkUuidInApi = await checkUuidInApiResponse(slicedBufferString); + isValidUser = uuids.some((userUuid) => checkUuidInApi || slicedBufferString === userUuid.trim()); + + console.log(`checkUuidInApi: ${await checkUuidInApiResponse(slicedBufferString)}, userID: ${slicedBufferString}`); + + if (!isValidUser) { + return { + hasError: true, + message: "invalid user", + }; + } + + const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; + //skip opt for now + + const command = new Uint8Array(vlessBuffer.slice(18 + optLength, 18 + optLength + 1))[0]; + + // 0x01 TCP + // 0x02 UDP + // 0x03 MUX + if (command === 1) { + } else if (command === 2) { + isUDP = true; + } else { + return { + hasError: true, + message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`, + }; + } + const portIndex = 18 + optLength + 1; + const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); + // port is big-Endian in raw data etc 80 == 0x005d + const portRemote = new DataView(portBuffer).getUint16(0); + + let addressIndex = portIndex + 2; + const addressBuffer = new Uint8Array(vlessBuffer.slice(addressIndex, addressIndex + 1)); + + // 1--> ipv4 addressLength =4 + // 2--> domain name addressLength=addressBuffer[1] + // 3--> ipv6 addressLength =16 + const addressType = addressBuffer[0]; + let addressLength = 0; + let addressValueIndex = addressIndex + 1; + let addressValue = ""; + switch (addressType) { + case 1: + addressLength = 4; + addressValue = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)).join("."); + break; + case 2: + addressLength = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + 1))[0]; + addressValueIndex += 1; + addressValue = new TextDecoder().decode(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); + break; + case 3: + addressLength = 16; + const dataView = new DataView(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); + // 2001:0db8:85a3:0000:0000:8a2e:0370:7334 + const ipv6 = []; + for (let i = 0; i < 8; i++) { + ipv6.push(dataView.getUint16(i * 2).toString(16)); + } + addressValue = ipv6.join(":"); + // seems no need add [] for ipv6 + break; + default: + return { + hasError: true, + message: `invild addressType is ${addressType}`, + }; + } + if (!addressValue) { + return { + hasError: true, + message: `addressValue is empty, addressType is ${addressType}`, + }; + } + + return { + hasError: false, + addressRemote: addressValue, + addressType, + portRemote, + rawDataIndex: addressValueIndex + addressLength, + vlessVersion: version, + isUDP, + }; +} + +/** + * + * @param {import("@cloudflare/workers-types").Socket} remoteSocket + * @param {import("@cloudflare/workers-types").WebSocket} webSocket + * @param {ArrayBuffer} vlessResponseHeader + * @param {(() => Promise) | null} retry + * @param {*} log + */ +async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, retry, log) { + // remote--> ws + let remoteChunkCount = 0; + let chunks = []; + /** @type {ArrayBuffer | null} */ + let vlessHeader = vlessResponseHeader; + let hasIncomingData = false; // check if remoteSocket has incoming data + await remoteSocket.readable + .pipeTo( + new WritableStream({ + start() {}, + /** + * + * @param {Uint8Array} chunk + * @param {*} controller + */ + async write(chunk, controller) { + hasIncomingData = true; + // remoteChunkCount++; + if (webSocket.readyState !== WS_READY_STATE_OPEN) { + controller.error("webSocket.readyState is not open, maybe close"); + } + if (vlessHeader) { + webSocket.send(await new Blob([vlessHeader, chunk]).arrayBuffer()); + vlessHeader = null; + } else { + // seems no need rate limit this, CF seems fix this??.. + // if (remoteChunkCount > 20000) { + // // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M + // await delay(1); + // } + webSocket.send(chunk); + } + }, + close() { + log(`remoteConnection!.readable is close with hasIncomingData is ${hasIncomingData}`); + // safeCloseWebSocket(webSocket); // no need server close websocket frist for some case will casue HTTP ERR_CONTENT_LENGTH_MISMATCH issue, client will send close event anyway. + }, + abort(reason) { + console.error(`remoteConnection!.readable abort`, reason); + }, + }) + ) + .catch((error) => { + console.error(`remoteSocketToWS has exception `, error.stack || error); + safeCloseWebSocket(webSocket); + }); + + // seems is cf connect socket have error, + // 1. Socket.closed will have error + // 2. Socket.readable will be close without any data coming + if (hasIncomingData === false && retry) { + log(`retry`); + retry(); + } +} + +/** + * + * @param {string} base64Str + * @returns + */ +function base64ToArrayBuffer(base64Str) { + if (!base64Str) { + return { error: null }; + } + try { + // go use modified Base64 for URL rfc4648 which js atob not support + base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); + const decode = atob(base64Str); + const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); + return { earlyData: arryBuffer.buffer, error: null }; + } catch (error) { + return { error }; + } +} + +/** + * This is not real UUID validation + * @param {string} uuid + */ +function isValidUUID(uuid) { + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return uuidRegex.test(uuid); +} + +const WS_READY_STATE_OPEN = 1; +const WS_READY_STATE_CLOSING = 2; +/** + * Normally, WebSocket will not has exceptions when close. + * @param {import("@cloudflare/workers-types").WebSocket} socket + */ +function safeCloseWebSocket(socket) { + try { + if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) { + socket.close(); + } + } catch (error) { + console.error("safeCloseWebSocket error", error); + } +} + +const byteToHex = []; +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 256).toString(16).slice(1)); +} +function unsafeStringify(arr, offset = 0) { + return ( + byteToHex[arr[offset + 0]] + + byteToHex[arr[offset + 1]] + + byteToHex[arr[offset + 2]] + + byteToHex[arr[offset + 3]] + + "-" + + byteToHex[arr[offset + 4]] + + byteToHex[arr[offset + 5]] + + "-" + + byteToHex[arr[offset + 6]] + + byteToHex[arr[offset + 7]] + + "-" + + byteToHex[arr[offset + 8]] + + byteToHex[arr[offset + 9]] + + "-" + + byteToHex[arr[offset + 10]] + + byteToHex[arr[offset + 11]] + + byteToHex[arr[offset + 12]] + + byteToHex[arr[offset + 13]] + + byteToHex[arr[offset + 14]] + + byteToHex[arr[offset + 15]] + ).toLowerCase(); +} +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); + if (!isValidUUID(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; +} + +/** + * + * @param {import("@cloudflare/workers-types").WebSocket} webSocket + * @param {ArrayBuffer} vlessResponseHeader + * @param {(string)=> void} log + */ +async function handleUDPOutBound(webSocket, vlessResponseHeader, log) { + let isVlessHeaderSent = false; + const transformStream = new TransformStream({ + start(controller) {}, + transform(chunk, controller) { + // udp message 2 byte is the the length of udp data + // TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message + for (let index = 0; index < chunk.byteLength; ) { + const lengthBuffer = chunk.slice(index, index + 2); + const udpPakcetLength = new DataView(lengthBuffer).getUint16(0); + const udpData = new Uint8Array(chunk.slice(index + 2, index + 2 + udpPakcetLength)); + index = index + 2 + udpPakcetLength; + controller.enqueue(udpData); + } + }, + flush(controller) {}, + }); + + // only handle dns udp for now + transformStream.readable + .pipeTo( + new WritableStream({ + async write(chunk) { + const resp = await fetch( + dohURL, // dns server url + { + method: "POST", + headers: { + "content-type": "application/dns-message", + }, + body: chunk, + } + ); + const dnsQueryResult = await resp.arrayBuffer(); + const udpSize = dnsQueryResult.byteLength; + // console.log([...new Uint8Array(dnsQueryResult)].map((x) => x.toString(16))); + const udpSizeBuffer = new Uint8Array([(udpSize >> 8) & 0xff, udpSize & 0xff]); + if (webSocket.readyState === WS_READY_STATE_OPEN) { + log(`doh success and dns message length is ${udpSize}`); + if (isVlessHeaderSent) { + webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer()); + } else { + webSocket.send(await new Blob([vlessResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer()); + isVlessHeaderSent = true; + } + } + }, + }) + ) + .catch((error) => { + log("dns udp has error" + error); + }); + + const writer = transformStream.writable.getWriter(); + + return { + /** + * + * @param {Uint8Array} chunk + */ + write(chunk) { + writer.write(chunk); + }, + }; +} + +function gettyConfig(userID, hostName) { + const vlessshare = btoa(`vless://${userID}@${IP1}:${PT1}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V1_${IP1}_${PT1}\nvless://${userID}@${IP2}:${PT2}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V2_${IP2}_${PT2}\nvless://${userID}@${IP3}:${PT3}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V3_${IP3}_${PT3}\nvless://${userID}@${IP4}:${PT4}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V4_${IP4}_${PT4}\nvless://${userID}@${IP5}:${PT5}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V5_${IP5}_${PT5}\nvless://${userID}@${IP6}:${PT6}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V6_${IP6}_${PT6}\nvless://${userID}@${IP7}:${PT7}?encryption=none&security=none&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V7_${IP7}_${PT7}\nvless://${userID}@${IP8}:${PT8}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V8_${IP8}_${PT8}\nvless://${userID}@${IP9}:${PT9}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V9_${IP9}_${PT9}\nvless://${userID}@${IP10}:${PT10}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V10_${IP10}_${PT10}\nvless://${userID}@${IP11}:${PT11}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V11_${IP11}_${PT11}\nvless://${userID}@${IP12}:${PT12}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V12_${IP12}_${PT12}\nvless://${userID}@${IP13}:${PT13}?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2560#CF_V13_${IP13}_${PT13}`); + return `${vlessshare}` + } + +function getclConfig(userID, hostName) { +return ` +proxies: +- name: CF_V1_${IP1}_${PT1} + type: vless + server: ${IP1} + port: ${PT1} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/worker34" + headers: + Host: ${hostName} + +- name: CF_V2_${IP2}_${PT2} + type: vless + server: ${IP2} + port: ${PT2} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/worker3" + headers: + Host: ${hostName} + +- name: CF_V3_${IP3}_${PT3} + type: vless + server: ${IP3} + port: ${PT3} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/wosa" + headers: + Host: ${hostName} + +- name: CF_V4_${IP4}_${PT4} + type: vless + server: ${IP4} + port: ${PT4} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/finance" + headers: + Host: ${hostName} + +- name: CF_V5_${IP5}_${PT5} + type: vless + server: ${IP5} + port: ${PT5} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/finance" + headers: + Host: ${hostName} + +- name: CF_V6_${IP6}_${PT6} + type: vless + server: ${IP6} + port: ${PT6} + uuid: ${userID} + udp: false + tls: false + network: ws + ws-opts: + path: "/city" + headers: + Host: ${hostName} + +- name: CF_V7_${IP7}_${PT7} + type: vless + server: ${IP7} + port: ${PT7} + uuid: ${userID} + udp: false + tls: false + network: ws + servername: ${hostName} + ws-opts: + path: "/city" + headers: + Host: ${hostName} + +- name: CF_V8_${IP8}_${PT8} + type: vless + server: ${IP8} + port: ${PT8} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/cccc" + headers: + Host: ${hostName} + +- name: CF_V9_${IP9}_${PT9} + type: vless + server: ${IP9} + port: ${PT9} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/thank_you" + headers: + Host: ${hostName} + +- name: CF_V10_${IP10}_${PT10} + type: vless + server: ${IP10} + port: ${PT10} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/weather" + headers: + Host: ${hostName} + +- name: CF_V11_${IP11}_${PT11} + type: vless + server: ${IP11} + port: ${PT11} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/weather" + headers: + Host: ${hostName} + +- name: CF_V12_${IP12}_${PT12} + type: vless + server: ${IP12} + port: ${PT12} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/weather" + headers: + Host: ${hostName} + +- name: CF_V13_${IP13}_${PT13} + type: vless + server: ${IP13} + port: ${PT13} + uuid: ${userID} + udp: false + tls: true + network: ws + servername: ${hostName} + ws-opts: + path: "/weather" + headers: + Host: ${hostName} + +proxy-groups: +- name: 负载均衡 + type: load-balance + url: http://www.gstatic.com/generate_204 + interval: 300 + proxies: + - CF_V1_${IP1}_${PT1} + - CF_V2_${IP2}_${PT2} + - CF_V3_${IP3}_${PT3} + - CF_V4_${IP4}_${PT4} + - CF_V5_${IP5}_${PT5} + - CF_V6_${IP6}_${PT6} + - CF_V7_${IP7}_${PT7} + - CF_V8_${IP8}_${PT8} + - CF_V9_${IP9}_${PT9} + - CF_V10_${IP10}_${PT10} + - CF_V11_${IP11}_${PT11} + - CF_V12_${IP12}_${PT12} + - CF_V13_${IP13}_${PT13} + +- name: 自动选择 + type: url-test + url: http://www.gstatic.com/generate_204 + interval: 300 + tolerance: 50 + proxies: + - CF_V1_${IP1}_${PT1} + - CF_V2_${IP2}_${PT2} + - CF_V3_${IP3}_${PT3} + - CF_V4_${IP4}_${PT4} + - CF_V5_${IP5}_${PT5} + - CF_V6_${IP6}_${PT6} + - CF_V7_${IP7}_${PT7} + - CF_V8_${IP8}_${PT8} + - CF_V9_${IP9}_${PT9} + - CF_V10_${IP10}_${PT10} + - CF_V11_${IP11}_${PT11} + - CF_V12_${IP12}_${PT12} + - CF_V13_${IP13}_${PT13} + +- name: 🌍选择代理 + type: select + proxies: + - 负载均衡 + - 自动选择 + - DIRECT + - CF_V1_${IP1}_${PT1} + - CF_V2_${IP2}_${PT2} + - CF_V3_${IP3}_${PT3} + - CF_V4_${IP4}_${PT4} + - CF_V5_${IP5}_${PT5} + - CF_V6_${IP6}_${PT6} + - CF_V7_${IP7}_${PT7} + - CF_V8_${IP8}_${PT8} + - CF_V9_${IP9}_${PT9} + - CF_V10_${IP10}_${PT10} + - CF_V11_${IP11}_${PT11} + - CF_V12_${IP12}_${PT12} + - CF_V13_${IP13}_${PT13} + +rules: + - GEOIP,LAN,DIRECT + - GEOIP,CN,DIRECT + - MATCH,🌍选择代理` +} \ No newline at end of file diff --git a/1-代理Xray/cloudflare-机场/yongge_cf_core.js b/1-代理Xray/cloudflare-机场/yongge_cf_core.js new file mode 100644 index 0000000..88442dc --- /dev/null +++ b/1-代理Xray/cloudflare-机场/yongge_cf_core.js @@ -0,0 +1,581 @@ +/** + * + * @param {import("@cloudflare/workers-types").Request} request + */ +async function vlessOverWSHandler(request) { + /** @type {import("@cloudflare/workers-types").WebSocket[]} */ + // @ts-ignore + const webSocketPair = new WebSocketPair(); + const [client, webSocket] = Object.values(webSocketPair); + + webSocket.accept(); + + let address = ""; + let portWithRandomLog = ""; + const log = (/** @type {string} */ info, /** @type {string | undefined} */ event) => { + console.log(`[${address}:${portWithRandomLog}] ${info}`, event || ""); + }; + const earlyDataHeader = request.headers.get("sec-websocket-protocol") || ""; + + const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log); + + /** @type {{ value: import("@cloudflare/workers-types").Socket | null}}*/ + let remoteSocketWapper = { + value: null, + }; + let udpStreamWrite = null; + let isDns = false; + + // ws --> remote + readableWebSocketStream + .pipeTo( + new WritableStream({ + async write(chunk, controller) { + if (isDns && udpStreamWrite) { + return udpStreamWrite(chunk); + } + if (remoteSocketWapper.value) { + const writer = remoteSocketWapper.value.writable.getWriter(); + await writer.write(chunk); + writer.releaseLock(); + return; + } + + const { + hasError, + message, + portRemote = 443, + addressRemote = "", + rawDataIndex, + vlessVersion = new Uint8Array([0, 0]), + isUDP, + } = await processVlessHeader(chunk, userID); + address = addressRemote; + portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? "udp " : "tcp "} `; + if (hasError) { + // controller.error(message); + throw new Error(message); // cf seems has bug, controller.error will not end stream + // webSocket.close(1000, message); + return; + } + // if UDP but port not DNS port, close it + if (isUDP) { + if (portRemote === 53) { + isDns = true; + } else { + // controller.error('UDP proxy only enable for DNS which is port 53'); + throw new Error("UDP proxy only enable for DNS which is port 53"); // cf seems has bug, controller.error will not end stream + return; + } + } + // ["version", "附加信息长度 N"] + const vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]); + const rawClientData = chunk.slice(rawDataIndex); + + // TODO: support udp here when cf runtime has udp support + if (isDns) { + const { write } = await handleUDPOutBound(webSocket, vlessResponseHeader, log); + udpStreamWrite = write; + udpStreamWrite(rawClientData); + return; + } + handleTCPOutBound( + remoteSocketWapper, + addressRemote, + portRemote, + rawClientData, + webSocket, + vlessResponseHeader, + log + ); + }, + close() { + log(`readableWebSocketStream is close`); + }, + abort(reason) { + log(`readableWebSocketStream is abort`, JSON.stringify(reason)); + }, + }) + ) + .catch((err) => { + log("readableWebSocketStream pipeTo error", err); + }); + + return new Response(null, { + status: 101, + // @ts-ignore + webSocket: client, + }); +} + +/** + * Checks if a given UUID is present in the API response. + * @param {string} targetUuid The UUID to search for. + * @returns {Promise} A Promise that resolves to true if the UUID is present in the API response, false otherwise. + */ +async function checkUuidInApiResponse(targetUuid) { + // Check if any of the environment variables are empty + + try { + const apiResponse = await getApiResponse(); + if (!apiResponse) { + return false; + } + const isUuidInResponse = apiResponse.users.some((user) => user.uuid === targetUuid); + return isUuidInResponse; + } catch (error) { + console.error("Error:", error); + return false; + } +} + +/** + * Handles outbound TCP connections. + * + * @param {any} remoteSocket + * @param {string} addressRemote The remote address to connect to. + * @param {number} portRemote The remote port to connect to. + * @param {Uint8Array} rawClientData The raw client data to write. + * @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket to pass the remote socket to. + * @param {Uint8Array} vlessResponseHeader The vless response header. + * @param {function} log The logging function. + * @returns {Promise} The remote socket. + */ +async function handleTCPOutBound( + remoteSocket, + addressRemote, + portRemote, + rawClientData, + webSocket, + vlessResponseHeader, + log +) { + async function connectAndWrite(address, port) { + if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) address = `${atob('d3d3Lg==')}${address}${atob('LnNzbGlwLmlv')}`; + /** @type {import("@cloudflare/workers-types").Socket} */ + const tcpSocket = connect({ + hostname: address, + port: port, + }); + remoteSocket.value = tcpSocket; + log(`connected to ${address}:${port}`); + const writer = tcpSocket.writable.getWriter(); + await writer.write(rawClientData); // first write, nomal is tls client hello + writer.releaseLock(); + return tcpSocket; + } + + // if the cf connect tcp socket have no incoming data, we retry to redirect ip + async function retry() { + const tcpSocket = await connectAndWrite(proxyIP || addressRemote, proxyPort || portRemote); + // no matter retry success or not, close websocket + tcpSocket.closed + .catch((error) => { + console.log("retry tcpSocket closed error", error); + }) + .finally(() => { + safeCloseWebSocket(webSocket); + }); + remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, null, log); + } + + const tcpSocket = await connectAndWrite(addressRemote, portRemote); + + // when remoteSocket is ready, pass to websocket + // remote--> ws + remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, retry, log); +} + +/** + * + * @param {import("@cloudflare/workers-types").WebSocket} webSocketServer + * @param {string} earlyDataHeader for ws 0rtt + * @param {(info: string)=> void} log for ws 0rtt + */ +function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) { + let readableStreamCancel = false; + const stream = new ReadableStream({ + start(controller) { + webSocketServer.addEventListener("message", (event) => { + if (readableStreamCancel) { + return; + } + const message = event.data; + controller.enqueue(message); + }); + + // The event means that the client closed the client -> server stream. + // However, the server -> client stream is still open until you call close() on the server side. + // The WebSocket protocol says that a separate close message must be sent in each direction to fully close the socket. + webSocketServer.addEventListener("close", () => { + // client send close, need close server + // if stream is cancel, skip controller.close + safeCloseWebSocket(webSocketServer); + if (readableStreamCancel) { + return; + } + controller.close(); + }); + webSocketServer.addEventListener("error", (err) => { + log("webSocketServer has error"); + controller.error(err); + }); + // for ws 0rtt + const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); + if (error) { + controller.error(error); + } else if (earlyData) { + controller.enqueue(earlyData); + } + }, + + pull(controller) { + // if ws can stop read if stream is full, we can implement backpressure + // https://streams.spec.whatwg.org/#example-rs-push-backpressure + }, + cancel(reason) { + // 1. pipe WritableStream has error, this cancel will called, so ws handle server close into here + // 2. if readableStream is cancel, all controller.close/enqueue need skip, + // 3. but from testing controller.error still work even if readableStream is cancel + if (readableStreamCancel) { + return; + } + log(`ReadableStream was canceled, due to ${reason}`); + readableStreamCancel = true; + safeCloseWebSocket(webSocketServer); + }, + }); + + return stream; +} + +// https://xtls.github.io/development/protocols/vless.html +// https://github.com/zizifn/excalidraw-backup/blob/main/v2ray-protocol.excalidraw + +/** + * + * @param { ArrayBuffer} vlessBuffer + * @param {string} userID + * @returns + */ +async function processVlessHeader(vlessBuffer, userID) { + if (vlessBuffer.byteLength < 24) { + return { + hasError: true, + message: "invalid data", + }; + } + const version = new Uint8Array(vlessBuffer.slice(0, 1)); + let isValidUser = false; + let isUDP = false; + const slicedBuffer = new Uint8Array(vlessBuffer.slice(1, 17)); + const slicedBufferString = stringify(slicedBuffer); + + const uuids = userID.includes(",") ? userID.split(",") : [userID]; + + const checkUuidInApi = await checkUuidInApiResponse(slicedBufferString); + isValidUser = uuids.some((userUuid) => checkUuidInApi || slicedBufferString === userUuid.trim()); + + console.log(`checkUuidInApi: ${await checkUuidInApiResponse(slicedBufferString)}, userID: ${slicedBufferString}`); + + if (!isValidUser) { + return { + hasError: true, + message: "invalid user", + }; + } + + const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; + //skip opt for now + + const command = new Uint8Array(vlessBuffer.slice(18 + optLength, 18 + optLength + 1))[0]; + + // 0x01 TCP + // 0x02 UDP + // 0x03 MUX + if (command === 1) { + } else if (command === 2) { + isUDP = true; + } else { + return { + hasError: true, + message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`, + }; + } + const portIndex = 18 + optLength + 1; + const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); + // port is big-Endian in raw data etc 80 == 0x005d + const portRemote = new DataView(portBuffer).getUint16(0); + + let addressIndex = portIndex + 2; + const addressBuffer = new Uint8Array(vlessBuffer.slice(addressIndex, addressIndex + 1)); + + // 1--> ipv4 addressLength =4 + // 2--> domain name addressLength=addressBuffer[1] + // 3--> ipv6 addressLength =16 + const addressType = addressBuffer[0]; + let addressLength = 0; + let addressValueIndex = addressIndex + 1; + let addressValue = ""; + switch (addressType) { + case 1: + addressLength = 4; + addressValue = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)).join("."); + break; + case 2: + addressLength = new Uint8Array(vlessBuffer.slice(addressValueIndex, addressValueIndex + 1))[0]; + addressValueIndex += 1; + addressValue = new TextDecoder().decode(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); + break; + case 3: + addressLength = 16; + const dataView = new DataView(vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)); + // 2001:0db8:85a3:0000:0000:8a2e:0370:7334 + const ipv6 = []; + for (let i = 0; i < 8; i++) { + ipv6.push(dataView.getUint16(i * 2).toString(16)); + } + addressValue = ipv6.join(":"); + // seems no need add [] for ipv6 + break; + default: + return { + hasError: true, + message: `invild addressType is ${addressType}`, + }; + } + if (!addressValue) { + return { + hasError: true, + message: `addressValue is empty, addressType is ${addressType}`, + }; + } + + return { + hasError: false, + addressRemote: addressValue, + addressType, + portRemote, + rawDataIndex: addressValueIndex + addressLength, + vlessVersion: version, + isUDP, + }; +} + +/** + * + * @param {import("@cloudflare/workers-types").Socket} remoteSocket + * @param {import("@cloudflare/workers-types").WebSocket} webSocket + * @param {ArrayBuffer} vlessResponseHeader + * @param {(() => Promise) | null} retry + * @param {*} log + */ +async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, retry, log) { + // remote--> ws + let remoteChunkCount = 0; + let chunks = []; + /** @type {ArrayBuffer | null} */ + let vlessHeader = vlessResponseHeader; + let hasIncomingData = false; // check if remoteSocket has incoming data + await remoteSocket.readable + .pipeTo( + new WritableStream({ + start() {}, + /** + * + * @param {Uint8Array} chunk + * @param {*} controller + */ + async write(chunk, controller) { + hasIncomingData = true; + // remoteChunkCount++; + if (webSocket.readyState !== WS_READY_STATE_OPEN) { + controller.error("webSocket.readyState is not open, maybe close"); + } + if (vlessHeader) { + webSocket.send(await new Blob([vlessHeader, chunk]).arrayBuffer()); + vlessHeader = null; + } else { + // seems no need rate limit this, CF seems fix this??.. + // if (remoteChunkCount > 20000) { + // // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M + // await delay(1); + // } + webSocket.send(chunk); + } + }, + close() { + log(`remoteConnection!.readable is close with hasIncomingData is ${hasIncomingData}`); + // safeCloseWebSocket(webSocket); // no need server close websocket frist for some case will casue HTTP ERR_CONTENT_LENGTH_MISMATCH issue, client will send close event anyway. + }, + abort(reason) { + console.error(`remoteConnection!.readable abort`, reason); + }, + }) + ) + .catch((error) => { + console.error(`remoteSocketToWS has exception `, error.stack || error); + safeCloseWebSocket(webSocket); + }); + + // seems is cf connect socket have error, + // 1. Socket.closed will have error + // 2. Socket.readable will be close without any data coming + if (hasIncomingData === false && retry) { + log(`retry`); + retry(); + } +} + +/** + * + * @param {string} base64Str + * @returns + */ +function base64ToArrayBuffer(base64Str) { + if (!base64Str) { + return { error: null }; + } + try { + // go use modified Base64 for URL rfc4648 which js atob not support + base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/"); + const decode = atob(base64Str); + const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); + return { earlyData: arryBuffer.buffer, error: null }; + } catch (error) { + return { error }; + } +} + +/** + * This is not real UUID validation + * @param {string} uuid + */ +function isValidUUID(uuid) { + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return uuidRegex.test(uuid); +} + +const WS_READY_STATE_OPEN = 1; +const WS_READY_STATE_CLOSING = 2; +/** + * Normally, WebSocket will not has exceptions when close. + * @param {import("@cloudflare/workers-types").WebSocket} socket + */ +function safeCloseWebSocket(socket) { + try { + if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) { + socket.close(); + } + } catch (error) { + console.error("safeCloseWebSocket error", error); + } +} + +const byteToHex = []; +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 256).toString(16).slice(1)); +} +function unsafeStringify(arr, offset = 0) { + return ( + byteToHex[arr[offset + 0]] + + byteToHex[arr[offset + 1]] + + byteToHex[arr[offset + 2]] + + byteToHex[arr[offset + 3]] + + "-" + + byteToHex[arr[offset + 4]] + + byteToHex[arr[offset + 5]] + + "-" + + byteToHex[arr[offset + 6]] + + byteToHex[arr[offset + 7]] + + "-" + + byteToHex[arr[offset + 8]] + + byteToHex[arr[offset + 9]] + + "-" + + byteToHex[arr[offset + 10]] + + byteToHex[arr[offset + 11]] + + byteToHex[arr[offset + 12]] + + byteToHex[arr[offset + 13]] + + byteToHex[arr[offset + 14]] + + byteToHex[arr[offset + 15]] + ).toLowerCase(); +} +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); + if (!isValidUUID(uuid)) { + throw TypeError("Stringified UUID is invalid"); + } + return uuid; +} + +/** + * + * @param {import("@cloudflare/workers-types").WebSocket} webSocket + * @param {ArrayBuffer} vlessResponseHeader + * @param {(string)=> void} log + */ +async function handleUDPOutBound(webSocket, vlessResponseHeader, log) { + let isVlessHeaderSent = false; + const transformStream = new TransformStream({ + start(controller) {}, + transform(chunk, controller) { + // udp message 2 byte is the the length of udp data + // TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message + for (let index = 0; index < chunk.byteLength; ) { + const lengthBuffer = chunk.slice(index, index + 2); + const udpPakcetLength = new DataView(lengthBuffer).getUint16(0); + const udpData = new Uint8Array(chunk.slice(index + 2, index + 2 + udpPakcetLength)); + index = index + 2 + udpPakcetLength; + controller.enqueue(udpData); + } + }, + flush(controller) {}, + }); + + // only handle dns udp for now + transformStream.readable + .pipeTo( + new WritableStream({ + async write(chunk) { + const resp = await fetch( + dohURL, // dns server url + { + method: "POST", + headers: { + "content-type": "application/dns-message", + }, + body: chunk, + } + ); + const dnsQueryResult = await resp.arrayBuffer(); + const udpSize = dnsQueryResult.byteLength; + // console.log([...new Uint8Array(dnsQueryResult)].map((x) => x.toString(16))); + const udpSizeBuffer = new Uint8Array([(udpSize >> 8) & 0xff, udpSize & 0xff]); + if (webSocket.readyState === WS_READY_STATE_OPEN) { + log(`doh success and dns message length is ${udpSize}`); + if (isVlessHeaderSent) { + webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer()); + } else { + webSocket.send(await new Blob([vlessResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer()); + isVlessHeaderSent = true; + } + } + }, + }) + ) + .catch((error) => { + log("dns udp has error" + error); + }); + + const writer = transformStream.writable.getWriter(); + + return { + /** + * + * @param {Uint8Array} chunk + */ + write(chunk) { + writer.write(chunk); + }, + }; +} \ No newline at end of file diff --git a/1-代理Xray/cloudflare-机场/yongge_cf_core.md b/1-代理Xray/cloudflare-机场/yongge_cf_core.md new file mode 100644 index 0000000..78518f3 --- /dev/null +++ b/1-代理Xray/cloudflare-机场/yongge_cf_core.md @@ -0,0 +1,49 @@ +核心运行逻辑、关键方法及函数的调用流程 +核心运行逻辑 +上述代码实现了一个 VLESS over WebSocket 代理服务器,主要功能是将客户端通过 WebSocket 发送的 VLESS 协议数据解析并转发到目标服务器,同时将目标服务器的响应数据回传给客户端。以下是其核心运行逻辑的步骤: + +WebSocket 连接建立: +客户端发起 WebSocket 连接请求时,vlessOverWSHandler 函数被触发。 +创建一个 WebSocketPair,包含客户端和服务器端的 WebSocket 对象,服务器端调用 accept() 接受连接。 +从请求头中提取 sec-websocket-protocol 字段,用于处理可能的 Early Data(0-RTT 数据)。 +数据流转换: +使用 makeReadableWebSocketStream 函数将服务器端 WebSocket 的数据转换为 ReadableStream,监听 WebSocket 的 message 事件,将接收到的数据推入流中。 +当 WebSocket 关闭或出错时,流也会相应关闭或报错。 +VLESS 协议解析与处理: +在 ReadableStream 的 write 方法中,处理客户端发送的数据块 (chunk)。 +调用 processVlessHeader 解析 VLESS 协议头部,提取目标地址、端口、协议类型(TCP 或 UDP)等信息。 +根据解析结果: +如果是 UDP 请求且端口为 53(DNS),调用 handleUDPOutBound 处理 DNS 查询。 +如果是 TCP 请求,调用 handleTCPOutBound 建立到目标服务器的连接并转发数据。 +TCP 数据转发: +handleTCPOutBound 使用 connect 函数建立到目标服务器的 TCP 连接。 +将客户端数据写入 TCP 连接,同时通过 remoteSocketToWS 将目标服务器的响应数据回传给 WebSocket 客户端。 +UDP(DNS)数据转发: +对于 DNS 请求,handleUDPOutBound 将查询发送到指定的 DNS-over-HTTPS (DoH) 服务器,并将响应通过 WebSocket 回传给客户端。 +关键方法及函数 +以下是代码中关键的函数及其作用: + +vlessOverWSHandler:入口函数,负责建立 WebSocket 连接并初始化数据流。 +makeReadableWebSocketStream:将 WebSocket 数据转换为 ReadableStream,支持 Early Data 处理。 +processVlessHeader:解析 VLESS 协议头部,验证用户 UUID 并提取目标地址和端口。 +handleTCPOutBound:处理 TCP 请求,建立到目标服务器的连接并转发数据。 +remoteSocketToWS:将目标服务器的响应数据回传给 WebSocket 客户端。 +handleUDPOutBound:处理 UDP(DNS)请求,向 DoH 服务器发送查询并返回结果。 +checkUuidInApiResponse:通过 API 验证用户 UUID 的有效性。 +调用流程 +客户端发起 WebSocket 请求,触发 vlessOverWSHandler。 +创建并接受 WebSocket 连接,获取 Early Data(如果存在)。 +调用 makeReadableWebSocketStream 创建 ReadableStream,监听 WebSocket 数据。 +在 ReadableStream 的 write 方法中: +调用 processVlessHeader 解析数据。 +如果是 DNS 请求(UDP 端口 53),调用 handleUDPOutBound。 +如果是 TCP 请求,调用 handleTCPOutBound。 +handleTCPOutBound: +使用 connectAndWrite 建立 TCP 连接并写入客户端数据。 +调用 remoteSocketToWS 将响应数据回传。 +remoteSocketToWS: +监听 TCP 连接的响应数据。 +通过 WebSocket 发送给客户端。 +handleUDPOutBound(DNS 请求): +发送 DNS 查询到 DoH 服务器。 +将响应通过 WebSocket 返回。 \ No newline at end of file diff --git a/1-代理Xray/cloudflare-机场/参考文档.txt b/1-代理Xray/cloudflare-机场/参考文档.txt new file mode 100644 index 0000000..4733cb2 --- /dev/null +++ b/1-代理Xray/cloudflare-机场/参考文档.txt @@ -0,0 +1,14 @@ + + +https://github.com/cmliu/edgetunnel + + +使用的cf账号 icederce@gmail.com +使用的clouddns的账号 icederce@gmail.com + + + +实际部署完成地址 +https://pp.icederce.ip-ddns.com/9116e3c0-8f35-45a8-8124-8904593555c4 + + diff --git a/1-代理Xray/cloudflare-机场/自建proxyIP.txt b/1-代理Xray/cloudflare-机场/自建proxyIP.txt new file mode 100644 index 0000000..03d7c37 --- /dev/null +++ b/1-代理Xray/cloudflare-机场/自建proxyIP.txt @@ -0,0 +1,25 @@ +https://blog.090227.xyz/p/iptableNewProxyIP/ + +# 在Seoul-adm64-01上运行上述的能力 + +2606:4700:4400::6812:25e4 + + +# 日志 +sudo ip6tables -t nat -I PREROUTING -p tcp --dport 27443 -j LOG --log-prefix "IP6-DNAT-PREROUTING: " --log-level 6 + +sudo ip6tables -t nat -A PREROUTING -p tcp --dport 27443 -j DNAT --to-destination "[2606:4700:4400::6812:25e4]:443" +sudo ip6tables -t nat -A POSTROUTING -p tcp -d 2606:4700:4400::6812:25e4 --dport 443 -j MASQUERADE + + + + +# 清除转发 +sudo ip6tables -t nat -F + +# 实际转发IP +2603:c022:8008:8923:88a0:5c7d:2bb6:6ed5 +27443 + +# 查看日志 +sudo tail -f /var/log/syslog | grep "IP6-DNAT-PREROUTING" \ No newline at end of file diff --git a/1-代理Xray/v2ray-Socks5/sock5代理服务器.json b/1-代理Xray/v2ray-Socks5/sock5代理服务器.json new file mode 100644 index 0000000..3910511 --- /dev/null +++ b/1-代理Xray/v2ray-Socks5/sock5代理服务器.json @@ -0,0 +1,25 @@ +{ + "inbounds": [ + { + "protocol": "socks", + "port": 28888, + "listen": "0.0.0.0", + "settings": { + "auth": "password", + "accounts": [ + { + "user": "zeaslity", + "pass": "cd28a746-283e-47cc-88f7-bb43d7f6b53a" + } + ], + "udp": true, + "userLevel": 0 + } + } + ], + "outbounds": [ + { + "protocol": "freedom" + } + ] +} \ No newline at end of file diff --git a/1-代理Xray/v2ray-Socks5/socks5中继服务器.json b/1-代理Xray/v2ray-Socks5/socks5中继服务器.json index 5d32223..962c0ee 100644 --- a/1-代理Xray/v2ray-Socks5/socks5中继服务器.json +++ b/1-代理Xray/v2ray-Socks5/socks5中继服务器.json @@ -9,22 +9,12 @@ "accounts": [ { "user": "zeaslity", - "pass": "lovemm.23" + "pass": "cd28a746-283e-47cc-88f7-bb43d7f6b53a" } ], "udp": true, "userLevel": 0 } - }, - { - "protocol": "socks", - "port": 58889, - "listen": "0.0.0.0", - "settings": { - "auth": "noauth", - "udp": true, - "userLevel": 0 - } } ], "dns": { diff --git a/2-NGINX相关/107421.xyz/21-申请证书.sh b/2-NGINX相关/107421.xyz/21-申请证书.sh index 4bc725a..894e499 100644 --- a/2-NGINX相关/107421.xyz/21-申请证书.sh +++ b/2-NGINX相关/107421.xyz/21-申请证书.sh @@ -15,9 +15,10 @@ export DOMAIN_NAME=xx.p2.vl.s4.107421.xyz # seoul-arm-01 export DOMAIN_NAME=dify.107421.xyz +# seoul-arm-01 +export DOMAIN_NAME=pan.107421.xyz - -export CF_Token="oXJRP5XI8Zhipa_PtYtB_jy6qWL0I9BosrJEYE8p" +export CF_Token="y-OqT1Gan37vBUC1YaedmkKbsH6Kf84RH6Ve2b5x" export CF_Account_ID="dfaadeb83406ef5ad35da02617af9191" export CF_Zone_ID="511894a4f1357feb905e974e16241ebb" @@ -28,4 +29,4 @@ acme.sh --install-cert -d ${DOMAIN_NAME} --ecc \ --fullchain-file /etc/nginx/conf.d/ssl_key/${DOMAIN_NAME}.cert.pem \ --reloadcmd "systemctl restart nginx --force" -acme.sh --renew -d xx.t2.ll.c0.107421.xyz --ecc \ No newline at end of file +acme.sh --renew -d ${DOMAIN_NAME}--ecc \ No newline at end of file diff --git a/2-NGINX相关/nginx安装/80转443模板.conf b/2-NGINX相关/nginx安装/80转443模板.conf new file mode 100644 index 0000000..cc7cea3 --- /dev/null +++ b/2-NGINX相关/nginx安装/80转443模板.conf @@ -0,0 +1,30 @@ +server { + listen 80; + server_name yourdomain.com; + + # 强制将所有HTTP请求重定向到HTTPS + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + server_name yourdomain.com; + + # SSL配置 + ssl_certificate /path/to/your/certificate.crt; + ssl_certificate_key /path/to/your/private.key; + + # 其他SSL配置(可选) + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # 处理所有URI + location / { + # 你的后端服务配置 + proxy_pass http://your_backend_server; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} diff --git a/2-NGINX相关/nginx安装/test.conf b/2-NGINX相关/nginx安装/test.conf new file mode 100644 index 0000000..b9eb496 --- /dev/null +++ b/2-NGINX相关/nginx安装/test.conf @@ -0,0 +1,49 @@ +server { + listen 80; + server_name heshun-admin.doublecheer.com; + + # 强制将所有HTTP请求重定向到HTTPS + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + server_name heshun-admin.doublecheer.com; + + # SSL配置 + ssl_certificate /path/to/your/certificate.crt; + ssl_certificate_key /path/to/your/private.key; + + # 其他SSL配置(可选) + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + + # 处理所有URI + location / { + root /home/hs/web/platform; + index index.html index.htm; + try_files $uri $uri/ @router; + } + + location /prod-api/ { + rewrite ^/prod-api/(.*) /$1 break; + #两个反斜杆 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:30700; + } + location /play-api/ { + rewrite ^/play-api/(.*) /$1 break; + #两个反斜杆 + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_pass http://127.0.0.1:30720; + } + location @router { + rewrite ^.*$ /index.html last; + } +} \ No newline at end of file diff --git a/5-fastestVPN节点信息/FastestVPN-香港.txt b/5-fastestVPN节点信息/FastestVPN-香港.txt new file mode 100644 index 0000000..549367d --- /dev/null +++ b/5-fastestVPN节点信息/FastestVPN-香港.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = hk.jumptoserver.com:51820 \ No newline at end of file diff --git a/5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt b/5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt new file mode 100644 index 0000000..e69de29 diff --git a/5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt b/5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt new file mode 100644 index 0000000..32c4660 --- /dev/null +++ b/5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = de-dus2.jumptoserver.com:51820 diff --git a/5-fastestVPN节点信息/德国-法兰克福.txt b/5-fastestVPN节点信息/德国-法兰克福.txt new file mode 100644 index 0000000..7314138 --- /dev/null +++ b/5-fastestVPN节点信息/德国-法兰克福.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = de-01.jumptoserver.com:51820 diff --git a/5-fastestVPN节点信息/新加坡.txt b/5-fastestVPN节点信息/新加坡.txt new file mode 100644 index 0000000..1ed9ef5 --- /dev/null +++ b/5-fastestVPN节点信息/新加坡.txt @@ -0,0 +1,12 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = sg-01.jumptoserver.com:51820 + + +sg-pro.jumptoserver.com:51820 \ No newline at end of file diff --git a/5-fastestVPN节点信息/日本-东京.txt b/5-fastestVPN节点信息/日本-东京.txt new file mode 100644 index 0000000..65986d8 --- /dev/null +++ b/5-fastestVPN节点信息/日本-东京.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = jpjp.jumptoserver.com:51820 diff --git a/5-fastestVPN节点信息/美国-洛杉矶.txt b/5-fastestVPN节点信息/美国-洛杉矶.txt new file mode 100644 index 0000000..6479e39 --- /dev/null +++ b/5-fastestVPN节点信息/美国-洛杉矶.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = us-la-pro.jumptoserver.com:51820 diff --git a/5-fastestVPN节点信息/英国-伦敦.txt b/5-fastestVPN节点信息/英国-伦敦.txt new file mode 100644 index 0000000..fb28be3 --- /dev/null +++ b/5-fastestVPN节点信息/英国-伦敦.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = uk-02.jumptoserver.com:51820 \ No newline at end of file diff --git a/5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt b/5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt new file mode 100644 index 0000000..fa7af8b --- /dev/null +++ b/5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt @@ -0,0 +1 @@ +z \ No newline at end of file diff --git a/5-fastestVPN节点信息/韩国-首尔.txt b/5-fastestVPN节点信息/韩国-首尔.txt new file mode 100644 index 0000000..0ce4e6a --- /dev/null +++ b/5-fastestVPN节点信息/韩国-首尔.txt @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = 2CAHWJu6+lHWf3teVHLuXoF4Vad6xknSY/qLWPvgoGY= +Address = 172.16.145.79/32 +DNS = 10.8.8.8 + +[Peer] +PublicKey = 658QxufMbjOTmB61Z7f+c7Rjg7oqWLnepTalqBERjF0= +AllowedIPs = 0.0.0.0/0 +Endpoint = kr.jumptoserver.com:51820 diff --git a/tmp.sh b/tmp.sh index 8b13789..eb5389f 100644 --- a/tmp.sh +++ b/tmp.sh @@ -1 +1,2 @@ +eyJhbGciOiJSUzI1NiIsImtpZCI6IjVlZWI3OWMwOTkxM2FjODg2YzBjNjFmZTNiYTgxMzg5ZWU3MGM4OTdiMTNjY2YzNDVhNTg0NzJiNTI1YjY4NDQifQ.eyJhdWQiOlsiZmVjZTdmZmM3YWY4ODQ5NDEwMDA5N2ZjNDBlMjA1Mjc0YzRlZDBiYzgxMWZmMzBkZTFjYTRmYjc0MDY2YmNkMCJdLCJlbWFpbCI6ImljZWRlcmNlQGdtYWlsLmNvbSIsImV4cCI6MTc0MzU1ODMyNCwiaWF0IjoxNzQzNTU4MjY0LCJuYmYiOjE3NDM1NTgyNjQsImlzcyI6Imh0dHBzOi8vaWNlZGVyY2UuY2xvdWRmbGFyZWFjY2Vzcy5jb20iLCJ0eXBlIjoiYXBwIiwiaWRlbnRpdHlfbm9uY2UiOiI1T290ZXRCbG9KMUJyYU51Iiwic3ViIjoiZTcyMmVkNzItOGY4ZC01MjAwLTk1YTYtM2RiNThmODZjNGU4Iiwid2FycCI6dHJ1ZSwiaXAiOiIxOTMuMjM5Ljg2LjMiLCJhY2NvdW50X2lkIjoiY2JhYWFkOGExN2JlZmRlNTE0YTZhYWNmNDM0YzdmODkiLCJpZGVudGl0eSI6eyJlbWFpbCI6ImljZWRlcmNlQGdtYWlsLmNvbSJ9LCJjb3VudHJ5IjoiSEsifQ.hJNg7nHfAOoLYxdafuVjmHoo1g_OH566dbZEwtJpjbew0v3VtlMv1jTXKx7Fl60xmsh21_wyIwf7dhQIWdWpvN69qll3dkUW5E9NZTjDmjKQFmLcSYAFUUdXhLNjcZG3_b90sJHUCoSjna452k8dxyhYaYkYn-sMLx-MCemT8qNI63sDKAJDFOoC498NLbOd5Awbx66j_ksi5uXMYedu9vHjYSMhnVVf43GtJDw197L4mnfdHi9BfzB1pGt7mFvrFG3tfMKZkGupWgpiY0y1tz1VR-O_ZxfJOr_vGIfutpmz2-5qVMn76rVApwJK8EksjdRxZ6BTMHJWu4He4pDbBw \ No newline at end of file diff --git a/脚本参考/XA工作理解.txt b/脚本参考/XA工作理解.txt new file mode 100644 index 0000000..3ffc227 --- /dev/null +++ b/脚本参考/XA工作理解.txt @@ -0,0 +1,10 @@ +剑哥你好,关于雄安交流的工作,我做了一定的工作和理解 + +背景是:雄安政策对于低空经济的支持还是相当大的,详见PPT;已经有竞品公司,中国电信成立团队,中国邮政的无人机快递,中国通号的低空监视防护网等各家公司的进驻; + +关于工作的理解和安排,总结如下: +1. 低空经济政策顶规:我已请教何博,对于相关的工作内容有了一定的了解。 +2. 市场扩展:雄安移动的资源力度,能否考虑构建北方的示范基地 +3. 工作及个人安排:可以外驻交流,脱离目前工作的“舒适圈”。主体工作交由技术支撑交付团队完成 + +还望剑哥批评指正,一切服从组织安排。 \ No newline at end of file