大量更新
This commit is contained in:
22
0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml
Normal file
22
0-部署应用/Dify-AI-Center/crawl4AI/craw4ai-docker-compose.yml
Normal file
@@ -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
|
||||
9
0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env
Normal file
9
0-部署应用/Dify-AI-Center/crawl4AI/环境变量.env
Normal file
@@ -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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md
Normal file
6
0-部署应用/Dify-AI-Center/股票咨询工作流-ethinvestmentlab/输出内容.md
Normal file
@@ -0,0 +1,6 @@
|
||||
这篇文章揭露了豆粕市场崩盘背后的资本博弈和行业乱象,核心内容包括:
|
||||
1. **资本操控**:豆粕价格暴跌并非单纯市场供需所致,而是压榨巨头和饲料企业为争夺定价权进行的资本博弈,散户成为牺牲品。
|
||||
1. **需求疲软假象**:所谓的“需求疲软”实则是饲料企业为保利润调整配方,减少豆粕用量,而养殖户因成本上升和猪周期下行遭受重创。
|
||||
1. **开工率谎言**:压榨企业通过“停机检修”人为控制供应,制造紧张假象以操纵价格,同时过度依赖进口大豆威胁国内农业生态和产业安全。
|
||||
2. **库存猫腻**:“缺豆不缺粕”的异常现象暗示压榨企业和贸易商囤积居奇,通过信息不对称和低买高卖剥削散户。
|
||||
1. **未来预测争议**:卓创资讯对4月豆粕价格走势的预测被质疑可能受利益集团影响,提醒投资者保持独立判断,警惕市场陷阱。
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -53,7 +53,17 @@ services:
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
82
1-代理Xray/0-香港节点/0-基础原生配置.json
Normal file
82
1-代理Xray/0-香港节点/0-基础原生配置.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
84
1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json
Normal file
84
1-代理Xray/0-香港节点/1-FV-德国-富兰克林.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
84
1-代理Xray/0-香港节点/2-FV-韩国-首尔.json
Normal file
84
1-代理Xray/0-香港节点/2-FV-韩国-首尔.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
84
1-代理Xray/0-香港节点/3-FV-日本-东京.json
Normal file
84
1-代理Xray/0-香港节点/3-FV-日本-东京.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
85
1-代理Xray/0-香港节点/4-FV-英国-伦敦.json
Normal file
85
1-代理Xray/0-香港节点/4-FV-英国-伦敦.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
85
1-代理Xray/0-香港节点/5-FV-新加坡.json
Normal file
85
1-代理Xray/0-香港节点/5-FV-新加坡.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
85
1-代理Xray/0-香港节点/6-FV-香港.json
Normal file
85
1-代理Xray/0-香港节点/6-FV-香港.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
861
1-代理Xray/0-香港节点/9-Vless组合配置.json
Normal file
861
1-代理Xray/0-香港节点/9-Vless组合配置.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
72
1-代理Xray/4-凤凰城-amd02节点/普通代理.json
Normal file
72
1-代理Xray/4-凤凰城-amd02节点/普通代理.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
27
1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml
Normal file
27
1-代理Xray/cloudflare-机场/cloudflare-worker-vless.yaml
Normal file
@@ -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
|
||||
772
1-代理Xray/cloudflare-机场/cmliu-vless-worker.js
Normal file
772
1-代理Xray/cloudflare-机场/cmliu-vless-worker.js
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
996
1-代理Xray/cloudflare-机场/yonge_cf_worker.js
Normal file
996
1-代理Xray/cloudflare-机场/yonge_cf_worker.js
Normal file
@@ -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<Response>}
|
||||
*/
|
||||
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<boolean>} 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<void>} 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<void>) | 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,🌍选择代理`
|
||||
}
|
||||
581
1-代理Xray/cloudflare-机场/yongge_cf_core.js
Normal file
581
1-代理Xray/cloudflare-机场/yongge_cf_core.js
Normal file
@@ -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<boolean>} 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<void>} 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<void>) | 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);
|
||||
},
|
||||
};
|
||||
}
|
||||
49
1-代理Xray/cloudflare-机场/yongge_cf_core.md
Normal file
49
1-代理Xray/cloudflare-机场/yongge_cf_core.md
Normal file
@@ -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 返回。
|
||||
14
1-代理Xray/cloudflare-机场/参考文档.txt
Normal file
14
1-代理Xray/cloudflare-机场/参考文档.txt
Normal file
@@ -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
|
||||
|
||||
|
||||
25
1-代理Xray/cloudflare-机场/自建proxyIP.txt
Normal file
25
1-代理Xray/cloudflare-机场/自建proxyIP.txt
Normal file
@@ -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"
|
||||
25
1-代理Xray/v2ray-Socks5/sock5代理服务器.json
Normal file
25
1-代理Xray/v2ray-Socks5/sock5代理服务器.json
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
|
||||
acme.sh --renew -d ${DOMAIN_NAME}--ecc
|
||||
30
2-NGINX相关/nginx安装/80转443模板.conf
Normal file
30
2-NGINX相关/nginx安装/80转443模板.conf
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
49
2-NGINX相关/nginx安装/test.conf
Normal file
49
2-NGINX相关/nginx安装/test.conf
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
9
5-fastestVPN节点信息/FastestVPN-香港.txt
Normal file
9
5-fastestVPN节点信息/FastestVPN-香港.txt
Normal file
@@ -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
|
||||
0
5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt
Normal file
0
5-fastestVPN节点信息/土耳其-伊斯坦布尔.txt
Normal file
9
5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt
Normal file
9
5-fastestVPN节点信息/德国-杜塞尔多夫-无法使用.txt
Normal file
@@ -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
|
||||
9
5-fastestVPN节点信息/德国-法兰克福.txt
Normal file
9
5-fastestVPN节点信息/德国-法兰克福.txt
Normal file
@@ -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
|
||||
12
5-fastestVPN节点信息/新加坡.txt
Normal file
12
5-fastestVPN节点信息/新加坡.txt
Normal file
@@ -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
|
||||
9
5-fastestVPN节点信息/日本-东京.txt
Normal file
9
5-fastestVPN节点信息/日本-东京.txt
Normal file
@@ -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
|
||||
9
5-fastestVPN节点信息/美国-洛杉矶.txt
Normal file
9
5-fastestVPN节点信息/美国-洛杉矶.txt
Normal file
@@ -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
|
||||
9
5-fastestVPN节点信息/英国-伦敦.txt
Normal file
9
5-fastestVPN节点信息/英国-伦敦.txt
Normal file
@@ -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
|
||||
1
5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt
Normal file
1
5-fastestVPN节点信息/阿根廷-布伊利诺斯艾利斯.txt
Normal file
@@ -0,0 +1 @@
|
||||
z
|
||||
9
5-fastestVPN节点信息/韩国-首尔.txt
Normal file
9
5-fastestVPN节点信息/韩国-首尔.txt
Normal file
@@ -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
|
||||
1
tmp.sh
1
tmp.sh
@@ -1 +1,2 @@
|
||||
|
||||
eyJhbGciOiJSUzI1NiIsImtpZCI6IjVlZWI3OWMwOTkxM2FjODg2YzBjNjFmZTNiYTgxMzg5ZWU3MGM4OTdiMTNjY2YzNDVhNTg0NzJiNTI1YjY4NDQifQ.eyJhdWQiOlsiZmVjZTdmZmM3YWY4ODQ5NDEwMDA5N2ZjNDBlMjA1Mjc0YzRlZDBiYzgxMWZmMzBkZTFjYTRmYjc0MDY2YmNkMCJdLCJlbWFpbCI6ImljZWRlcmNlQGdtYWlsLmNvbSIsImV4cCI6MTc0MzU1ODMyNCwiaWF0IjoxNzQzNTU4MjY0LCJuYmYiOjE3NDM1NTgyNjQsImlzcyI6Imh0dHBzOi8vaWNlZGVyY2UuY2xvdWRmbGFyZWFjY2Vzcy5jb20iLCJ0eXBlIjoiYXBwIiwiaWRlbnRpdHlfbm9uY2UiOiI1T290ZXRCbG9KMUJyYU51Iiwic3ViIjoiZTcyMmVkNzItOGY4ZC01MjAwLTk1YTYtM2RiNThmODZjNGU4Iiwid2FycCI6dHJ1ZSwiaXAiOiIxOTMuMjM5Ljg2LjMiLCJhY2NvdW50X2lkIjoiY2JhYWFkOGExN2JlZmRlNTE0YTZhYWNmNDM0YzdmODkiLCJpZGVudGl0eSI6eyJlbWFpbCI6ImljZWRlcmNlQGdtYWlsLmNvbSJ9LCJjb3VudHJ5IjoiSEsifQ.hJNg7nHfAOoLYxdafuVjmHoo1g_OH566dbZEwtJpjbew0v3VtlMv1jTXKx7Fl60xmsh21_wyIwf7dhQIWdWpvN69qll3dkUW5E9NZTjDmjKQFmLcSYAFUUdXhLNjcZG3_b90sJHUCoSjna452k8dxyhYaYkYn-sMLx-MCemT8qNI63sDKAJDFOoC498NLbOd5Awbx66j_ksi5uXMYedu9vHjYSMhnVVf43GtJDw197L4mnfdHi9BfzB1pGt7mFvrFG3tfMKZkGupWgpiY0y1tz1VR-O_ZxfJOr_vGIfutpmz2-5qVMn76rVApwJK8EksjdRxZ6BTMHJWu4He4pDbBw
|
||||
10
脚本参考/XA工作理解.txt
Normal file
10
脚本参考/XA工作理解.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
剑哥你好,关于雄安交流的工作,我做了一定的工作和理解
|
||||
|
||||
背景是:雄安政策对于低空经济的支持还是相当大的,详见PPT;已经有竞品公司,中国电信成立团队,中国邮政的无人机快递,中国通号的低空监视防护网等各家公司的进驻;
|
||||
|
||||
关于工作的理解和安排,总结如下:
|
||||
1. 低空经济政策顶规:我已请教何博,对于相关的工作内容有了一定的了解。
|
||||
2. 市场扩展:雄安移动的资源力度,能否考虑构建北方的示范基地
|
||||
3. 工作及个人安排:可以外驻交流,脱离目前工作的“舒适圈”。主体工作交由技术支撑交付团队完成
|
||||
|
||||
还望剑哥批评指正,一切服从组织安排。
|
||||
Reference in New Issue
Block a user