├── 256_IPs.json ├── Gifts ├── peyman-nekobox-gift.json ├── peyman-sing-box-1.8.json └── peyman-sing-box-gift.json ├── README.md ├── ServerLess_TLSFrag_Xray_Config.json ├── Xray-examples ├── p-m-f.json ├── vless-tcp-header.json └── vless-ws-header.json ├── bash.sh ├── bot.py ├── certificate.sh ├── clash12.yaml ├── config-fregment.json ├── media ├── 1-1.png ├── 1.jpg ├── 10.jpg ├── 11.jpg ├── 12.jpg ├── 13.jpg ├── 14.jpg ├── 15.jpg ├── 16.jpg ├── 17.jpg ├── 18.jpg ├── 19.jpg ├── 2-2.png ├── 2.jpg ├── 20.jpg ├── 21.jpg ├── 22.jpg ├── 23.gif ├── 24.gif ├── 25.jpg ├── 26.jpg ├── 27.jpg ├── 28.jpg ├── 29.jpg ├── 3-3.jpeg ├── 3.jpg ├── 30.jpg ├── 31.jpg ├── 32.jpg ├── 33.jpg ├── 4-4.jpg ├── 4.jpg ├── 5-5.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg ├── 9.jpg ├── Nim.xls ├── Waterwall ├── h.mp3 ├── line.gif └── neko.gif ├── mtu.sh ├── vmess.json ├── wa.py ├── wg.sh ├── worker.js └── ytdl.sh /Gifts/peyman-nekobox-gift.json: -------------------------------------------------------------------------------- 1 | { 2 | "dns": { 3 | "independent_cache": true, 4 | "rules": [ 5 | { 6 | "domain": [ 7 | "dns.google" 8 | ], 9 | "server": "dns-direct" 10 | } 11 | ], 12 | "servers": [ 13 | { 14 | "address": "https://8.8.8.8/dns-query",//peyman//@P_tech2024 15 | "address_resolver": "dns-direct", 16 | "strategy": "ipv4_only", 17 | "tag": "dns-remote" 18 | }, 19 | { 20 | "address": "local", 21 | "address_resolver": "dns-local", 22 | "detour": "direct", 23 | "strategy": "ipv4_only", 24 | "tag": "dns-direct" 25 | }, 26 | { 27 | "address": "local", 28 | "detour": "direct", 29 | "tag": "dns-local" 30 | }, 31 | { 32 | "address": "rcode://success", 33 | "tag": "dns-block" 34 | } 35 | ] 36 | }, 37 | "experimental": { 38 | "clash_api": { 39 | "cache_file": "../cache/clash.db", 40 | "external_controller": "127.0.0.1:9090", 41 | "external_ui": "../files/yacd" 42 | } 43 | }, 44 | "inbounds": [ 45 | { 46 | "listen": "127.0.0.1", 47 | "listen_port": 6450, 48 | "override_address": "8.8.8.8", 49 | "override_port": 53, 50 | "tag": "dns-in", 51 | "type": "direct" 52 | }, 53 | { 54 | "domain_strategy": "", 55 | "endpoint_independent_nat": true, 56 | "inet4_address": [ 57 | "172.19.0.1/28" 58 | ], 59 | "mtu": 9000, 60 | "sniff": true, 61 | "sniff_override_destination": false, 62 | "stack": "mixed", 63 | "tag": "tun-in", 64 | "type": "tun" 65 | }, 66 | { 67 | "domain_strategy": "", 68 | "listen": "127.0.0.1", 69 | "listen_port": 2080, 70 | "sniff": true, 71 | "sniff_override_destination": false, 72 | "tag": "mixed-in", 73 | "type": "mixed" 74 | } 75 | ], 76 | "log": { 77 | "level": "panic" 78 | }, 79 | "outbounds": [ 80 | { 81 | "packet_encoding": "", 82 | "server": "104.31.16.60", 83 | "server_port": 443, 84 | "tls": { 85 | "alpn": [ 86 | "h3" 87 | ], 88 | "enabled": true, 89 | "insecure": true, 90 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 91 | "utls": { 92 | "enabled": true, 93 | "fingerprint": "chrome" 94 | } 95 | }, 96 | "transport": { 97 | "early_data_header_name": "Sec-WebSocket-Protocol", 98 | "headers": { 99 | "Host": "2222.BWvD9gh5-Dcb.wOrkErs.DEv" 100 | }, 101 | "max_early_data": 2048, 102 | "path": "/", 103 | "type": "ws" 104 | }, 105 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 106 | "type": "vless", 107 | "domain_strategy": "", 108 | "tag": "worker 1️⃣" 109 | }, 110 | { 111 | "packet_encoding": "xudp", 112 | "server": "198.41.216.11", 113 | "server_port": 2087, 114 | "tls": { 115 | "alpn": [ 116 | "h3" 117 | ], 118 | "enabled": true, 119 | "insecure": true, 120 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 121 | "utls": { 122 | "enabled": true, 123 | "fingerprint": "randomized" 124 | } 125 | }, 126 | "transport": { 127 | "early_data_header_name": "Sec-WebSocket-Protocol", 128 | "headers": { 129 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 130 | }, 131 | "max_early_data": 2048, 132 | "path": "/", 133 | "type": "ws" 134 | }, 135 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 136 | "type": "vless", 137 | "domain_strategy": "", 138 | "tag": "worker 2️⃣" 139 | }, 140 | { 141 | "packet_encoding": "", 142 | "server": "[2606:4700:d0::a29f:c001]", 143 | "server_port": 443, 144 | "tls": { 145 | "alpn": [ 146 | "h3" 147 | ], 148 | "enabled": true, 149 | "insecure": true, 150 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 151 | "utls": { 152 | "enabled": true, 153 | "fingerprint": "randomized" 154 | } 155 | }, 156 | "transport": { 157 | "early_data_header_name": "Sec-WebSocket-Protocol", 158 | "headers": { 159 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 160 | }, 161 | "path": "/", 162 | "type": "ws" 163 | }, 164 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 165 | "type": "vless", 166 | "domain_strategy": "", 167 | "tag": "worker 3️⃣" 168 | }, 169 | { 170 | "packet_encoding": "", 171 | "server": "104.31.16.60", 172 | "server_port": 443, 173 | "tls": { 174 | "alpn": [ 175 | "h3" 176 | ], 177 | "enabled": true, 178 | "insecure": true, 179 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 180 | "utls": { 181 | "enabled": true, 182 | "fingerprint": "chrome" 183 | } 184 | }, 185 | "transport": { 186 | "early_data_header_name": "Sec-WebSocket-Protocol", 187 | "headers": { 188 | "Host": "2222.BWvD9gh5-Dcb.wOrkErs.DEv" 189 | }, 190 | "max_early_data": 2048, 191 | "path": "/", 192 | "type": "ws" 193 | }, 194 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 195 | "type": "vless", 196 | "domain_strategy": "", 197 | "tag": "worker 4️⃣" 198 | }, 199 | { 200 | "packet_encoding": "", 201 | "server": "198.41.216.11", 202 | "server_port": 2087, 203 | "tls": { 204 | "alpn": [ 205 | "h3" 206 | ], 207 | "enabled": true, 208 | "insecure": true, 209 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 210 | "utls": { 211 | "enabled": true, 212 | "fingerprint": "chrome" 213 | } 214 | }, 215 | "transport": { 216 | "early_data_header_name": "Sec-WebSocket-Protocol", 217 | "headers": { 218 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 219 | }, 220 | "path": "/", 221 | "type": "ws" 222 | }, 223 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 224 | "type": "vless", 225 | "domain_strategy": "", 226 | "tag": "worker 5️⃣" 227 | }, 228 | { 229 | "local_address": [ 230 | "172.16.0.2/32", 231 | "2606:4700:110:8f6a:418a:9b60:35bb:e660/128" 232 | ], 233 | "mtu": 1280, 234 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 235 | "pre_shared_key": "", 236 | "private_key": "mL11kkXnNi46gmvLT7Ci1xjn1X3FMKUvF+NeHPC4fFM=", 237 | "reserved": "hTlE", 238 | "server": "162.159.192.204", 239 | "server_port": 1070, 240 | "type": "wireguard", 241 | "domain_strategy": "", 242 | "tag": "عمو وایرگارد1️⃣" 243 | }, 244 | { 245 | "local_address": [ 246 | "172.16.0.2/32", 247 | "2606:4700:110:8f6a:418a:9b60:35bb:e660/128" 248 | ], 249 | "mtu": 1280, 250 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 251 | "pre_shared_key": "", 252 | "private_key": "mL11kkXnNi46gmvLT7Ci1xjn1X3FMKUvF+NeHPC4fFM=", 253 | "reserved": "hTlE", 254 | "server": "162.159.192.135", 255 | "server_port": 1070, 256 | "type": "wireguard", 257 | "domain_strategy": "", 258 | "tag": "عمو وایرگارد2️⃣" 259 | }, 260 | { 261 | "local_address": [ 262 | "172.16.0.2/32", 263 | "2606:4700:110:8a0d:444c:a568:474c:f13e/128" 264 | ], 265 | "mtu": 1280, 266 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 267 | "pre_shared_key": "", 268 | "private_key": "UGqDCeCtzr2bPshy0SzdaFIIcvbZPj6frOGhPxKqpHA=", 269 | "reserved": "86yW", 270 | "server": "2606:4700:d0::a29f:c001", 271 | "server_port": 1070, 272 | "type": "wireguard", 273 | "domain_strategy": "", 274 | "tag": "عمو وایرگارد3️⃣" 275 | }, 276 | { 277 | "tag": "💚Internet💚", 278 | "type": "selector", 279 | "outbounds":[ 280 | "❤️Best Latency❤️", 281 | "worker 1️⃣", 282 | "worker 2️⃣", 283 | "worker 3️⃣", 284 | "worker 4️⃣", 285 | "worker 5️⃣", 286 | "عمو وایرگارد1️⃣", 287 | "عمو وایرگارد2️⃣", 288 | "عمو وایرگارد3️⃣" 289 | ] 290 | }, 291 | { 292 | "tag": "❤️Best Latency❤️", 293 | "type": "urltest", 294 | "outbounds":[ 295 | "worker 1️⃣", 296 | "worker 2️⃣", 297 | "worker 3️⃣", 298 | "worker 4️⃣", 299 | "worker 5️⃣", 300 | "عمو وایرگارد1️⃣", 301 | "عمو وایرگارد2️⃣", 302 | "عمو وایرگارد3️⃣" 303 | ], 304 | "url": "https://detectportal.firefox.com/success.txt", 305 | "interval": "60s", 306 | "tolerance": 0 307 | }, 308 | { 309 | "tag": "direct", 310 | "type": "direct" 311 | }, 312 | { 313 | "tag": "bypass", 314 | "type": "direct" 315 | }, 316 | { 317 | "tag": "block", 318 | "type": "block" 319 | }, 320 | { 321 | "tag": "dns-out", 322 | "type": "dns" 323 | } 324 | ], 325 | "route": { 326 | "auto_detect_interface": true, 327 | "rules": [ 328 | { 329 | "outbound": "dns-out", 330 | "port": [ 331 | 53 332 | ] 333 | }, 334 | { 335 | "inbound": [ 336 | "dns-in" 337 | ], 338 | "outbound": "dns-out" 339 | }, 340 | { 341 | "ip_cidr": [ 342 | "224.0.0.0/3", 343 | "ff00::/8" 344 | ], 345 | "outbound": "block", 346 | "source_ip_cidr": [ 347 | "224.0.0.0/3", 348 | "ff00::/8" 349 | ] 350 | } 351 | ] 352 | } 353 | } 354 | -------------------------------------------------------------------------------- /Gifts/peyman-sing-box-1.8.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "level": "info", 4 | "timestamp": true 5 | }, 6 | "dns": { 7 | "servers": [ 8 | { 9 | "tag": "dns-remote", 10 | "address": "https://8.8.8.8/dns-query", 11 | "address_resolver": "dns-direct", 12 | "strategy": "ipv4_only" 13 | }, 14 | { 15 | "tag": "dns-direct", 16 | "address": "local", 17 | "address_resolver": "dns-local", 18 | "strategy": "ipv4_only", 19 | "detour": "direct" 20 | }, 21 | { 22 | "tag": "dns-local", 23 | "address": "local", 24 | "detour": "direct" 25 | }, 26 | { 27 | "tag": "dns-block", 28 | "address": "rcode://success" 29 | } 30 | ], 31 | "independent_cache": true 32 | }, 33 | "inbounds": [ 34 | { 35 | "type": "tun", 36 | "inet4_address": "172.19.0.1/30", 37 | "inet6_address": "fdfe:dcba:9876::1/126", 38 | "auto_route": true, 39 | "strict_route": true, 40 | "stack": "mixed", 41 | "sniff": true 42 | } 43 | ], 44 | "outbounds": [ 45 | { 46 | "type": "vless", 47 | "tag": "worker 1️⃣", 48 | "server": "104.31.16.60", 49 | "server_port": 443, 50 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 51 | "tls": { 52 | "enabled": true, 53 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 54 | "insecure": true, 55 | "alpn": "h3", 56 | "utls": { 57 | "enabled": true, 58 | "fingerprint": "chrome" 59 | } 60 | }, 61 | "transport": { 62 | "type": "ws", 63 | "path": "/", 64 | "headers": { 65 | "Host": "2222.BWvD9Gh5-Dcb.wOrkErs.DEv" 66 | }, 67 | "max_early_data": 2048, 68 | "early_data_header_name": "Sec-WebSocket-Protocol" 69 | }, 70 | "packet_encoding": "" 71 | }, 72 | { 73 | "type": "vless", 74 | "tag": "worker 2️⃣", 75 | "server": "198.41.216.11", 76 | "server_port": 2087, 77 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 78 | "tls": { 79 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 80 | "insecure": true, 81 | "alpn": "h3", 82 | "utls": { 83 | "enabled": true, 84 | "fingerprint": "randomized" 85 | } 86 | }, 87 | "transport": { 88 | "type": "ws", 89 | "path": "/", 90 | "headers": { 91 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 92 | }, 93 | "max_early_data": 2048, 94 | "early_data_header_name": "Sec-WebSocket-Protocol" 95 | }, 96 | "packet_encoding": "xudp" 97 | }, 98 | { 99 | "type": "vless", 100 | "tag": "worker 3️⃣", 101 | "server": "[2606:4700:d0::a29f:c001]", 102 | "server_port": 443, 103 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 104 | "tls": { 105 | "enabled": true, 106 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 107 | "insecure": true, 108 | "alpn": "h3", 109 | "utls": { 110 | "enabled": true, 111 | "fingerprint": "randomized" 112 | } 113 | }, 114 | "transport": { 115 | "type": "ws", 116 | "path": "/", 117 | "headers": { 118 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 119 | }, 120 | "early_data_header_name": "Sec-WebSocket-Protocol" 121 | }, 122 | "packet_encoding": "" 123 | }, 124 | { 125 | "type": "vless", 126 | "tag": "worker 4️⃣", 127 | "server": "104.31.16.60", 128 | "server_port": 443, 129 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 130 | "tls": { 131 | "enabled": true, 132 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 133 | "insecure": true, 134 | "alpn": "h3", 135 | "utls": { 136 | "enabled": true, 137 | "fingerprint": "chrome" 138 | } 139 | }, 140 | "transport": { 141 | "type": "ws", 142 | "path": "/", 143 | "headers": { 144 | "Host": "2222.BWvD9gh5-Dcb.wOrkErs.DEv" 145 | }, 146 | "max_early_data": 2048, 147 | "early_data_header_name": "Sec-WebSocket-Protocol" 148 | }, 149 | "packet_encoding": "" 150 | }, 151 | { 152 | "type": "vless", 153 | "tag": "worker 5️⃣", 154 | "server": "198.41.216.11", 155 | "server_port": 2087, 156 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 157 | "tls": { 158 | "enabled": true, 159 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 160 | "insecure": true, 161 | "alpn": "h3", 162 | "utls": { 163 | "enabled": true, 164 | "fingerprint": "chrome" 165 | } 166 | }, 167 | "transport": { 168 | "type": "ws", 169 | "path": "/", 170 | "headers": { 171 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 172 | }, 173 | "early_data_header_name": "Sec-WebSocket-Protocol" 174 | }, 175 | "packet_encoding": "" 176 | }, 177 | { 178 | "type": "wireguard", 179 | "tag": "عمو وایرگارد1️⃣", 180 | "local_address": [ 181 | "172.16.0.2/32", 182 | "2606:4700:110:8988:c1ee:9e0a:cd47:ac4a/128" 183 | ], 184 | "private_key": "qNSfNi2ZMZQXeif/BpC9xjh/nje/NBifogRXCRGv4lc=", 185 | "server": "162.159.192.0", 186 | "server_port": 1070, 187 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 188 | "reserved": "vedv", 189 | "mtu": 1280 190 | }, 191 | { 192 | "type": "wireguard", 193 | "tag": "عمو وایرگارد2️⃣", 194 | "local_address": [ 195 | "172.16.0.2/32", 196 | "2606:4700:110:8f6a:418a:9b60:35bb:e660/128" 197 | ], 198 | "private_key": "mL11kkXnNi46gmvLT7Ci1xjn1X3FMKUvF+NeHPC4fFM=", 199 | "server": "162.159.192.135", 200 | "server_port": 1070, 201 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 202 | "reserved": "hTlE", 203 | "mtu": 1280 204 | }, 205 | { 206 | "type": "wireguard", 207 | "tag": "عمو وایرگارد3️⃣", 208 | "local_address": [ 209 | "172.16.0.2/32", 210 | "2606:4700:110:8a0d:444c:a568:474c:f13e/128" 211 | ], 212 | "private_key": "UGqDCeCtzr2bPshy0SzdaFIIcvbZPj6frOGhPxKqpHA=", 213 | "server": "2606:4700:d0::a29f:c001", 214 | "server_port": 1070, 215 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 216 | "reserved": "86yW", 217 | "mtu": 1280 218 | }, 219 | { 220 | "type": "direct", 221 | "tag": "direct" 222 | }, 223 | { 224 | "type": "block", 225 | "tag": "block" 226 | }, 227 | { 228 | "type": "dns", 229 | "tag": "dns-out" 230 | }, 231 | { 232 | "type": "selector", 233 | "tag": "💚select💚", 234 | "outbounds": [ 235 | "❤️Best Latency❤️", 236 | "worker 1️⃣", 237 | "worker 2️⃣", 238 | "worker 3️⃣", 239 | "worker 4️⃣", 240 | "worker 5️⃣", 241 | "عمو وایرگارد1️⃣", 242 | "عمو وایرگارد2️⃣", 243 | "عمو وایرگارد3️⃣" 244 | ] 245 | }, 246 | { 247 | "type": "urltest", 248 | "tag": "❤️Best Latency❤️", 249 | "outbounds": [ 250 | "worker 1️⃣", 251 | "worker 2️⃣", 252 | "worker 3️⃣", 253 | "worker 4️⃣", 254 | "worker 5️⃣", 255 | "عمو وایرگارد1️⃣", 256 | "عمو وایرگارد2️⃣", 257 | "عمو وایرگارد3️⃣" 258 | ], 259 | "url": "https://detectportal.firefox.com/success.txt", 260 | "interval": "1m0s" 261 | } 262 | ], 263 | "route": { 264 | "geoip": { 265 | "download_url": "https://github.com/Ptechgithub/sing-box/blob/main/geo/geoip.db", 266 | "download_detour": "💚select💚" 267 | }, 268 | "geosite": { 269 | "download_url": "https://github.com/Ptechgithub/sing-box/blob/main/geo/geosite.db", 270 | "download_detour": "💚select💚" 271 | }, 272 | "rules": [ 273 | { 274 | "protocol": "dns", 275 | "outbound": "dns-out" 276 | }, 277 | { 278 | "clash_mode": "Direct", 279 | "outbound": "direct" 280 | }, 281 | { 282 | "clash_mode": "Global", 283 | "outbound": "💚select💚" 284 | }, 285 | { 286 | "geosite": "ir", 287 | "geoip": [ 288 | "ir", 289 | "private" 290 | ], 291 | "outbound": "direct" 292 | }, 293 | { 294 | "geosite": "geolocation-!ir", 295 | "outbound": "💚select💚" 296 | } 297 | ], 298 | "final": "💚select💚", 299 | "auto_detect_interface": true 300 | }, 301 | "experimental": { 302 | "cache_file": { 303 | "enabled": true, 304 | "path": "cache.db" 305 | } 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /Gifts/peyman-sing-box-gift.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "disabled": false, 4 | "level": "info", 5 | "timestamp": true 6 | }, 7 | "dns": { 8 | "independent_cache": true, 9 | "rules": [], 10 | "servers": [ 11 | { 12 | "address": "https://8.8.8.8/dns-query", 13 | "address_resolver": "dns-direct", 14 | "strategy": "ipv4_only", 15 | "tag": "dns-remote" 16 | }, 17 | { 18 | "address": "local", 19 | "address_resolver": "dns-local", 20 | "detour": "direct", 21 | "strategy": "ipv4_only", 22 | "tag": "dns-direct" 23 | }, 24 | { 25 | "address": "local", 26 | "detour": "direct", 27 | "tag": "dns-local" 28 | }, 29 | { 30 | "address": "rcode://success", 31 | "tag": "dns-block" 32 | } 33 | ] 34 | }, 35 | "inbounds": [ 36 | { 37 | "type": "tun", 38 | "inet4_address": "172.19.0.1/30", 39 | "inet6_address": "fdfe:dcba:9876::1/126", 40 | "auto_route": true, 41 | "strict_route": true, 42 | "stack": "mixed", 43 | "sniff": true 44 | } 45 | ], 46 | "experimental": { 47 | "clash_api": { 48 | "external_controller": "127.0.0.1:9090", 49 | "external_ui": "ui", 50 | "external_ui_download_url": "", 51 | "external_ui_download_detour": "", 52 | "secret": "", 53 | "default_mode": "Rule", 54 | "store_mode": true, 55 | "store_selected": true, 56 | "store_fakeip": true 57 | } 58 | }, 59 | "outbounds": [ 60 | { 61 | "packet_encoding": "", 62 | "server": "104.31.16.60", 63 | "server_port": 443, 64 | "tls": { 65 | "alpn": [ 66 | "h3" 67 | ], 68 | "enabled": true, 69 | "insecure": true, 70 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 71 | "utls": { 72 | "enabled": true, 73 | "fingerprint": "chrome" 74 | } 75 | }, 76 | "transport": { 77 | "early_data_header_name": "Sec-WebSocket-Protocol", 78 | "headers": { 79 | "Host": "2222.BWvD9gh5-Dcb.wOrkErs.DEv" 80 | }, 81 | "max_early_data": 2048, 82 | "path": "/", 83 | "type": "ws" 84 | }, 85 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 86 | "type": "vless", 87 | "domain_strategy": "", 88 | "tag": "worker 1️⃣" 89 | }, 90 | { 91 | "packet_encoding": "xudp", 92 | "server": "198.41.216.11", 93 | "server_port": 2087, 94 | "tls": { 95 | "alpn": [ 96 | "h3" 97 | ], 98 | "enabled": true, 99 | "insecure": true, 100 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 101 | "utls": { 102 | "enabled": true, 103 | "fingerprint": "randomized" 104 | } 105 | }, 106 | "transport": { 107 | "early_data_header_name": "Sec-WebSocket-Protocol", 108 | "headers": { 109 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 110 | }, 111 | "max_early_data": 2048, 112 | "path": "/", 113 | "type": "ws" 114 | }, 115 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 116 | "type": "vless", 117 | "domain_strategy": "", 118 | "tag": "worker 2️⃣" 119 | }, 120 | { 121 | "packet_encoding": "", 122 | "server": "[2606:4700:d0::a29f:c001]", 123 | "server_port": 443, 124 | "tls": { 125 | "alpn": [ 126 | "h3" 127 | ], 128 | "enabled": true, 129 | "insecure": true, 130 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 131 | "utls": { 132 | "enabled": true, 133 | "fingerprint": "randomized" 134 | } 135 | }, 136 | "transport": { 137 | "early_data_header_name": "Sec-WebSocket-Protocol", 138 | "headers": { 139 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 140 | }, 141 | "path": "/", 142 | "type": "ws" 143 | }, 144 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 145 | "type": "vless", 146 | "domain_strategy": "", 147 | "tag": "worker 3️⃣" 148 | }, 149 | { 150 | "packet_encoding": "", 151 | "server": "104.31.16.60", 152 | "server_port": 443, 153 | "tls": { 154 | "alpn": [ 155 | "h3" 156 | ], 157 | "enabled": true, 158 | "insecure": true, 159 | "server_name": "2222.BWvD9gh5-Dcb.wOrkErs.DEv", 160 | "utls": { 161 | "enabled": true, 162 | "fingerprint": "chrome" 163 | } 164 | }, 165 | "transport": { 166 | "early_data_header_name": "Sec-WebSocket-Protocol", 167 | "headers": { 168 | "Host": "2222.BWvD9gh5-Dcb.wOrkErs.DEv" 169 | }, 170 | "max_early_data": 2048, 171 | "path": "/", 172 | "type": "ws" 173 | }, 174 | "uuid": "6c00e3f1-b0ec-425b-a5b8-3f786a50e402", 175 | "type": "vless", 176 | "domain_strategy": "", 177 | "tag": "worker 4️⃣" 178 | }, 179 | { 180 | "packet_encoding": "", 181 | "server": "198.41.216.11", 182 | "server_port": 2087, 183 | "tls": { 184 | "alpn": [ 185 | "h3" 186 | ], 187 | "enabled": true, 188 | "insecure": true, 189 | "server_name": "Bee.OnlyclOudflarE.Workers.DEv", 190 | "utls": { 191 | "enabled": true, 192 | "fingerprint": "chrome" 193 | } 194 | }, 195 | "transport": { 196 | "early_data_header_name": "Sec-WebSocket-Protocol", 197 | "headers": { 198 | "Host": "Bee.OnlyclOudflarE.Workers.DEv" 199 | }, 200 | "path": "/", 201 | "type": "ws" 202 | }, 203 | "uuid": "71e6dde6-8ba9-4bed-8904-1f01c4fc803d", 204 | "type": "vless", 205 | "domain_strategy": "", 206 | "tag": "worker 5️⃣" 207 | }, 208 | { 209 | "local_address": [ 210 | "172.16.0.2/32", 211 | "2606:4700:110:8f6a:418a:9b60:35bb:e660/128" 212 | ], 213 | "mtu": 1280, 214 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 215 | "pre_shared_key": "", 216 | "private_key": "mL11kkXnNi46gmvLT7Ci1xjn1X3FMKUvF+NeHPC4fFM=", 217 | "reserved": "hTlE", 218 | "server": "162.159.192.204", 219 | "server_port": 1070, 220 | "type": "wireguard", 221 | "domain_strategy": "", 222 | "tag": "عمو وایرگارد1️⃣" 223 | }, 224 | { 225 | "local_address": [ 226 | "172.16.0.2/32", 227 | "2606:4700:110:8f6a:418a:9b60:35bb:e660/128" 228 | ], 229 | "mtu": 1280, 230 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 231 | "pre_shared_key": "", 232 | "private_key": "mL11kkXnNi46gmvLT7Ci1xjn1X3FMKUvF+NeHPC4fFM=", 233 | "reserved": "hTlE", 234 | "server": "162.159.192.135", 235 | "server_port": 1070, 236 | "type": "wireguard", 237 | "domain_strategy": "", 238 | "tag": "عمو وایرگارد2️⃣" 239 | }, 240 | { 241 | "local_address": [ 242 | "172.16.0.2/32", 243 | "2606:4700:110:8a0d:444c:a568:474c:f13e/128" 244 | ], 245 | "mtu": 1280, 246 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 247 | "pre_shared_key": "", 248 | "private_key": "UGqDCeCtzr2bPshy0SzdaFIIcvbZPj6frOGhPxKqpHA=", 249 | "reserved": "86yW", 250 | "server": "2606:4700:d0::a29f:c001", 251 | "server_port": 1070, 252 | "type": "wireguard", 253 | "domain_strategy": "", 254 | "tag": "عمو وایرگارد3️⃣" 255 | }, 256 | { 257 | "tag": "direct", 258 | "type": "direct" 259 | }, 260 | { 261 | "tag": "block", 262 | "type": "block" 263 | }, 264 | { 265 | "tag": "dns-out", 266 | "type": "dns" 267 | }, 268 | { 269 | "tag": "💚select💚", 270 | "type": "selector", 271 | "outbounds":[ 272 | "❤️Best Latency❤️", 273 | "worker 1️⃣", 274 | "worker 2️⃣", 275 | "worker 3️⃣", 276 | "worker 4️⃣", 277 | "worker 5️⃣", 278 | "عمو وایرگارد1️⃣", 279 | "عمو وایرگارد2️⃣", 280 | "عمو وایرگارد3️⃣" 281 | ] 282 | }, 283 | { 284 | "tag": "❤️Best Latency❤️", 285 | "type": "urltest", 286 | "outbounds":[ 287 | "worker 1️⃣", 288 | "worker 2️⃣", 289 | "worker 3️⃣", 290 | "worker 4️⃣", 291 | "worker 5️⃣", 292 | "عمو وایرگارد1️⃣", 293 | "عمو وایرگارد2️⃣", 294 | "عمو وایرگارد3️⃣" 295 | ], 296 | "url": "https://detectportal.firefox.com/success.txt", 297 | "interval": "60s", 298 | "tolerance": 0 299 | } 300 | ], 301 | "route": { 302 | "geoip": { 303 | "download_url": "https://mirror.ghproxy.com/https://github.com/Ptechgithub/sing-box/blob/main/geo/geoip.db", 304 | "download_detour": "💚select💚" 305 | }, 306 | "geosite": { 307 | "download_url": "https://mirror.ghproxy.com/https://github.com/Ptechgithub/sing-box/blob/main/geo/geosite.db", 308 | "download_detour": "💚select💚" 309 | }, 310 | "auto_detect_interface": true, 311 | "final": "💚select💚", 312 | "rules": [ 313 | { 314 | "outbound": "dns-out", 315 | "protocol": "dns" 316 | }, 317 | { 318 | "clash_mode": "Direct", 319 | "outbound": "direct" 320 | }, 321 | { 322 | "clash_mode": "Global", 323 | "outbound": "💚select💚" 324 | }, 325 | { 326 | "geosite": "ir", 327 | "geoip": [ 328 | "ir", 329 | "private" 330 | ], 331 | "outbound": "direct" 332 | }, 333 | { 334 | "geosite": "geolocation-!ir", 335 | "outbound": "💚select💚" 336 | } 337 | ] 338 | } 339 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # configs 2 | 3 | # [دریافت کانفیگ های رایگان worker ](https://github.com/Ptechgithub/configs/tree/main/Gifts) 4 | 5 | 6 | 7 | 12-Config to 1 [ClashMeta](https://github.com/MetaCubeX/ClashMetaForAndroid/releases) config 8 | 9 | 10 | 11 | - Config Url: 12 | ``` 13 | https://raw.githubusercontent.com/Ptechgithub/configs/main/clash12.yaml 14 | ``` 15 | 16 | ## اسکریپت نصب wireguard با docker 17 | ``` 18 | bash <(curl -fsSL https://raw.githubusercontent.com/Ptechgithub/configs/main/wg.sh) 19 | ``` 20 | ## محاسبه ی MTU 21 | 22 | ``` 23 | bash <(curl -fsSL https://raw.githubusercontent.com/Ptechgithub/configs/main/mtu.sh) 1.1.1.1 24 | ``` 25 | 26 | [Xray-configs](https://github.com/Ptechgithub/configs/tree/main/Xray-examples) 27 | -------------------------------------------------------------------------------- /ServerLess_TLSFrag_Xray_Config.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "access": "", 4 | "error": "", 5 | "loglevel": "none", 6 | "dnsLog": false 7 | }, 8 | "dns": { 9 | "tag": "dns", 10 | "hosts": { 11 | "cloudflare-dns.com": [ 12 | "104.16.248.249", 13 | "104.16.249.249" 14 | ], 15 | "domain:youtube.com": [ 16 | "google.com" 17 | ] 18 | }, 19 | "servers": [ 20 | "https://cloudflare-dns.com/dns-query" 21 | ] 22 | }, 23 | "inbounds": [ 24 | { 25 | "domainOverride": [ 26 | "http", 27 | "tls" 28 | ], 29 | "protocol": "socks", 30 | "tag": "socks-in", 31 | "listen": "127.0.0.1", 32 | "port": 10808, 33 | "settings": { 34 | "auth": "noauth", 35 | "udp": true, 36 | "userLevel": 8 37 | }, 38 | "sniffing": { 39 | "enabled": true, 40 | "destOverride": [ 41 | "http", 42 | "tls" 43 | ] 44 | } 45 | }, 46 | { 47 | "protocol": "http", 48 | "tag": "http-in", 49 | "listen": "127.0.0.1", 50 | "port": 10809, 51 | "settings": { 52 | "userLevel": 8 53 | }, 54 | "sniffing": { 55 | "enabled": true, 56 | "destOverride": [ 57 | "http", 58 | "tls" 59 | ] 60 | } 61 | } 62 | ], 63 | "outbounds": [ 64 | { 65 | "protocol": "freedom", 66 | "tag": "fragment-out", 67 | "domainStrategy": "UseIP", 68 | "sniffing": { 69 | "enabled": true, 70 | "destOverride": [ 71 | "http", 72 | "tls" 73 | ] 74 | }, 75 | "settings": { 76 | "fragment": { 77 | "packets": "tlshello", 78 | "length": "100-200", 79 | "interval": "10-20" 80 | } 81 | }, 82 | "streamSettings": { 83 | "sockopt": { 84 | "tcpNoDelay": true, 85 | "domainStrategy": "UseIP" 86 | } 87 | } 88 | }, 89 | { 90 | "protocol": "dns", 91 | "tag": "dns-out" 92 | }, 93 | { 94 | "protocol": "vless", 95 | "tag": "fakeproxy-out", 96 | "domainStrategy": "", 97 | "settings": { 98 | "vnext": [ 99 | { 100 | "address": "google.com", 101 | "port": 443, 102 | "users": [ 103 | { 104 | "encryption": "none", 105 | "flow": "", 106 | "id": "3e992e24-b4de-4fea-9e34-2ae3d9aee34e", 107 | "level": 8, 108 | "security": "auto" 109 | } 110 | ] 111 | } 112 | ] 113 | }, 114 | "streamSettings": { 115 | "network": "ws", 116 | "security": "tls", 117 | "tlsSettings": { 118 | "allowInsecure": false, 119 | "alpn": [ 120 | "h2", 121 | "http/1.1" 122 | ], 123 | "fingerprint": "randomized", 124 | "publicKey": "", 125 | "serverName": "google.com", 126 | "shortId": "", 127 | "show": false, 128 | "spiderX": "" 129 | }, 130 | "wsSettings": { 131 | "headers": { 132 | "Host": "google.com" 133 | }, 134 | "path": "/" 135 | } 136 | }, 137 | "mux": { 138 | "concurrency": 8, 139 | "enabled": false 140 | } 141 | } 142 | ], 143 | "policy": { 144 | "levels": { 145 | "8": { 146 | "connIdle": 300, 147 | "downlinkOnly": 1, 148 | "handshake": 4, 149 | "uplinkOnly": 1 150 | } 151 | }, 152 | "system": { 153 | "statsOutboundUplink": true, 154 | "statsOutboundDownlink": true 155 | } 156 | }, 157 | "routing": { 158 | "domainStrategy": "IPIfNonMatch", 159 | "rules": [ 160 | { 161 | "inboundTag": [ 162 | "socks-in", 163 | "http-in" 164 | ], 165 | "type": "field", 166 | "port": "8443", 167 | "outboundTag": "dns-out", 168 | "enabled": true 169 | }, 170 | { 171 | "inboundTag": [ 172 | "socks-in", 173 | "http-in" 174 | ], 175 | "type": "field", 176 | "port": "0-65535", 177 | "outboundTag": "fragment-out", 178 | "enabled": true 179 | } 180 | ], 181 | "strategy": "rules" 182 | }, 183 | "stats": {} 184 | } -------------------------------------------------------------------------------- /Xray-examples/p-m-f.json: -------------------------------------------------------------------------------- 1 | { 2 | "dns": { 3 | "hosts": { 4 | "cloudflare-dns.com": [ 5 | "104.16.248.249", 6 | "104.16.249.249" 7 | ] 8 | }, 9 | "servers": [ 10 | "https://cloudflare-dns.com/dns-query" 11 | ] 12 | }, 13 | "inbounds": [ 14 | { 15 | "listen": "127.0.0.1", 16 | "port": 10808, 17 | "protocol": "socks", 18 | "settings": { 19 | "auth": "noauth", 20 | "udp": true, 21 | "userLevel": 8 22 | }, 23 | "sniffing": { 24 | "destOverride": [ 25 | "http", 26 | "tls" 27 | ], 28 | "enabled": true 29 | }, 30 | "tag": "socks" 31 | }, 32 | { 33 | "listen": "127.0.0.1", 34 | "port": 10809, 35 | "protocol": "http", 36 | "settings": { 37 | "userLevel": 8 38 | }, 39 | "tag": "http" 40 | } 41 | ], 42 | "log": { 43 | "loglevel": "warning" 44 | }, 45 | "outbounds": [ 46 | { 47 | "protocol": "freedom", 48 | "settings": { 49 | "fragment": { 50 | "interval": "10-20", 51 | "length": "10-20", 52 | "packets": "tlshello" 53 | } 54 | }, 55 | "streamSettings": { 56 | "network": "tcp", 57 | "security": "", 58 | "sockopt": { 59 | "TcpNoDelay": true, 60 | "domainStrategy": "UseIP", 61 | "mark": 255 62 | } 63 | }, 64 | "tag": "fragment" 65 | }, 66 | { 67 | "protocol": "freedom", 68 | "settings": {}, 69 | "tag": "direct" 70 | }, 71 | { 72 | "protocol": "blackhole", 73 | "settings": { 74 | "response": { 75 | "type": "http" 76 | } 77 | }, 78 | "tag": "block" 79 | }, 80 | { 81 | "protocol": "socks", 82 | "settings": { 83 | "servers": [ 84 | { 85 | "address": "127.0.0.1", 86 | "level": 8, 87 | "method": "chacha20-poly1305", 88 | "ota": false, 89 | "password": "", 90 | "port": 1234 91 | } 92 | ] 93 | }, 94 | "streamSettings": { 95 | "network": "tcp", 96 | "security": "" 97 | }, 98 | "tag": "proxy" 99 | }, 100 | { 101 | "protocol": "dns", 102 | "tag": "dns-out" 103 | } 104 | ], 105 | "remarks": "Peyman_Mci_Fragment", 106 | "routing": { 107 | "domainStrategy": "IPIfNonMatch", 108 | "rules": [ 109 | { 110 | "inboundTag": [ 111 | "socks", 112 | "http" 113 | ], 114 | "type": "field", 115 | "port": "53", 116 | "outboundTag": "dns-out", 117 | "enabled": true 118 | }, 119 | { 120 | "inboundTag": [ 121 | "socks", 122 | "http" 123 | ], 124 | "outboundTag": "fragment", 125 | "type": "field" 126 | } 127 | ] 128 | } 129 | } -------------------------------------------------------------------------------- /Xray-examples/vless-tcp-header.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "loglevel": "warning" 4 | }, 5 | "routing": { 6 | "domainStrategy": "AsIs", 7 | "rules": [ 8 | { 9 | "type": "field", 10 | "ip": [ 11 | "geoip:private" 12 | ], 13 | "outboundTag": "block" 14 | } 15 | ] 16 | }, 17 | "inbounds": [ 18 | { 19 | "listen": "0.0.0.0", 20 | "port": 80, 21 | "protocol": "vless", 22 | "settings": { 23 | "clients": [ 24 | { 25 | "id": "6abe55b9-ec44-46bd-aee2-40bd4d8bc249" 26 | } 27 | ], 28 | "decryption": "none" 29 | }, 30 | "streamSettings": { 31 | "network": "tcp", 32 | "tcpSettings": { 33 | "header": { 34 | "type": "http", 35 | "response": { 36 | "version": "1.1", 37 | "status": "200", 38 | "reason": "OK", 39 | "headers": { 40 | "host": [ 41 | "web.rubika.ir" 42 | ] 43 | }, 44 | "method": "GET", 45 | "path": [ 46 | "/" 47 | ], 48 | "version": "1.1" 49 | }, 50 | "response": { 51 | "headers": {}, 52 | "reason": "OK", 53 | "status": "200", 54 | "version": "1.1" 55 | }, 56 | "type": "http" 57 | } 58 | } 59 | } 60 | } 61 | ], 62 | "outbounds": [ 63 | { 64 | "protocol": "freedom", 65 | "tag": "direct" 66 | }, 67 | { 68 | "protocol": "blackhole", 69 | "tag": "block" 70 | } 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /Xray-examples/vless-ws-header.json: -------------------------------------------------------------------------------- 1 | { 2 | "inbounds": [ 3 | { 4 | "listen": "0.0.0.0", 5 | "port": 80, 6 | "protocol": "vless", 7 | "settings": { 8 | "clients": [ 9 | { 10 | "id": "6abe55b9-ec44-46bd-aee2-40bd4d8bc249" 11 | } 12 | ], 13 | "decryption": "none" 14 | }, 15 | "streamSettings": { 16 | "network": "ws", 17 | "security": "none", 18 | "wsSettings": { 19 | "acceptProxyProtocol": false, 20 | "path": "/", 21 | "headers": { 22 | "host": "bama.ir" 23 | } 24 | } 25 | }, 26 | "tag": "Vless-Ws-header" 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /bash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #colors 4 | red='\033[0;31m' 5 | green='\033[0;32m' 6 | yellow='\033[0;33m' 7 | blue='\033[0;34m' 8 | purple='\033[0;35m' 9 | cyan='\033[0;36m' 10 | white='\033[0;37m' 11 | rest='\033[0m' 12 | 13 | #-------------------------------------------------------# 14 | 15 | # root check 16 | root() { 17 | if [[ $EUID -ne 0 ]]; then 18 | echo -e "${red}Please run as root. Use [sudo -i]${rest}" 19 | exit 1 20 | fi 21 | } 22 | 23 | #-------------------------------------------------------# 24 | #progress 25 | display_progress() { 26 | local duration=$1 27 | local sleep_interval=0.1 28 | local progress=0 29 | local bar_length=40 30 | local colors=("" "" "" "" "" "" "") 31 | 32 | while [ $progress -lt $duration ]; do 33 | echo -ne "\r${colors[$((progress % 7))]}" 34 | for ((i = 0; i < bar_length; i++)); do 35 | if [ $i -lt $((progress * bar_length / duration)) ]; then 36 | echo -ne "█" 37 | else 38 | echo -ne "░" 39 | fi 40 | done 41 | echo -ne " ${progress}%" 42 | progress=$((progress + 1)) 43 | sleep $sleep_interval 44 | done 45 | echo -ne "\r${colors[0]}" 46 | for ((i = 0; i < bar_length; i++)); do 47 | echo -ne " " 48 | done 49 | echo -ne " 100%" 50 | echo 51 | } 52 | 53 | #apt upgrade -y > /dev/null 2>&1 & 54 | #pid=$! 55 | #display_progress 10 56 | #wait "$pid" 57 | 58 | #-------------------------------------------------------# 59 | 60 | #logo 61 | logo_animated() { 62 | colors=("\e[92m" "\e[91m" "\e[93m" "\e[94m" "\e[95m" "\e[96m" "\e[93m" "\e[96m") 63 | NC="\e[0m" 64 | for color in "${colors[@]}"; do 65 | clear 66 | echo -e "\n${color} 67 | ___ ___ ___ ___ ___ ___ 68 | /\ \ /\ \ |\__\ /\__\ /\ \ /\__\ 69 | /::\ \ /::\ \ |:| | /::| | /::\ \ /::| | 70 | /:/\:\ \ /:/\:\ \ |:| | /:|:| | /:/\:\ \ /:|:| | 71 | /::\~\:\ \ /::\~\:\ \ |:|__|__ /:/|:|__|__ /::\~\:\ \ /:/|:| |__ 72 | /:/\:\ \:\__/:/\:\ \:\__\/::::\__/:/ |::::\__/:/\:\ \:\__/:/ |:| /\__\ 73 | \/__\:\/:/ \:\~\:\ \/__/:/~~/~ \/__/~~/:/ \/__\:\/:/ \/__|:|/:/ / 74 | \::/ / \:\ \:\__\/:/ / /:/ / \::/ / |:/:/ / 75 | \/__/ \:\ \/__/\/__/ /:/ / /:/ / |::/ / 76 | \:\__\ /:/ / /:/ / /:/ / 77 | \/__/ \/__/ \/__/ \/__/ 78 | 79 | ${R}\n" 80 | sleep 0.2 81 | done 82 | } 83 | 84 | #-------------------------------------------------------# 85 | 86 | #dependencies 87 | dependencies() { 88 | if command -v apt-get &> /dev/null; then 89 | package_manager="apt" 90 | elif command -v yum &> /dev/null; then 91 | package_manager="yum" 92 | elif command -v dnf &> /dev/null; then 93 | package_manager="dnf" 94 | else 95 | echo "Unsupported package manager. Exiting..." 96 | exit 1 97 | fi 98 | 99 | programs=("wget" "curl" "nano") 100 | 101 | for program in "${programs[@]}"; do 102 | if ! command -v "$program" &> /dev/null; then 103 | echo "$program is not installed. Installing..." 104 | sudo "$package_manager" install -y "$program" 105 | else 106 | echo "$program installed." 107 | fi 108 | done 109 | } 110 | 111 | update() { 112 | dependencies 113 | "$package_manager" update -y 114 | } -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pytube import YouTube 3 | import platform 4 | 5 | def on_progress(stream, chunk, bytes_remaining): 6 | total_size = stream.filesize 7 | bytes_downloaded = total_size - bytes_remaining 8 | percentage = (bytes_downloaded / total_size) * 100 9 | print(f"Downloading : {percentage:.2f}%", end='\r') 10 | 11 | # Clear the terminal based on the OS 12 | if platform.system() == 'Windows': 13 | os.system('cls') 14 | else: 15 | os.system('clear') 16 | 17 | try: 18 | # Get the current working directory 19 | current_dir = os.getcwd() 20 | 21 | # Create the directory if it doesn't exist 22 | download_dir = os.path.join(current_dir, 'YouTube_dl') 23 | os.makedirs(download_dir, exist_ok=True) 24 | 25 | # Get the video link from the user 26 | video_url = input("Enter the video link: ") 27 | 28 | # Create a YouTube object using the link 29 | yt = YouTube(video_url, on_progress_callback=on_progress) 30 | 31 | # Video information 32 | print("----------------------------------------------------------") 33 | print(f"Video Title: {yt.title}") 34 | print(f"Channel Name: {yt.author}") 35 | print(f"Video Duration: {yt.length // 60} minutes {yt.length % 60} seconds") 36 | print(f"Views: {yt.views}") 37 | print(f"Published Date: {yt.publish_date}") 38 | print("----------------------------------------------------------") 39 | print(" ") 40 | 41 | # Get all available download formats 42 | all_formats = yt.streams 43 | 44 | # Filter and sort available formats 45 | audio_formats = [stream for stream in all_formats if stream.includes_audio_track and stream.resolution is not None] 46 | sorted_formats = sorted(audio_formats, key=lambda x: (int(x.resolution[:-1]), -x.filesize), reverse=True) 47 | 48 | # Display sorted quality, format, and file size with numbers 49 | for i, stream in enumerate(sorted_formats): 50 | print(f"{i + 1}. Quality: {stream.resolution}, F/Rate: {stream.fps} fps, Bitrate: {stream.bitrate / 1000} Kbps, Format: {stream.mime_type}, Audio Codec: {stream.audio_codec}, Filesize: {stream.filesize / 1024 / 1024:.2f} MB") 51 | print(" -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ") 52 | 53 | # Let the user choose a desired format by entering a number 54 | choice = int(input("Enter the number of quality: ")) - 1 55 | 56 | # Download the video with the selected quality 57 | selected_format = sorted_formats[choice] 58 | print(f"Downloading with Quality: {selected_format.resolution} ") 59 | selected_format.download(output_path=download_dir) 60 | print(f"Download was successful & Saved to {download_dir}") 61 | 62 | except Exception as e: 63 | print("An error occurred:", str(e)) -------------------------------------------------------------------------------- /certificate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED="\033[31m" 4 | GREEN="\033[32m" 5 | YELLOW="\033[33m" 6 | PLAIN="\033[0m" 7 | 8 | red(){ 9 | echo -e "\033[31m\033[01m$1\033[0m" 10 | } 11 | 12 | green(){ 13 | echo -e "\033[32m\033[01m$1\033[0m" 14 | } 15 | 16 | yellow(){ 17 | echo -e "\033[33m\033[01m$1\033[0m" 18 | } 19 | 20 | detect_distribution() { 21 | local supported_distributions=("ubuntu" "debian" "centos" "fedora") 22 | 23 | if [ -f /etc/os-release ]; then 24 | source /etc/os-release 25 | if [[ "${ID}" == "ubuntu" || "${ID}" == "debian" || "${ID}" == "centos" || "${ID}" == "fedora" ]]; then 26 | pm="apt" 27 | [ "${ID}" == "centos" ] && pm="yum" 28 | [ "${ID}" == "fedora" ] && pm="dnf" 29 | else 30 | echo "Unsupported distribution!" 31 | exit 1 32 | fi 33 | else 34 | echo "Unsupported distribution!" 35 | exit 1 36 | fi 37 | } 38 | 39 | check_dependencies() { 40 | detect_distribution 41 | 42 | local dependencies=("curl" "wget" "openssl" "socat") 43 | 44 | for dep in "${dependencies[@]}"; do 45 | if ! command -v "${dep}" &> /dev/null; then 46 | echo "${dep} is not installed. Installing..." 47 | sudo "${pm}" install "${dep}" -y 48 | fi 49 | done 50 | } 51 | 52 | ip=$(hostname -I | awk '{print $1}') 53 | 54 | inst_cert(){ 55 | check_dependencies 56 | 57 | green "Methods of applying certificate :" 58 | echo "" 59 | echo -e " ${GREEN}1.${PLAIN} Bing self-signed certificate ${YELLOW} (default) ${PLAIN}" 60 | echo -e " ${GREEN}2.${PLAIN} Acme script auto-apply" 61 | echo "" 62 | read -rp "please enter options [1-2]: " certInput 63 | if [[ $certInput == 2 ]]; then 64 | mkdir -p /root/peyman 65 | cert_path="/root/peyman/cert.crt" 66 | key_path="/root/peyman/private.key" 67 | 68 | if [[ -f /root/peyman/cert.crt && -f /root/peyman/private.key ]] && [[ -s /root/peyman/cert.crt && -s /root/peyman/private.key ]] && [[ -f /root/ca.log ]]; then 69 | domain=$(cat /root/ca.log) 70 | green "Legacy domain name detected: certificate for $domain, applying" 71 | hy_domain=$domain 72 | else 73 | read -p "Please enter the domain name:" domain 74 | [[ -z $domain ]] && red "No domain name entered, unable to perform operation!" && exit 1 75 | green "Domain name entered: $domain" && sleep 1 76 | domainIP=$(dig +short "${domain}") 77 | if [[ $domainIP == $ip ]]; then 78 | $pm install socat 79 | if [[ $pm == "apt-get" ]]; then 80 | sudo $pm install cron 81 | elif [[ $pm == "yum" || $pm == "dnf" ]]; then 82 | sudo $pm install cronie 83 | systemctl start crond 84 | systemctl enable crond 85 | fi 86 | 87 | curl https://get.acme.sh | sh -s email=$(date +%s%N | md5sum | cut -c 1-16)@gmail.com 88 | source ~/.bashrc 89 | bash ~/.acme.sh/acme.sh --upgrade --auto-upgrade 90 | bash ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt 91 | if [[ -n $(echo $ip | grep ":") ]]; then 92 | bash ~/.acme.sh/acme.sh --issue -d ${domain} --standalone -k ec-256 --listen-v6 --insecure 93 | else 94 | bash ~/.acme.sh/acme.sh --issue -d ${domain} --standalone -k ec-256 --insecure 95 | fi 96 | bash ~/.acme.sh/acme.sh --install-cert -d ${domain} --key-file /root/peyman/private.key --fullchain-file /root/peyman/cert.crt --ecc 97 | if [[ -f /root/peyman/cert.crt && -f /root/peyman/private.key ]] && [[ -s /root/peyman/cert.crt && -s /root/peyman/private.key ]]; then 98 | echo $domain > /root/ca.log 99 | sed -i '/--cron/d' /etc/crontab >/dev/null 2>&1 100 | echo "0 0 * * * root bash /root/.acme.sh/acme.sh --cron -f >/dev/null 2>&1" | sudo tee -a /etc/crontab >/dev/null 2>&1 101 | green "Successful! The certificate (cer.crt) and private key (private.key) files applied by the script have been saved to the /root folder" 102 | yellow "The certificate crt file path is as follows: /root/peyman/cert.crt" 103 | yellow "The private key file path is as follows: /root/peyman/private.key" 104 | hy_domain=$domain 105 | fi 106 | else 107 | red "The IP resolved by the current domain name does not match the real IP used by the current VPS" 108 | green "suggestions below:" 109 | yellow "1. Please make sure CloudFlare is turned off (DNS only), other domain name resolution or CDN website settings are the same" 110 | yellow "2. Please check whether the IP set by the DNS resolution is the real IP of the VPS" 111 | yellow "3. The script may not keep up with the times, it is recommended to post screenshots to GitHub Issues, or TG groups for inquiries" 112 | exit 1 113 | fi 114 | fi 115 | else 116 | mkdir -p /root/peyman 117 | cert_path="/root/peyman/cert.crt" 118 | key_path="/root/peyman/private.key" 119 | openssl ecparam -genkey -name prime256v1 -out /root/peyman/private.key 120 | openssl req -new -x509 -days 36500 -key /root/peyman/private.key -out /root/peyman/cert.crt -subj "/CN=www.bing.com" 121 | chmod 777 /root/peyman/cert.crt 122 | sudo chmod 777 /root/peyman/private.key 123 | hy_domain="www.bing.com" 124 | domain="www.bing.com" 125 | green "Generated Successfully! You can now use them ." 126 | fi 127 | } 128 | 129 | renew() { 130 | read -p "Enter your domain: " renew_domain 131 | 132 | if [ -z "$renew_domain" ]; then 133 | echo "Domain is required." 134 | exit 1 135 | fi 136 | 137 | /root/.acme.sh/acme.sh --renew -d $renew_domain --force 138 | 139 | echo "SSL certificate renewed successfully!" 140 | } 141 | 142 | clear 143 | echo "By --> Peyman * Github.com/Ptechgithub * " 144 | echo "" 145 | echo "1) Get SSL certificate" 146 | echo "2) Renew scme certificates" 147 | echo "0) Exit" 148 | read -p "Please choose: " choice 149 | 150 | case $choice in 151 | 1) 152 | inst_cert 153 | ;; 154 | 2) 155 | renew 156 | ;; 157 | 0) 158 | echo "Exiting..." 159 | exit 0 160 | ;; 161 | *) 162 | echo "Invalid choice. Please enter a number between 0 and 2." 163 | ;; 164 | esac -------------------------------------------------------------------------------- /clash12.yaml: -------------------------------------------------------------------------------- 1 | #Github :Github.com/Ptechgithub 2 | #YouTube :www.youtube.com/@IR_TECH 3 | #====Reference from clash-meta official document: wiki.metacubex.one===== 4 | 5 | # (Part 1) ============================== (clash configuration) 6 | # dns can be modified by yourself 7 | port: 7890 8 | allow-lan: true 9 | mode: rule 10 | log-level: info 11 | unified-delay: true 12 | global-client-fingerprint: chrome 13 | dns: 14 | enable: true 15 | listen: :53 16 | ipv6: true 17 | enhanced-mode: fake-ip 18 | fake-ip-range: 198.18.0.1/16 19 | default-nameserver: 20 | - 223.5.5.5 21 | - 8.8.8.8 22 | nameserver: 23 | - https://dns.alidns.com/dns-query 24 | - https://1.1.1.1/dns-query 25 | fallback: 26 | - https://1.0.0.1/dns-query 27 | - tls://1.1.1.1 28 | fallback-filter: 29 | geoip: true 30 | geoip-code: IR 31 | ipcidr: 32 | - 240.0.0.0/4 33 | 34 | 35 | 36 | # (Part 2) ================================ (Configs) 37 | # Currently 12 protocol node configuration templates, modify according to requirements, if a certain protocol node is not used, there is no need to delete it, just make sure that the node name does not exist in (Part 3) 38 | proxies: 39 | #==============1================(vless-reality-vision node) 40 | - name: vless-reality-vision node #Customizable name 41 | type: vless 42 | server: for.forcedparadise.space #The resolved domain name or IP 43 | port: 101 #custom port 44 | uuid: bbab7aaf-f77c-480c-be00-276c35eeedd3 #custom uuid 45 | network: tcp 46 | udp: true 47 | tls: true 48 | flow: xtls-rprx-vision 49 | servername: google.com #custom SNI 50 | reality-opts: 51 | public-key: JHvkY6wjxkk6c7CUjVR63QumCQewWrvo2VebduKcqCA #custom public-key 52 | short-id: b4c5fc07 #custom short-id 53 | client-fingerprint: chrome #Custom browser fingerprinting 54 | 55 | #==============2================(vless-reality-grpc node) 56 | - name: vless-reality-grpc node #Customizable name 57 | type: vless 58 | server: for.forcedparadise.space #The resolved domain name or IP 59 | port: 102 #custom port 60 | uuid: 86934f59-255a-47f0-a495-38b4a7dc8a6c #custom uuid 61 | network: grpc 62 | tls: true 63 | udp: true 64 | flow: 65 | client-fingerprint: chrome #Custom browser fingerprinting 66 | servername: google.com #custom SNI 67 | grpc-opts: 68 | grpc-service-name: "Peyman" #" "custom characters 69 | reality-opts: 70 | public-key: 7V6PMJXFEHWIl5pIOqqWLWnC5UYr48pn4a43rI98oQQ #custom public-key 71 | short-id: c76cc99e #custom short-id 72 | 73 | #=============3=================(vless-ws-tls node) 74 | - name: vless-ws-tls node #Customizable name 75 | type: vless 76 | server: 104.31.16.60 #resolved domain name or preferred domain name IP 77 | port: 2083 #custom port 78 | uuid: 94ad16a0-1783-4b76-b04b-ac895c862c3d #custom uuid 79 | udp: true 80 | tls: true 81 | network: ws 82 | servername: for.forcedparadise.space #sni domain name, consistent with the following host 83 | ws-opts: 84 | path: "/?ed=2048" #" "inner custom path 85 | headers: 86 | Host: for.forcedparadise.space #host domain name, consistent with the above servername 87 | 88 | #=============4=================(vless-ws node) 89 | - name: vless-ws node #Customizable name 90 | type: vless 91 | server: for.forcedparadise.space #resolved domain name or preferred domain name IP 92 | port: 103 #custom port 93 | uuid: fc05dc52-2be7-4667-92dd-8b536535395c #custom uuid 94 | udp: true 95 | tls: false 96 | network: ws 97 | servername: for.forcedparadise.space #sni domain name, consistent with the following host 98 | ws-opts: 99 | path: "/?ed=2048" #" "inner custom path 100 | headers: 101 | Host: for.forcedparadise.space #host domain name, consistent with the above servername 102 | 103 | #===============5===============(vmess-ws-tls node) 104 | - name: vmess-ws-tls node #Customizable name 105 | type: vmess 106 | server: 104.31.16.60 #resolved domain name or preferred domain name IP 107 | port: 8443 #custom port 108 | uuid: 88d8e461-1a60-4707-81bc-18621a250981 #custom uuid 109 | alterId: 0 110 | cipher: auto 111 | udp: true 112 | tls: true 113 | network: ws 114 | servername: for.forcedparadise.space #sni domain name, consistent with the following host 115 | ws-opts: 116 | path: "/?ed=2048" #custom path 117 | headers: 118 | Host: for.forcedparadise.space #host domain name, consistent with the above servername 119 | 120 | #=============6=================(vmess-ws node) 121 | - name: vmess-ws node #Customizable name 122 | type: vmess 123 | server: for.forcedparadise.space #resolved domain name or preferred domain name IP 124 | port: 104 #custom port 125 | uuid: f3aa6a3f-dfef-3a92-8a0b-a3229625dc23 #custom uuid 126 | alterId: 0 127 | cipher: auto 128 | udp: true 129 | tls: false 130 | network: ws 131 | servername: for.forcedparadise.space #sni domain name, consistent with the following host 132 | ws-opts: 133 | path: "/?ed=2048" #" "inner custom path 134 | headers: 135 | Host: for.forcedparadise.space #host domain name, consistent with the above servername 136 | 137 | #=============7=================(trojan-tcp-tls node) 138 | - name: trojan-tcp-tls node #Customizable name 139 | type: trojan 140 | server: for.forcedparadise.space #resolved domain name 141 | port: 443 #custom port 142 | password: x9yz70zXEm #custom password 143 | client-fingerprint: chrome 144 | udp: true 145 | sni: for.forcedparadise.space #sni domain name, consistent with the above server address 146 | alpn: 147 | - h2 148 | - http/1.1 149 | skip-cert-verify: true 150 | 151 | #==============8================(hysteria certificate node) 152 | - name: hysteria certificate node #Customizable name 153 | type: hysteria 154 | server: for.forcedparadise.space #resolved domain name 155 | port: 105 #Custom port, change multiple ports to ports: space 1000,2000-3000 156 | auth-str: 126456 #custom password 157 | alpn: 158 | - h3 159 | protocol: udp #Custom protocol: udp/wechat-video/faketcp 160 | up: 50 #Custom upload limit 161 | down: 200 #Custom Download Limits 162 | sni: for.forcedparadise.space #sni domain name, consistent with the above server address 163 | skip-cert-verify: false 164 | fast-open: true 165 | 166 | #=============9=================(hysteria self signed node) 167 | - name: hysteria self signed node #Customizable name 168 | type: hysteria 169 | server: 91.107.23.17 #Server local IP 170 | port: 106 #Custom port 171 | auth-str: 12345 #custom password 172 | alpn: 173 | - h3 174 | protocol: udp #Custom protocol: udp/wechat-video/faketcp 175 | up: 40 #Custom upload limit 176 | down: 100 #Custom Download Limits 177 | sni: www.bing.com 178 | skip-cert-verify: true 179 | fast-open: true 180 | 181 | #==============10================(tuic-V5 node) 182 | - name: tuic-V5 node #Customizable name 183 | server: tuic.forcedparadise.space #The resolved domain name or IP 184 | port: 107 #custom port 185 | type: tuic 186 | uuid: d0c12467-506f-49b2-8481-93afc89cfe0f #custom uuid 187 | password: 12345 #custom password 188 | alpn: ["h3", "spdy/3.1"] 189 | disable-sni: true 190 | reduce-rtt: true 191 | udp-relay-mode: native 192 | congestion-controller: bbr 193 | 194 | #==============11================(tuic-V5 node IP V6) 195 | - name: tuic-V5 node V6 #Customizable name 196 | server: 2a01:4f8:1c1b:c14::1 #The resolved domain name or IPV6 197 | port: 108 #custom port 198 | type: tuic 199 | uuid: d0c22467-516f-42b2-8781-93afc89cfe0f #custom uuid 200 | password: 12345 #custom password 201 | alpn: ["h3", "spdy/3.1"] 202 | disable-sni: true 203 | reduce-rtt: true 204 | udp-relay-mode: native 205 | congestion-controller: bbr 206 | #===============12===============(warp-wireguard node) 207 | - name: warp-wireguard node #Customizable name 208 | type: wireguard 209 | server: 162.159.193.10 #You can customize the preferred peer IP, which corresponds to the port below 210 | port: 2408 #You can customize the preferred peer IP, which corresponds to the IP of the server above 211 | ip: 172.16.0.2 212 | ipv6: 2606:4700:190:814e:7de3:5ddb:9d3e:9359 #Corresponding to private-key, if you delete this line, it means only IPV4 213 | public-key: bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= 214 | private-key: gK3C8ijdVlT7sd5fsdf5ssdfgsdfgsdfgobT2U+rgHo= #Get private-key 215 | udp: true 216 | 217 | 218 | 219 | #(part 3) ================================ (Proxy Group Configuration) 220 | #The diversion group can be created and added by itself. The name node name under the proxies parameter can be increased or decreased according to the needs to ensure that the name node name that appears can be found in the proxy agreement of the (Part 2) 221 | proxy-groups: 222 | - name: 🔠Load balancing 223 | type: load-balance 224 | url: http://www.gstatic.com/generate_204 225 | interval: 300 226 | proxies: 227 | - vless-reality-vision node 228 | - vless-reality-grpc node 229 | - vless-ws-tls node 230 | - vless-ws node 231 | - vmess-ws-tls node 232 | - vmess-ws node 233 | - trojan-tcp-tls node 234 | - hysteria certificate node 235 | - hysteria self signed node 236 | - tuic-V5 node 237 | - tuic-V5 node V6 238 | - warp-wireguard node 239 | 240 | - name: ♻️Auto choose 241 | type: url-test 242 | url: http://www.gstatic.com/generate_204 243 | interval: 300 244 | tolerance: 50 245 | proxies: 246 | - vless-reality-vision node 247 | - vless-reality-grpc node 248 | - vless-ws-tls node 249 | - vless-ws node 250 | - vmess-ws-tls node 251 | - vmess-ws node 252 | - trojan-tcp-tls node 253 | - hysteria certificate node 254 | - hysteria self signed node 255 | - tuic-V5 node 256 | - tuic-V5 node V6 257 | - warp-wireguard node 258 | 259 | - name: 🌍All proxy 260 | type: select 261 | proxies: 262 | - 🔠Load balancing #Customize the name field of the added protocol 263 | - ♻️Auto choose 264 | - DIRECT 265 | - vless-reality-vision node 266 | - vless-reality-grpc node 267 | - vless-ws-tls node 268 | - vless-ws node 269 | - vmess-ws-tls node 270 | - vmess-ws node 271 | - trojan-tcp-tls node 272 | - hysteria certificate node 273 | - hysteria self signed node 274 | - tuic-V5 node 275 | - tuic-V5 node V6 276 | - warp-wireguard node 277 | 278 | 279 | 280 | #(Part 4) ================================ (Rules) 281 | # Proxy rules can be added by themselves 282 | rules: 283 | - GEOIP,IR,DIRECT 284 | - MATCH,🌍All proxy 285 | -------------------------------------------------------------------------------- /config-fregment.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "loglevel": "warning" 4 | }, 5 | "routing": { 6 | "domainStrategy": "AsIs", 7 | "rules": [ 8 | { 9 | "type": "field", 10 | "ip": [ 11 | "geoip:private" 12 | ], 13 | "outboundTag": "block" 14 | } 15 | ] 16 | }, 17 | "inbounds": [ 18 | { 19 | "listen": "0.0.0.0", 20 | "port": 80, 21 | "protocol": "vmess", 22 | "settings": { 23 | "clients": [ 24 | { 25 | "id": "3e992e24-b4de-4fea-9e34-2ae3d9aee34e" 26 | } 27 | ] 28 | }, 29 | "streamSettings": { 30 | "network": "ws", 31 | "security": "none" 32 | } 33 | } 34 | ], 35 | "outbounds": [ 36 | { 37 | "protocol": "freedom", 38 | "tag": "direct", 39 | "settings": { 40 | "domainStrategy": "AsIs", 41 | "fragment": { 42 | "packets": "tlshello", 43 | "length": "100-200", 44 | "interval": "10-20" 45 | } 46 | } 47 | }, 48 | { 49 | "protocol": "blackhole", 50 | "tag": "block" 51 | } 52 | ] 53 | } -------------------------------------------------------------------------------- /media/1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/1-1.png -------------------------------------------------------------------------------- /media/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/1.jpg -------------------------------------------------------------------------------- /media/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/10.jpg -------------------------------------------------------------------------------- /media/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/11.jpg -------------------------------------------------------------------------------- /media/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/12.jpg -------------------------------------------------------------------------------- /media/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/13.jpg -------------------------------------------------------------------------------- /media/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/14.jpg -------------------------------------------------------------------------------- /media/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/15.jpg -------------------------------------------------------------------------------- /media/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/16.jpg -------------------------------------------------------------------------------- /media/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/17.jpg -------------------------------------------------------------------------------- /media/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/18.jpg -------------------------------------------------------------------------------- /media/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/19.jpg -------------------------------------------------------------------------------- /media/2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/2-2.png -------------------------------------------------------------------------------- /media/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/2.jpg -------------------------------------------------------------------------------- /media/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/20.jpg -------------------------------------------------------------------------------- /media/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/21.jpg -------------------------------------------------------------------------------- /media/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/22.jpg -------------------------------------------------------------------------------- /media/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/23.gif -------------------------------------------------------------------------------- /media/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/24.gif -------------------------------------------------------------------------------- /media/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/25.jpg -------------------------------------------------------------------------------- /media/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/26.jpg -------------------------------------------------------------------------------- /media/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/27.jpg -------------------------------------------------------------------------------- /media/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/28.jpg -------------------------------------------------------------------------------- /media/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/29.jpg -------------------------------------------------------------------------------- /media/3-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/3-3.jpeg -------------------------------------------------------------------------------- /media/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/3.jpg -------------------------------------------------------------------------------- /media/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/30.jpg -------------------------------------------------------------------------------- /media/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/31.jpg -------------------------------------------------------------------------------- /media/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/32.jpg -------------------------------------------------------------------------------- /media/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/33.jpg -------------------------------------------------------------------------------- /media/4-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/4-4.jpg -------------------------------------------------------------------------------- /media/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/4.jpg -------------------------------------------------------------------------------- /media/5-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/5-5.jpg -------------------------------------------------------------------------------- /media/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/5.jpg -------------------------------------------------------------------------------- /media/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/6.jpg -------------------------------------------------------------------------------- /media/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/7.jpg -------------------------------------------------------------------------------- /media/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/8.jpg -------------------------------------------------------------------------------- /media/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/9.jpg -------------------------------------------------------------------------------- /media/Waterwall: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/Waterwall -------------------------------------------------------------------------------- /media/h.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/h.mp3 -------------------------------------------------------------------------------- /media/line.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/line.gif -------------------------------------------------------------------------------- /media/neko.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ptechgithub/configs/1c8c59cf7bc4118d32fd42fe29c1bfe5e3f85a96/media/neko.gif -------------------------------------------------------------------------------- /mtu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: 4 | # $1: Hostname 5 | # $2: Starting MTU (default 1540) 6 | # $3: Timeout in seconds (default 0.3) 7 | # $4: Starting MTU increment (default 10) 8 | 9 | # Ensure hostname is provided 10 | [ -z $1 ] && echo "Hostname must be specified." && exit 1 11 | 12 | # Set default values if arguments are not provided 13 | mtu=${2:-1540} 14 | timeout=${3:-0.3} 15 | increment=${4:-10} 16 | 17 | # Initialize variables 18 | goodjob=0 19 | 20 | # Loop until optimal MTU is found 21 | while :; do 22 | # Ping with adjusted MTU size 23 | timeout $timeout ping -s $(($mtu-28)) -M do -c 1 -q -n $1 >/dev/null 2>/dev/null 24 | 25 | # Check ping result 26 | if [ $? != 0 ]; then 27 | mtu=$(($mtu-$increment)) 28 | [ "$goodjob" = 1 ] && break 29 | else 30 | [ "$increment" = 1 ] && goodjob=1 31 | increment=1 32 | mtu2=$mtu 33 | mtu=$(($mtu+$increment)) 34 | fi 35 | done 36 | 37 | # Print the optimal MTU size 38 | echo "Optimal MTU size: $mtu2" -------------------------------------------------------------------------------- /vmess.json: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "loglevel": "warning" 4 | }, 5 | "routing": { 6 | "domainStrategy": "AsIs", 7 | "rules": [ 8 | { 9 | "type": "field", 10 | "ip": [ 11 | "geoip:private" 12 | ], 13 | "outboundTag": "block" 14 | } 15 | ] 16 | }, 17 | "inbounds": [ 18 | { 19 | "listen": "0.0.0.0", 20 | "port": 80, 21 | "protocol": "vmess", 22 | "settings": { 23 | "clients": [ 24 | { 25 | "id": "3e992e24-b4de-4fea-9e34-2ae3d9aee34e" 26 | } 27 | ] 28 | }, 29 | "streamSettings": { 30 | "network": "ws", 31 | "security": "none" 32 | } 33 | } 34 | ], 35 | "outbounds": [ 36 | { 37 | "protocol": "freedom", 38 | "tag": "direct" 39 | }, 40 | { 41 | "protocol": "blackhole", 42 | "tag": "block" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /wa.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | import json 3 | import datetime 4 | import random 5 | import string 6 | import time 7 | import os 8 | import sys 9 | 10 | os.system("title WARP-PLUS-CLOUDFLARE URSECRET") 11 | os.system('cls' if os.name == 'nt' else 'clear') 12 | 13 | file_paths = { 14 | "Primary": "/data/data/com.termux/files/home/.cache/warp-plus/primary/wgcf-identity.json", 15 | "Secondary": "/data/data/com.termux/files/home/.cache/warp-plus/secondary/wgcf-identity.json" 16 | } 17 | 18 | def display_id(file_path, name): 19 | if os.path.exists(file_path): 20 | with open(file_path, "r") as file: 21 | identity_data = json.load(file) 22 | return f"[{name} ID]\nID: {identity_data.get('id', 'Not set')}\n\n" 23 | else: 24 | return f"[{name} ID]\nID: Not set\n\n" 25 | 26 | print (" ======= Warp to Warp plus ======") 27 | print("") 28 | print(display_id(file_paths['Primary'], "Primary")) 29 | print(display_id(file_paths['Secondary'], "Secondary")) 30 | print ("---------------------------------------") 31 | 32 | option = input("[#] Choose an option:\n[1] Primary ID\n[2] Secondary ID\n[3] Manual (Enter ID)\n[4] Cancel\nChoice: ") 33 | 34 | if option == "1": 35 | file_path = file_paths.get("Primary", "") 36 | elif option == "2": 37 | file_path = file_paths.get("Secondary", "") 38 | elif option == "3": 39 | file_path = None 40 | elif option == "4": 41 | print("Goodbye 👋...") 42 | sys.exit(0) 43 | else: 44 | print("Invalid option. Please choose a valid option.") 45 | sys.exit(1) 46 | 47 | if file_path and os.path.exists(file_path): 48 | with open(file_path, "r") as file: 49 | identity_data = json.load(file) 50 | referrer = identity_data.get("id", "") 51 | else: 52 | referrer = input("[#] ENTER WARP+ ID : ") 53 | 54 | def genString(stringLength): 55 | try: 56 | letters = string.ascii_letters + string.digits 57 | return ''.join(random.choice(letters) for i in range(stringLength)) 58 | except Exception as error: 59 | print(error) 60 | 61 | def digitString(stringLength): 62 | try: 63 | digit = string.digits 64 | return ''.join((random.choice(digit) for i in range(stringLength))) 65 | except Exception as error: 66 | print(error) 67 | 68 | url = f'https://api.cloudflareclient.com/v0a{digitString(3)}/reg' 69 | 70 | def run(): 71 | try: 72 | install_id = genString(22) 73 | body = {"key": "{}=".format(genString(43)), 74 | "install_id": install_id, 75 | "fcm_token": "{}:APA91b{}".format(install_id, genString(134)), 76 | "referrer": referrer, 77 | "warp_enabled": False, 78 | "tos": datetime.datetime.now().isoformat()[:-3] + "+02:00", 79 | "type": "Android", 80 | "locale": "es_ES"} 81 | data = json.dumps(body).encode('utf8') 82 | headers = {'Content-Type': 'application/json; charset=UTF-8', 83 | 'Host': 'api.cloudflareclient.com', 84 | 'Connection': 'Keep-Alive', 85 | 'Accept-Encoding': 'gzip', 86 | 'User-Agent': 'okhttp/3.12.1' 87 | } 88 | req = urllib.request.Request(url, data, headers) 89 | response = urllib.request.urlopen(req) 90 | status_code = response.getcode() 91 | return status_code 92 | except Exception as error: 93 | print(error) 94 | 95 | g = 0 96 | b = 0 97 | while True: 98 | result = run() 99 | if result == 200: 100 | g = g + 1 101 | os.system('cls' if os.name == 'nt' else 'clear') 102 | print("") 103 | print(" WARP-PLUS-CLOUDFLARE ") 104 | print("") 105 | animation = ["[■□□□□□□□□□] 10%","[■■□□□□□□□□] 20%", "[■■■□□□□□□□] 30%", "[■■■■□□□□□□] 40%", "[■■■■■□□□□□] 50%", "[■■■■■■□□□□] 60%", "[■■■■■■■□□□] 70%", "[■■■■■■■■□□] 80%", "[■■■■■■■■■□] 90%", "[■■■■■■■■■■] 100%"] 106 | for i in range(len(animation)): 107 | time.sleep(0.4) 108 | sys.stdout.write("\r[+] Preparing... " + animation[i % len(animation)]) 109 | sys.stdout.flush() 110 | print(f"\n[-] WORK ON ID: {referrer}") 111 | print(f"[:)] {g} GB HAS BEEN SUCCESSFULLY ENTERED INTO YOUR ACCOUNT.") 112 | print(f"[#] Total: {g} Good {b} Bad") 113 | print("[*] AFTER 20 SECONDS A NEW REQUEST WILL BE SENT.") 114 | print(f" Please wait 20 seconds...") 115 | time.sleep(20) 116 | else: 117 | b = b + 1 118 | os.system('cls' if os.name == 'nt' else 'clear') 119 | print("") 120 | print("WARP-PLUS-CLOUDFLARE ") 121 | print("") 122 | print("[:(] Error when connecting to server.") 123 | print(f"[#] Total: {g} Good {b} Bad") -------------------------------------------------------------------------------- /wg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #distribution 4 | detect_distribution() { 5 | # Detect the Linux distribution 6 | local supported_distributions=("ubuntu" "debian" "centos" "fedora") 7 | if [ -f /etc/os-release ]; then 8 | source /etc/os-release 9 | if [[ "${ID}" = "ubuntu" || "${ID}" = "debian" || "${ID}" = "centos" || "${ID}" = "fedora" ]]; then 10 | PM="apt" 11 | [ "${ID}" = "centos" ] && PM="yum" 12 | [ "${ID}" = "fedora" ] && PM="dnf" 13 | else 14 | echo "Unsupported distribution!" 15 | exit 1 16 | fi 17 | else 18 | echo "Unsupported distribution!" 19 | exit 1 20 | fi 21 | } 22 | 23 | check_dependencies() { 24 | detect_distribution 25 | local dependencies=("curl") 26 | for dep in "${dependencies[@]}"; do 27 | if ! command -v "${dep}" &> /dev/null; then 28 | echo "${dep} is not installed. Installing..." 29 | sudo "$PM" update -y 30 | sudo "${PM}" install "${dep}" -y 31 | fi 32 | done 33 | } 34 | 35 | install_docker() { 36 | if ! command -v docker &> /dev/null; then 37 | echo "Docker is not installed. Installing..." 38 | curl -fsSL https://get.docker.com -o get-docker.sh 39 | sudo sh get-docker.sh 40 | sudo systemctl start docker 41 | sudo systemctl enable docker 42 | fi 43 | } 44 | 45 | install_docker_compose() { 46 | if ! command -v docker-compose &> /dev/null; then 47 | echo "Docker Compose is not installed. Installing..." 48 | sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 49 | sudo chmod +x /usr/local/bin/docker-compose 50 | fi 51 | } 52 | 53 | install() { 54 | check_dependencies 55 | install_docker 56 | install_docker_compose 57 | mkdir -p docker/wireguard 58 | cd docker/wireguard 59 | 60 | read -p "Enter server IP: " IP 61 | read -p "Enter Tcp Port (default is : 51821): " Tcp_Port 62 | Tcp_Port=${Tcp_Port:-51821} 63 | read -p "Enter Udp Port (default is : 51820): " Udp_Port 64 | Udp_Port=${Udp_Port:-51820} 65 | read -p "Enter Password: " PASSWORD 66 | read -p "Enter DNS (default is : 1.1.1.1) : " DNS 67 | DNS=${DNS:-1.1.1.1} 68 | read -p "Enter MTU (default is : 1420) : " MTU 69 | MTU=${MTU:-1420} 70 | 71 | cat < docker-compose.yml 72 | version: "3.8" 73 | services: 74 | wg-easy: 75 | environment: 76 | - WG_HOST=$IP 77 | - PASSWORD=$PASSWORD 78 | - WG_PORT=$Udp_Port 79 | - WG_DEFAULT_ADDRESS=10.8.0.x 80 | - WG_DEFAULT_DNS=$DNS 81 | - WG_MTU=$MTU 82 | # - WG_ALLOWED_IPS=192.168.15.0/24, 10.0.1.0/24 83 | # - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt 84 | # - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt 85 | # - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt 86 | # - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt 87 | 88 | image: weejewel/wg-easy 89 | container_name: wg-easy 90 | volumes: 91 | - .:/etc/wireguard 92 | ports: 93 | - "$Udp_Port:51820/udp" 94 | - "$Tcp_Port:51821/tcp" 95 | restart: always 96 | cap_add: 97 | - NET_ADMIN 98 | - SYS_MODULE 99 | sysctls: 100 | - net.ipv4.ip_forward=1 101 | - net.ipv4.conf.all.src_valid_mark=1 102 | EOL 103 | 104 | docker-compose up -d 105 | echo "The installation is finished" 106 | } 107 | 108 | uninstall() { 109 | container_id=$(docker ps -qf "ancestor=weejewel/wg-easy") 110 | 111 | if [ -n "$container_id" ]; then 112 | echo "Stopping the container..." 113 | docker stop "$container_id" 114 | echo "Container stopped successfully." 115 | 116 | echo "Removing the container..." 117 | docker rm "$container_id" 118 | rm -rf docker/wireguard 119 | echo "Uninstall completed." 120 | else 121 | echo "Wireguard is not Installed." 122 | fi 123 | } 124 | 125 | # Main menu 126 | clear 127 | echo "By --> Peyman * Github.com/Ptechgithub * " 128 | echo "" 129 | echo " --------#- Wireguard-#--------" 130 | echo "1) Install" 131 | echo "2) Uninstall" 132 | echo "0) Exit" 133 | read -p "Enter your choice: " choice 134 | 135 | case $choice in 136 | 1) 137 | install 138 | ;; 139 | 2) 140 | uninstall 141 | ;; 142 | 0) 143 | exit 0 144 | ;; 145 | *) 146 | echo "Invalid choice. Please select a valid option." 147 | ;; 148 | esac 149 | -------------------------------------------------------------------------------- /worker.js: -------------------------------------------------------------------------------- 1 | // version base on commit 43fad05dcdae3b723c53c226f8181fc5bd47223e, time is 2023-06-22 15:20:02 UTC. 2 | // @ts-ignore 3 | import { connect } from 'cloudflare:sockets'; 4 | 5 | // How to generate your own UUID: 6 | // [Windows] Press "Win + R", input cmd and run: Powershell -NoExit -Command "[guid]::NewGuid()" 7 | let userID = 'd342d11e-d424-4583-b36e-524ab1f0afa4'; 8 | 9 | const proxyIPs = ['cdn-all.xn--b6gac.eu.org', 'cdn.xn--b6gac.eu.org', 'cdn-b100.xn--b6gac.eu.org', 'edgetunnel.anycast.eu.org', 'cdn.anycast.eu.org']; 10 | 11 | let proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)]; 12 | 13 | let dohURL = 'https://sky.rethinkdns.com/1:-Pf_____9_8A_AMAIgE8kMABVDDmKOHTAKg='; // https://cloudflare-dns.com/dns-query or https://dns.google/dns-query 14 | 15 | // v2board api environment variables (optional) deprecated, please use planetscale.com instead 16 | 17 | if (!isValidUUID(userID)) { 18 | throw new Error('uuid is invalid'); 19 | } 20 | 21 | export default { 22 | /** 23 | * @param {import("@cloudflare/workers-types").Request} request 24 | * @param {{UUID: string, PROXYIP: string, DNS_RESOLVER_URL: string, NODE_ID: int, API_HOST: string, API_TOKEN: string}} env 25 | * @param {import("@cloudflare/workers-types").ExecutionContext} ctx 26 | * @returns {Promise} 27 | */ 28 | async fetch(request, env, ctx) { 29 | // uuid_validator(request); 30 | try { 31 | userID = env.UUID || userID; 32 | proxyIP = env.PROXYIP || proxyIP; 33 | dohURL = env.DNS_RESOLVER_URL || dohURL; 34 | let userID_Path = userID; 35 | if (userID.includes(',')) { 36 | userID_Path = userID.split(',')[0]; 37 | } 38 | const upgradeHeader = request.headers.get('Upgrade'); 39 | if (!upgradeHeader || upgradeHeader !== 'websocket') { 40 | const url = new URL(request.url); 41 | switch (url.pathname) { 42 | case '/cf': 43 | return new Response(JSON.stringify(request.cf, null, 4), { 44 | status: 200, 45 | headers: { 46 | "Content-Type": "application/json;charset=utf-8", 47 | }, 48 | }); 49 | case `/${userID_Path}`: { 50 | const vlessConfig = getVLESSConfig(userID, request.headers.get('Host')); 51 | return new Response(`${vlessConfig}`, { 52 | status: 200, 53 | headers: { 54 | "Content-Type": "text/html; charset=utf-8", 55 | } 56 | }); 57 | } 58 | case `/sub/${userID_Path}`: { 59 | const url = new URL(request.url); 60 | const searchParams = url.searchParams; 61 | let vlessConfig = createVLESSSub(userID, request.headers.get('Host')); 62 | // If 'format' query param equals to 'clash', convert config to base64 63 | if (searchParams.get('format') === 'clash') { 64 | vlessConfig = btoa(vlessConfig); 65 | } 66 | // Construct and return response object 67 | return new Response(vlessConfig, { 68 | status: 200, 69 | headers: { 70 | "Content-Type": "text/plain;charset=utf-8", 71 | } 72 | }); 73 | } 74 | case `/bestip/${userID_Path}`: { 75 | const bestiplink = `https://sub.xf.free.hr/auto?host=${request.headers.get('Host')}&uuid=${userID_Path}` 76 | const reqHeaders = new Headers(request.headers); 77 | const bestipresponse = await fetch(bestiplink, { redirect: 'manual', headers: reqHeaders, }); 78 | // Construct and return response object 79 | return bestipresponse 80 | } 81 | default: 82 | // return new Response('Not found', { status: 404 }); 83 | // For any other path, reverse proxy to 'www.fmprc.gov.cn' and return the original response, caching it in the process 84 | const hostnames = ['www.fmprc.gov.cn', 'www.xuexi.cn', 'www.gov.cn', 'mail.gov.cn', 'www.mofcom.gov.cn', 'www.gfbzb.gov.cn', 'www.miit.gov.cn', 'www.12377.cn']; 85 | url.hostname = hostnames[Math.floor(Math.random() * hostnames.length)]; 86 | url.protocol = 'https:'; 87 | 88 | const newHeaders = new Headers(request.headers); 89 | newHeaders.set('cf-connecting-ip', newHeaders.get('x-forwarded-for') || newHeaders.get('cf-connecting-ip')); 90 | newHeaders.set('x-forwarded-for', newHeaders.get('cf-connecting-ip')); 91 | newHeaders.set('x-real-ip', newHeaders.get('cf-connecting-ip')); 92 | newHeaders.set('referer', 'https://www.google.com/q=edtunnel'); 93 | 94 | request = new Request(url, { 95 | method: request.method, 96 | headers: newHeaders, 97 | body: request.body, 98 | redirect: request.redirect, 99 | }); 100 | 101 | const cache = caches.default; 102 | let response = await cache.match(request); 103 | 104 | if (!response) { 105 | try { 106 | response = await fetch(request, { redirect: 'manual' }); 107 | } catch (err) { 108 | url.protocol = 'http:'; 109 | url.hostname = hostnames[Math.floor(Math.random() * hostnames.length)]; 110 | request = new Request(url, { 111 | method: request.method, 112 | headers: newHeaders, 113 | body: request.body, 114 | redirect: request.redirect, 115 | }); 116 | response = await fetch(request, { redirect: 'manual' }); 117 | } 118 | 119 | const cloneResponse = response.clone(); 120 | ctx.waitUntil(cache.put(request, cloneResponse)); 121 | } 122 | return response; 123 | } 124 | } else { 125 | return await vlessOverWSHandler(request); 126 | } 127 | } catch (err) { 128 | /** @type {Error} */ let e = err; 129 | return new Response(e.toString()); 130 | } 131 | }, 132 | }; 133 | 134 | export async function uuid_validator(request) { 135 | const hostname = request.headers.get('Host'); 136 | const currentDate = new Date(); 137 | 138 | const subdomain = hostname.split('.')[0]; 139 | const year = currentDate.getFullYear(); 140 | const month = String(currentDate.getMonth() + 1).padStart(2, '0'); 141 | const day = String(currentDate.getDate()).padStart(2, '0'); 142 | 143 | const formattedDate = `${year}-${month}-${day}`; 144 | 145 | // const daliy_sub = formattedDate + subdomain 146 | const hashHex = await hashHex_f(subdomain); 147 | // subdomain string contains timestamps utc and uuid string TODO. 148 | console.log(hashHex, subdomain, formattedDate); 149 | } 150 | 151 | export async function hashHex_f(string) { 152 | const encoder = new TextEncoder(); 153 | const data = encoder.encode(string); 154 | const hashBuffer = await crypto.subtle.digest('SHA-256', data); 155 | const hashArray = Array.from(new Uint8Array(hashBuffer)); 156 | const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join(''); 157 | return hashHex; 158 | } 159 | 160 | /** 161 | * Handles VLESS over WebSocket requests by creating a WebSocket pair, accepting the WebSocket connection, and processing the VLESS header. 162 | * @param {import("@cloudflare/workers-types").Request} request The incoming request object. 163 | * @returns {Promise} A Promise that resolves to a WebSocket response object. 164 | */ 165 | async function vlessOverWSHandler(request) { 166 | const webSocketPair = new WebSocketPair(); 167 | const [client, webSocket] = Object.values(webSocketPair); 168 | webSocket.accept(); 169 | 170 | let address = ''; 171 | let portWithRandomLog = ''; 172 | let currentDate = new Date(); 173 | const log = (/** @type {string} */ info, /** @type {string | undefined} */ event) => { 174 | console.log(`[${currentDate} ${address}:${portWithRandomLog}] ${info}`, event || ''); 175 | }; 176 | const earlyDataHeader = request.headers.get('sec-websocket-protocol') || ''; 177 | 178 | const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log); 179 | 180 | /** @type {{ value: import("@cloudflare/workers-types").Socket | null}}*/ 181 | let remoteSocketWapper = { 182 | value: null, 183 | }; 184 | let udpStreamWrite = null; 185 | let isDns = false; 186 | 187 | // ws --> remote 188 | readableWebSocketStream.pipeTo(new WritableStream({ 189 | async write(chunk, controller) { 190 | if (isDns && udpStreamWrite) { 191 | return udpStreamWrite(chunk); 192 | } 193 | if (remoteSocketWapper.value) { 194 | const writer = remoteSocketWapper.value.writable.getWriter() 195 | await writer.write(chunk); 196 | writer.releaseLock(); 197 | return; 198 | } 199 | 200 | const { 201 | hasError, 202 | message, 203 | portRemote = 443, 204 | addressRemote = '', 205 | rawDataIndex, 206 | vlessVersion = new Uint8Array([0, 0]), 207 | isUDP, 208 | } = processVlessHeader(chunk, userID); 209 | address = addressRemote; 210 | portWithRandomLog = `${portRemote} ${isUDP ? 'udp' : 'tcp'} `; 211 | if (hasError) { 212 | // controller.error(message); 213 | throw new Error(message); // cf seems has bug, controller.error will not end stream 214 | // webSocket.close(1000, message); 215 | return; 216 | } 217 | 218 | // If UDP and not DNS port, close it 219 | if (isUDP && portRemote !== 53) { 220 | throw new Error('UDP proxy only enabled for DNS which is port 53'); 221 | // cf seems has bug, controller.error will not end stream 222 | } 223 | 224 | if (isUDP && portRemote === 53) { 225 | isDns = true; 226 | } 227 | 228 | // ["version", "附加信息长度 N"] 229 | const vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]); 230 | const rawClientData = chunk.slice(rawDataIndex); 231 | 232 | // TODO: support udp here when cf runtime has udp support 233 | if (isDns) { 234 | const { write } = await handleUDPOutBound(webSocket, vlessResponseHeader, log); 235 | udpStreamWrite = write; 236 | udpStreamWrite(rawClientData); 237 | return; 238 | } 239 | handleTCPOutBound(remoteSocketWapper, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log); 240 | }, 241 | close() { 242 | log(`readableWebSocketStream is close`); 243 | }, 244 | abort(reason) { 245 | log(`readableWebSocketStream is abort`, JSON.stringify(reason)); 246 | }, 247 | })).catch((err) => { 248 | log('readableWebSocketStream pipeTo error', err); 249 | }); 250 | 251 | return new Response(null, { 252 | status: 101, 253 | webSocket: client, 254 | }); 255 | } 256 | 257 | /** 258 | * Handles outbound TCP connections. 259 | * 260 | * @param {any} remoteSocket 261 | * @param {string} addressRemote The remote address to connect to. 262 | * @param {number} portRemote The remote port to connect to. 263 | * @param {Uint8Array} rawClientData The raw client data to write. 264 | * @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket to pass the remote socket to. 265 | * @param {Uint8Array} vlessResponseHeader The VLESS response header. 266 | * @param {function} log The logging function. 267 | * @returns {Promise} The remote socket. 268 | */ 269 | async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log,) { 270 | 271 | /** 272 | * Connects to a given address and port and writes data to the socket. 273 | * @param {string} address The address to connect to. 274 | * @param {number} port The port to connect to. 275 | * @returns {Promise} A Promise that resolves to the connected socket. 276 | */ 277 | async function connectAndWrite(address, port) { 278 | /** @type {import("@cloudflare/workers-types").Socket} */ 279 | const tcpSocket = connect({ 280 | hostname: address, 281 | port: port, 282 | }); 283 | remoteSocket.value = tcpSocket; 284 | log(`connected to ${address}:${port}`); 285 | const writer = tcpSocket.writable.getWriter(); 286 | await writer.write(rawClientData); // first write, nomal is tls client hello 287 | writer.releaseLock(); 288 | return tcpSocket; 289 | } 290 | 291 | /** 292 | * Retries connecting to the remote address and port if the Cloudflare socket has no incoming data. 293 | * @returns {Promise} A Promise that resolves when the retry is complete. 294 | */ 295 | async function retry() { 296 | const tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote) 297 | tcpSocket.closed.catch(error => { 298 | console.log('retry tcpSocket closed error', error); 299 | }).finally(() => { 300 | safeCloseWebSocket(webSocket); 301 | }) 302 | remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, null, log); 303 | } 304 | 305 | const tcpSocket = await connectAndWrite(addressRemote, portRemote); 306 | 307 | // when remoteSocket is ready, pass to websocket 308 | // remote--> ws 309 | remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, retry, log); 310 | } 311 | 312 | /** 313 | * Creates a readable stream from a WebSocket server, allowing for data to be read from the WebSocket. 314 | * @param {import("@cloudflare/workers-types").WebSocket} webSocketServer The WebSocket server to create the readable stream from. 315 | * @param {string} earlyDataHeader The header containing early data for WebSocket 0-RTT. 316 | * @param {(info: string)=> void} log The logging function. 317 | * @returns {ReadableStream} A readable stream that can be used to read data from the WebSocket. 318 | */ 319 | function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) { 320 | let readableStreamCancel = false; 321 | const stream = new ReadableStream({ 322 | start(controller) { 323 | webSocketServer.addEventListener('message', (event) => { 324 | const message = event.data; 325 | controller.enqueue(message); 326 | }); 327 | 328 | webSocketServer.addEventListener('close', () => { 329 | safeCloseWebSocket(webSocketServer); 330 | controller.close(); 331 | }); 332 | 333 | webSocketServer.addEventListener('error', (err) => { 334 | log('webSocketServer has error'); 335 | controller.error(err); 336 | }); 337 | const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader); 338 | if (error) { 339 | controller.error(error); 340 | } else if (earlyData) { 341 | controller.enqueue(earlyData); 342 | } 343 | }, 344 | 345 | pull(controller) { 346 | // if ws can stop read if stream is full, we can implement backpressure 347 | // https://streams.spec.whatwg.org/#example-rs-push-backpressure 348 | }, 349 | 350 | cancel(reason) { 351 | log(`ReadableStream was canceled, due to ${reason}`) 352 | readableStreamCancel = true; 353 | safeCloseWebSocket(webSocketServer); 354 | } 355 | }); 356 | 357 | return stream; 358 | } 359 | 360 | // https://xtls.github.io/development/protocols/vless.html 361 | // https://github.com/zizifn/excalidraw-backup/blob/main/v2ray-protocol.excalidraw 362 | 363 | /** 364 | * Processes the VLESS header buffer and returns an object with the relevant information. 365 | * @param {ArrayBuffer} vlessBuffer The VLESS header buffer to process. 366 | * @param {string} userID The user ID to validate against the UUID in the VLESS header. 367 | * @returns {{ 368 | * hasError: boolean, 369 | * message?: string, 370 | * addressRemote?: string, 371 | * addressType?: number, 372 | * portRemote?: number, 373 | * rawDataIndex?: number, 374 | * vlessVersion?: Uint8Array, 375 | * isUDP?: boolean 376 | * }} An object with the relevant information extracted from the VLESS header buffer. 377 | */ 378 | function processVlessHeader(vlessBuffer, userID) { 379 | if (vlessBuffer.byteLength < 24) { 380 | return { 381 | hasError: true, 382 | message: 'invalid data', 383 | }; 384 | } 385 | 386 | const version = new Uint8Array(vlessBuffer.slice(0, 1)); 387 | let isValidUser = false; 388 | let isUDP = false; 389 | const slicedBuffer = new Uint8Array(vlessBuffer.slice(1, 17)); 390 | const slicedBufferString = stringify(slicedBuffer); 391 | // check if userID is valid uuid or uuids split by , and contains userID in it otherwise return error message to console 392 | const uuids = userID.includes(',') ? userID.split(",") : [userID]; 393 | // uuid_validator(hostName, slicedBufferString); 394 | 395 | 396 | // isValidUser = uuids.some(userUuid => slicedBufferString === userUuid.trim()); 397 | isValidUser = uuids.some(userUuid => slicedBufferString === userUuid.trim()) || uuids.length === 1 && slicedBufferString === uuids[0].trim(); 398 | 399 | console.log(`userID: ${slicedBufferString}`); 400 | 401 | if (!isValidUser) { 402 | return { 403 | hasError: true, 404 | message: 'invalid user', 405 | }; 406 | } 407 | 408 | const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0]; 409 | //skip opt for now 410 | 411 | const command = new Uint8Array( 412 | vlessBuffer.slice(18 + optLength, 18 + optLength + 1) 413 | )[0]; 414 | 415 | // 0x01 TCP 416 | // 0x02 UDP 417 | // 0x03 MUX 418 | if (command === 1) { 419 | isUDP = false; 420 | } else if (command === 2) { 421 | isUDP = true; 422 | } else { 423 | return { 424 | hasError: true, 425 | message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`, 426 | }; 427 | } 428 | const portIndex = 18 + optLength + 1; 429 | const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2); 430 | // port is big-Endian in raw data etc 80 == 0x005d 431 | const portRemote = new DataView(portBuffer).getUint16(0); 432 | 433 | let addressIndex = portIndex + 2; 434 | const addressBuffer = new Uint8Array( 435 | vlessBuffer.slice(addressIndex, addressIndex + 1) 436 | ); 437 | 438 | // 1--> ipv4 addressLength =4 439 | // 2--> domain name addressLength=addressBuffer[1] 440 | // 3--> ipv6 addressLength =16 441 | const addressType = addressBuffer[0]; 442 | let addressLength = 0; 443 | let addressValueIndex = addressIndex + 1; 444 | let addressValue = ''; 445 | switch (addressType) { 446 | case 1: 447 | addressLength = 4; 448 | addressValue = new Uint8Array( 449 | vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) 450 | ).join('.'); 451 | break; 452 | case 2: 453 | addressLength = new Uint8Array( 454 | vlessBuffer.slice(addressValueIndex, addressValueIndex + 1) 455 | )[0]; 456 | addressValueIndex += 1; 457 | addressValue = new TextDecoder().decode( 458 | vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) 459 | ); 460 | break; 461 | case 3: 462 | addressLength = 16; 463 | const dataView = new DataView( 464 | vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength) 465 | ); 466 | // 2001:0db8:85a3:0000:0000:8a2e:0370:7334 467 | const ipv6 = []; 468 | for (let i = 0; i < 8; i++) { 469 | ipv6.push(dataView.getUint16(i * 2).toString(16)); 470 | } 471 | addressValue = ipv6.join(':'); 472 | // seems no need add [] for ipv6 473 | break; 474 | default: 475 | return { 476 | hasError: true, 477 | message: `invild addressType is ${addressType}`, 478 | }; 479 | } 480 | if (!addressValue) { 481 | return { 482 | hasError: true, 483 | message: `addressValue is empty, addressType is ${addressType}`, 484 | }; 485 | } 486 | 487 | return { 488 | hasError: false, 489 | addressRemote: addressValue, 490 | addressType, 491 | portRemote, 492 | rawDataIndex: addressValueIndex + addressLength, 493 | vlessVersion: version, 494 | isUDP, 495 | }; 496 | } 497 | 498 | 499 | /** 500 | * Converts a remote socket to a WebSocket connection. 501 | * @param {import("@cloudflare/workers-types").Socket} remoteSocket The remote socket to convert. 502 | * @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket to connect to. 503 | * @param {ArrayBuffer | null} vlessResponseHeader The VLESS response header. 504 | * @param {(() => Promise) | null} retry The function to retry the connection if it fails. 505 | * @param {(info: string) => void} log The logging function. 506 | * @returns {Promise} A Promise that resolves when the conversion is complete. 507 | */ 508 | async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, retry, log) { 509 | // remote--> ws 510 | let remoteChunkCount = 0; 511 | let chunks = []; 512 | /** @type {ArrayBuffer | null} */ 513 | let vlessHeader = vlessResponseHeader; 514 | let hasIncomingData = false; // check if remoteSocket has incoming data 515 | await remoteSocket.readable 516 | .pipeTo( 517 | new WritableStream({ 518 | start() { 519 | }, 520 | /** 521 | * 522 | * @param {Uint8Array} chunk 523 | * @param {*} controller 524 | */ 525 | async write(chunk, controller) { 526 | hasIncomingData = true; 527 | remoteChunkCount++; 528 | if (webSocket.readyState !== WS_READY_STATE_OPEN) { 529 | controller.error( 530 | 'webSocket.readyState is not open, maybe close' 531 | ); 532 | } 533 | if (vlessHeader) { 534 | webSocket.send(await new Blob([vlessHeader, chunk]).arrayBuffer()); 535 | vlessHeader = null; 536 | } else { 537 | // console.log(`remoteSocketToWS send chunk ${chunk.byteLength}`); 538 | // seems no need rate limit this, CF seems fix this??.. 539 | // if (remoteChunkCount > 20000) { 540 | // // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M 541 | // await delay(1); 542 | // } 543 | webSocket.send(chunk); 544 | } 545 | }, 546 | close() { 547 | log(`remoteConnection!.readable is close with hasIncomingData is ${hasIncomingData}`); 548 | // 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. 549 | }, 550 | abort(reason) { 551 | console.error(`remoteConnection!.readable abort`, reason); 552 | }, 553 | }) 554 | ) 555 | .catch((error) => { 556 | console.error( 557 | `remoteSocketToWS has exception `, 558 | error.stack || error 559 | ); 560 | safeCloseWebSocket(webSocket); 561 | }); 562 | 563 | // seems is cf connect socket have error, 564 | // 1. Socket.closed will have error 565 | // 2. Socket.readable will be close without any data coming 566 | if (hasIncomingData === false && retry) { 567 | log(`retry`) 568 | retry(); 569 | } 570 | } 571 | 572 | /** 573 | * Decodes a base64 string into an ArrayBuffer. 574 | * @param {string} base64Str The base64 string to decode. 575 | * @returns {{earlyData: ArrayBuffer|null, error: Error|null}} An object containing the decoded ArrayBuffer or null if there was an error, and any error that occurred during decoding or null if there was no error. 576 | */ 577 | function base64ToArrayBuffer(base64Str) { 578 | if (!base64Str) { 579 | return { earlyData: null, error: null }; 580 | } 581 | try { 582 | // go use modified Base64 for URL rfc4648 which js atob not support 583 | base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/'); 584 | const decode = atob(base64Str); 585 | const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0)); 586 | return { earlyData: arryBuffer.buffer, error: null }; 587 | } catch (error) { 588 | return { earlyData: null, error }; 589 | } 590 | } 591 | 592 | /** 593 | * Checks if a given string is a valid UUID. 594 | * Note: This is not a real UUID validation. 595 | * @param {string} uuid The string to validate as a UUID. 596 | * @returns {boolean} True if the string is a valid UUID, false otherwise. 597 | */ 598 | function isValidUUID(uuid) { 599 | 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; 600 | return uuidRegex.test(uuid); 601 | } 602 | 603 | const WS_READY_STATE_OPEN = 1; 604 | const WS_READY_STATE_CLOSING = 2; 605 | /** 606 | * Closes a WebSocket connection safely without throwing exceptions. 607 | * @param {import("@cloudflare/workers-types").WebSocket} socket The WebSocket connection to close. 608 | */ 609 | function safeCloseWebSocket(socket) { 610 | try { 611 | if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) { 612 | socket.close(); 613 | } 614 | } catch (error) { 615 | console.error('safeCloseWebSocket error', error); 616 | } 617 | } 618 | 619 | const byteToHex = []; 620 | 621 | for (let i = 0; i < 256; ++i) { 622 | byteToHex.push((i + 256).toString(16).slice(1)); 623 | } 624 | 625 | function unsafeStringify(arr, offset = 0) { 626 | 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(); 627 | } 628 | 629 | function stringify(arr, offset = 0) { 630 | const uuid = unsafeStringify(arr, offset); 631 | if (!isValidUUID(uuid)) { 632 | throw TypeError("Stringified UUID is invalid"); 633 | } 634 | return uuid; 635 | } 636 | 637 | 638 | /** 639 | * Handles outbound UDP traffic by transforming the data into DNS queries and sending them over a WebSocket connection. 640 | * @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket connection to send the DNS queries over. 641 | * @param {ArrayBuffer} vlessResponseHeader The VLESS response header. 642 | * @param {(string) => void} log The logging function. 643 | * @returns {{write: (chunk: Uint8Array) => void}} An object with a write method that accepts a Uint8Array chunk to write to the transform stream. 644 | */ 645 | async function handleUDPOutBound(webSocket, vlessResponseHeader, log) { 646 | 647 | let isVlessHeaderSent = false; 648 | const transformStream = new TransformStream({ 649 | start(controller) { 650 | 651 | }, 652 | transform(chunk, controller) { 653 | // udp message 2 byte is the the length of udp data 654 | // TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message 655 | for (let index = 0; index < chunk.byteLength;) { 656 | const lengthBuffer = chunk.slice(index, index + 2); 657 | const udpPakcetLength = new DataView(lengthBuffer).getUint16(0); 658 | const udpData = new Uint8Array( 659 | chunk.slice(index + 2, index + 2 + udpPakcetLength) 660 | ); 661 | index = index + 2 + udpPakcetLength; 662 | controller.enqueue(udpData); 663 | } 664 | }, 665 | flush(controller) { 666 | } 667 | }); 668 | 669 | // only handle dns udp for now 670 | transformStream.readable.pipeTo(new WritableStream({ 671 | async write(chunk) { 672 | const resp = await fetch(dohURL, // dns server url 673 | { 674 | method: 'POST', 675 | headers: { 676 | 'content-type': 'application/dns-message', 677 | }, 678 | body: chunk, 679 | }) 680 | const dnsQueryResult = await resp.arrayBuffer(); 681 | const udpSize = dnsQueryResult.byteLength; 682 | // console.log([...new Uint8Array(dnsQueryResult)].map((x) => x.toString(16))); 683 | const udpSizeBuffer = new Uint8Array([(udpSize >> 8) & 0xff, udpSize & 0xff]); 684 | if (webSocket.readyState === WS_READY_STATE_OPEN) { 685 | log(`doh success and dns message length is ${udpSize}`); 686 | if (isVlessHeaderSent) { 687 | webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer()); 688 | } else { 689 | webSocket.send(await new Blob([vlessResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer()); 690 | isVlessHeaderSent = true; 691 | } 692 | } 693 | } 694 | })).catch((error) => { 695 | log('dns udp has error' + error) 696 | }); 697 | 698 | const writer = transformStream.writable.getWriter(); 699 | 700 | return { 701 | /** 702 | * 703 | * @param {Uint8Array} chunk 704 | */ 705 | write(chunk) { 706 | writer.write(chunk); 707 | } 708 | }; 709 | } 710 | 711 | /** 712 | * 713 | * @param {string} userID - single or comma separated userIDs 714 | * @param {string | null} hostName 715 | * @returns {string} 716 | */ 717 | function getVLESSConfig(userIDs, hostName) { 718 | const commonUrlPart = `:443?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2048#${hostName}`; 719 | const separator = "---------------------------------------------------------------"; 720 | const hashSeparator = "################################################################"; 721 | 722 | // Split the userIDs into an array 723 | let userIDArray = userIDs.split(','); 724 | 725 | // Prepare output array 726 | let output = []; 727 | let header = []; 728 | const clash_link = `https://subconverter.do.xn--b6gac.eu.org/sub?target=clash&url=https://${hostName}/sub/${userIDArray[0]}?format=clash&insert=false&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; 729 | header.push(`\n

图片描述`); 730 | header.push(`\nWelcome! This function generates configuration for VLESS protocol. If you found this useful, please check our GitHub project for more:\n`); 731 | header.push(`欢迎!这是生成 VLESS 协议的配置。如果您发现这个项目很好用,请查看我们的 GitHub 项目给我一个star:\n`); 732 | header.push(`\nEDtunnel - https://github.com/3Kmfi6HP/EDtunnel\n`); 733 | header.push(`\n\n\n`.replace(/USERNAME/g, "3Kmfi6HP").replace(/REPOSITORY/g, "EDtunnel")); 734 | header.push(`VLESS 节点订阅连接\nClash 节点订阅连接\nClash 节点订阅连接2

\n`); 735 | header.push(``); 736 | 737 | // Generate output string for each userID 738 | userIDArray.forEach((userID) => { 739 | const vlessMain = `vless://${userID}@${hostName}${commonUrlPart}`; 740 | const vlessSec = `vless://${userID}@${proxyIP}${commonUrlPart}`; 741 | output.push(`UUID: ${userID}`); 742 | output.push(`${hashSeparator}\nv2ray default ip\n${separator}\n${vlessMain}\n${separator}`); 743 | output.push(`${hashSeparator}\nv2ray with best ip\n${separator}\n${vlessSec}\n${separator}`); 744 | }); 745 | output.push(`${hashSeparator}\n# Clash Proxy Provider 配置格式(configuration format)\nproxy-groups:\n - name: UseProvider\n type: select\n use:\n - provider1\n proxies:\n - Proxy\n - DIRECT\nproxy-providers:\n provider1:\n type: http\n url: https://${hostName}/sub/${userIDArray[0]}?format=clash\n interval: 3600\n path: ./provider1.yaml\n health-check:\n enable: true\n interval: 600\n # lazy: true\n url: http://www.gstatic.com/generate_204\n\n${hashSeparator}`); 746 | 747 | // HTML Head with CSS 748 | const htmlHead = ` 749 | 750 | EDtunnel: VLESS configuration 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 810 | 811 | `; 812 | 813 | // Join output with newlines, wrap inside and 814 | return ` 815 | 816 | ${htmlHead} 817 | 818 |
${header.join('')}
${output.join('\n')}
822 | 823 | `; 824 | } 825 | 826 | 827 | function createVLESSSub(userID_Path, hostName) { 828 | let portArray_http = [80, 8080, 8880, 2052, 2086, 2095, 2082]; 829 | let portArray_https = [443, 8443, 2053, 2096, 2087, 2083]; 830 | 831 | // Split the userIDs into an array 832 | let userIDArray = userID_Path.includes(',') ? userID_Path.split(',') : [userID_Path]; 833 | 834 | // Prepare output array 835 | let output = []; 836 | 837 | // Generate output string for each userID 838 | userIDArray.forEach((userID) => { 839 | // Check if the hostName is a Cloudflare Pages domain, if not, generate HTTP configurations 840 | // reasons: pages.dev not support http only https 841 | if (!hostName.includes('pages.dev')) { 842 | // Iterate over all ports for http 843 | portArray_http.forEach((port) => { 844 | const commonUrlPart_http = `:${port}?encryption=none&security=none&fp=random&type=ws&host=${hostName}&path=%2F%3Fed%3D2048#${hostName}-HTTP-${port}`; 845 | const vlessMainHttp = `vless://${userID}@${hostName}${commonUrlPart_http}`; 846 | 847 | // For each proxy IP, generate a VLESS configuration and add to output 848 | proxyIPs.forEach((proxyIP) => { 849 | const vlessSecHttp = `vless://${userID}@${proxyIP}${commonUrlPart_http}-${proxyIP}-EDtunnel`; 850 | output.push(`${vlessMainHttp}`); 851 | output.push(`${vlessSecHttp}`); 852 | }); 853 | }); 854 | } 855 | // Iterate over all ports for https 856 | portArray_https.forEach((port) => { 857 | const commonUrlPart_https = `:${port}?encryption=none&security=tls&sni=${hostName}&fp=random&type=ws&host=${hostName}&path=%2F%3Fed%3D2048#${hostName}-HTTPS-${port}`; 858 | const vlessMainHttps = `vless://${userID}@${hostName}${commonUrlPart_https}`; 859 | 860 | // For each proxy IP, generate a VLESS configuration and add to output 861 | proxyIPs.forEach((proxyIP) => { 862 | const vlessSecHttps = `vless://${userID}@${proxyIP}${commonUrlPart_https}-${proxyIP}-EDtunnel`; 863 | output.push(`${vlessMainHttps}`); 864 | output.push(`${vlessSecHttps}`); 865 | }); 866 | }); 867 | }); 868 | 869 | // Join output with newlines 870 | return output.join('\n'); 871 | } 872 | 873 | -------------------------------------------------------------------------------- /ytdl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if the operating system is Windows 4 | if [ "$OSTYPE" == "msys" ]; then 5 | # Windows OS detected 6 | python_cmd="python" 7 | else 8 | # Assume non-Windows (Linux/Mac) OS 9 | python_cmd="python3" 10 | fi 11 | 12 | # Check if Python is installed 13 | if ! command -v $python_cmd &>/dev/null; then 14 | echo "$python_cmd is not installed. Installing $python_cmd..." 15 | # Install Python based on the detected command (python or python3) 16 | if [ "$OSTYPE" == "msys" ]; then 17 | # Windows OS 18 | choco install python -y 19 | else 20 | # Linux/Mac OS 21 | sudo apt-get update 22 | sudo apt-get install $python_cmd -y 23 | fi 24 | else 25 | echo "$python_cmd is already installed." 26 | fi 27 | 28 | # Install pytube Python package 29 | echo "Installing pytube..." 30 | $python_cmd -m pip install pytube 31 | 32 | # Clear the terminal based on the OS 33 | if [ "$OSTYPE" == "msys" ]; then 34 | # Windows OS 35 | echo "Clearing the terminal (Windows)..." 36 | cls 37 | else 38 | # Linux/Mac OS 39 | echo "Clearing the terminal (Linux/Mac)..." 40 | clear 41 | fi 42 | 43 | # Install bot.py from the external link 44 | echo "Downloading bot.py..." 45 | curl -O https://raw.githubusercontent.com/Ptechgithub/configs/main/bot.py 46 | 47 | # Run the bot.py script 48 | echo "Running bot.py with $python_cmd..." 49 | $python_cmd bot.py --------------------------------------------------------------------------------