Add all project files, configs, scripts and results
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
525
test_all_configs.sh
Executable file
525
test_all_configs.sh
Executable file
@@ -0,0 +1,525 @@
|
||||
#!/usr/bin/env bash
|
||||
# test_all_configs.sh — Sequential test of 4 xray configurations on port 443
|
||||
# For each config: swap remote inbound, test locally, restore, next.
|
||||
#
|
||||
# Configs:
|
||||
# A: VLESS + TCP + Reality + Vision (baseline)
|
||||
# B: VLESS + XHTTP + Reality (split uploads, anti-freeze)
|
||||
# C: VLESS + gRPC + Reality (H2 enterprise traffic)
|
||||
# D: VLESS + TCP + Reality + Vision + Fragment+Noise (TLS handshake obfuscation)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
XRAY_BIN="/usr/local/x-ui/bin/xray-linux-amd64"
|
||||
SOCKS_PORT=11082
|
||||
REMOTE_IP="83.99.190.32"
|
||||
RESULTS_FILE="/home/alvis/ai-xray/config_test_results.md"
|
||||
VENV="/home/alvis/ai-xray/venv"
|
||||
|
||||
# Shared keys
|
||||
PUBLIC_KEY="58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw"
|
||||
PRIVATE_KEY="KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY"
|
||||
DEST="www.delfi.lv:443"
|
||||
SERVER_NAMES='["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"]'
|
||||
|
||||
# Config A
|
||||
UUID_A="64522a14-54aa-4b3c-8071-8c8b17aa1f08"
|
||||
SID_A="48b4c16249ad44ff"
|
||||
|
||||
# Config B (XHTTP)
|
||||
UUID_B="6e422ab5-070a-43f6-8241-38cd56d23d24"
|
||||
SID_B="6036d37d12c443c4"
|
||||
XHTTP_PATH="/xt-6036d37d"
|
||||
|
||||
# Config C (gRPC)
|
||||
UUID_C="d0dd1e83-43d8-4bf8-a2b0-005362076b7b"
|
||||
SID_C="52dfa6856de91d0f"
|
||||
GRPC_SVC="grpc-52dfa685"
|
||||
|
||||
# Config D (Fragment) — uses Config A server-side
|
||||
UUID_D="fdc4fbc1-d3c0-43e9-917f-4026ba6d4f7c"
|
||||
SID_D="90abc7d195f7341d"
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
|
||||
header() { echo ""; echo -e "${BOLD}${CYAN}══════════════════════════════════════════${NC}"; echo -e "${BOLD}${CYAN} $1${NC}"; echo -e "${BOLD}${CYAN}══════════════════════════════════════════${NC}"; }
|
||||
pass() { echo -e " ${GREEN}✓${NC} $1"; }
|
||||
fail() { echo -e " ${RED}✗${NC} $1"; }
|
||||
info() { echo -e " ${YELLOW}→${NC} $1"; }
|
||||
|
||||
XRAY_PID=""
|
||||
cleanup_xray() {
|
||||
if [[ -n "$XRAY_PID" ]]; then
|
||||
kill "$XRAY_PID" 2>/dev/null || true
|
||||
wait "$XRAY_PID" 2>/dev/null || true
|
||||
XRAY_PID=""
|
||||
fi
|
||||
}
|
||||
trap 'cleanup_xray; rm -f /tmp/xray-test-cfg.json' EXIT
|
||||
|
||||
# ── Remote inbound management ─────────────────────────────────────────────
|
||||
remote_update_inbound() {
|
||||
# $1 = inbound JSON string (the streamSettings portion as Python dict repr)
|
||||
local stream_json="$1"
|
||||
local uuid="$2"
|
||||
local flow="$3"
|
||||
local sid="$4"
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
|
||||
stream = $stream_json
|
||||
|
||||
client = {"id": "$uuid", "flow": "$flow", "email": "test-client",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0,
|
||||
"enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
|
||||
payload = {
|
||||
"id": 1,
|
||||
"tag": "inbound-443",
|
||||
"enable": True,
|
||||
"port": 443,
|
||||
"listen": "",
|
||||
"protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}),
|
||||
"remark": "inbound-443",
|
||||
"expiryTime": 0
|
||||
}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
print(r.json().get("success"), r.json().get("msg",""))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
restore_baseline() {
|
||||
info "Restoring baseline (TCP+Vision) on remote..."
|
||||
remote_update_inbound '{
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False,
|
||||
"dest": "www.delfi.lv:443",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "'"$PRIVATE_KEY"'",
|
||||
"shortIds": ["'"$SID_A"'", ""]
|
||||
},
|
||||
"tcpSettings": {"header": {"type": "none"}}
|
||||
}' "$UUID_A" "xtls-rprx-vision" "$SID_A"
|
||||
}
|
||||
|
||||
# ── Local standalone test config writers ──────────────────────────────────
|
||||
write_cfg_A() { cat > /tmp/xray-test-cfg.json << EOF
|
||||
{
|
||||
"log": {"loglevel": "error"},
|
||||
"inbounds": [{"listen":"127.0.0.1","port":$SOCKS_PORT,"protocol":"socks","settings":{"auth":"noauth","udp":true}}],
|
||||
"outbounds": [
|
||||
{"tag":"proxy","protocol":"vless",
|
||||
"settings":{"vnext":[{"address":"share.alogins.net","port":443,"users":[{"id":"$UUID_A","flow":"xtls-rprx-vision","encryption":"none"}]}]},
|
||||
"streamSettings":{
|
||||
"network":"tcp","security":"reality",
|
||||
"realitySettings":{"fingerprint":"chrome","serverName":"www.delfi.lv","publicKey":"$PUBLIC_KEY","shortId":"$SID_A","spiderX":"/"},
|
||||
"tcpSettings":{"header":{"type":"none"}}
|
||||
}
|
||||
},
|
||||
{"tag":"direct","protocol":"freedom"}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
write_cfg_B() { cat > /tmp/xray-test-cfg.json << EOF
|
||||
{
|
||||
"log": {"loglevel": "error"},
|
||||
"inbounds": [{"listen":"127.0.0.1","port":$SOCKS_PORT,"protocol":"socks","settings":{"auth":"noauth","udp":true}}],
|
||||
"outbounds": [
|
||||
{"tag":"proxy","protocol":"vless",
|
||||
"settings":{"vnext":[{"address":"share.alogins.net","port":443,"users":[{"id":"$UUID_B","flow":"","encryption":"none"}]}]},
|
||||
"streamSettings":{
|
||||
"network":"xhttp","security":"reality",
|
||||
"realitySettings":{"fingerprint":"chrome","serverName":"www.delfi.lv","publicKey":"$PUBLIC_KEY","shortId":"$SID_B","spiderX":"/"},
|
||||
"xhttpSettings":{"path":"$XHTTP_PATH","host":"","mode":"auto",
|
||||
"extra":{"xPaddingBytes":"100-1000","xmux":{"maxConcurrency":"16-32","maxConnections":0,"cMaxReuseTimes":"64-128","cMaxLifetimeMs":0,"hMaxRequestTimes":"600-900","hMaxReusableSecs":"1800-3000"}}}
|
||||
}
|
||||
},
|
||||
{"tag":"direct","protocol":"freedom"}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
write_cfg_C() { cat > /tmp/xray-test-cfg.json << EOF
|
||||
{
|
||||
"log": {"loglevel": "error"},
|
||||
"inbounds": [{"listen":"127.0.0.1","port":$SOCKS_PORT,"protocol":"socks","settings":{"auth":"noauth","udp":true}}],
|
||||
"outbounds": [
|
||||
{"tag":"proxy","protocol":"vless",
|
||||
"settings":{"vnext":[{"address":"share.alogins.net","port":443,"users":[{"id":"$UUID_C","flow":"","encryption":"none"}]}]},
|
||||
"streamSettings":{
|
||||
"network":"grpc","security":"reality",
|
||||
"realitySettings":{"fingerprint":"chrome","serverName":"www.delfi.lv","publicKey":"$PUBLIC_KEY","shortId":"$SID_C","spiderX":"/"},
|
||||
"grpcSettings":{"serviceName":"$GRPC_SVC","multiMode":true,"idle_timeout":60,"health_check_timeout":20,"initial_windows_size":65536}
|
||||
}
|
||||
},
|
||||
{"tag":"direct","protocol":"freedom"}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
write_cfg_D() { cat > /tmp/xray-test-cfg.json << EOF
|
||||
{
|
||||
"log": {"loglevel": "error"},
|
||||
"inbounds": [{"listen":"127.0.0.1","port":$SOCKS_PORT,"protocol":"socks","settings":{"auth":"noauth","udp":true}}],
|
||||
"outbounds": [
|
||||
{"tag":"proxy","protocol":"vless",
|
||||
"settings":{"vnext":[{"address":"share.alogins.net","port":443,"users":[{"id":"$UUID_D","flow":"xtls-rprx-vision","encryption":"none"}]}]},
|
||||
"streamSettings":{
|
||||
"network":"tcp","security":"reality",
|
||||
"realitySettings":{"fingerprint":"chrome","serverName":"www.delfi.lv","publicKey":"$PUBLIC_KEY","shortId":"$SID_D","spiderX":"/"},
|
||||
"tcpSettings":{"header":{"type":"none"}},
|
||||
"sockopt":{"dialerProxy":"frag-chain1"}
|
||||
}
|
||||
},
|
||||
{"tag":"frag-chain1","protocol":"freedom",
|
||||
"settings":{"fragment":{"packets":"tlshello","length":"100-200","interval":"10-20"}},
|
||||
"streamSettings":{"sockopt":{"dialerProxy":"frag-chain2"}}
|
||||
},
|
||||
{"tag":"frag-chain2","protocol":"freedom",
|
||||
"settings":{
|
||||
"fragment":{"packets":"1-3","length":"1-5","interval":"1-2"},
|
||||
"noises":[
|
||||
{"type":"rand","packet":"50-150","delay":"10-16"},
|
||||
{"type":"base64","packet":"7nQBAAABAAAAAAAABnQtcmluZwZtc2VkZ2UDbmV0AAABAAE=","delay":"10-16"}
|
||||
]
|
||||
}
|
||||
},
|
||||
{"tag":"direct","protocol":"freedom"}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
# ── Core test runner ──────────────────────────────────────────────────────
|
||||
run_test() {
|
||||
local label="$1"
|
||||
local write_fn="$2" # function name to write the config
|
||||
local update_fn="$3" # function name to update remote (or empty)
|
||||
|
||||
header "$label"
|
||||
|
||||
# Update remote if needed
|
||||
if [[ -n "$update_fn" ]]; then
|
||||
info "Updating remote inbound..."
|
||||
$update_fn
|
||||
sleep 3 # give xray time to pick up the change
|
||||
fi
|
||||
|
||||
# Write local test config
|
||||
$write_fn
|
||||
|
||||
# Validate
|
||||
if ! "$XRAY_BIN" -test -c /tmp/xray-test-cfg.json &>/dev/null; then
|
||||
fail "Config validation FAILED"
|
||||
echo "$label|INVALID|—|—|—|—|—|—" >> /tmp/results.tsv
|
||||
return
|
||||
fi
|
||||
pass "Config valid"
|
||||
|
||||
# Start test xray
|
||||
cleanup_xray
|
||||
"$XRAY_BIN" -c /tmp/xray-test-cfg.json >/tmp/xray-test.log 2>&1 &
|
||||
XRAY_PID=$!
|
||||
sleep 2
|
||||
|
||||
if ! kill -0 "$XRAY_PID" 2>/dev/null; then
|
||||
fail "Xray failed to start: $(tail -3 /tmp/xray-test.log)"
|
||||
echo "$label|FAIL-START|—|—|—|—|—|—" >> /tmp/results.tsv
|
||||
return
|
||||
fi
|
||||
pass "Xray started (PID $XRAY_PID)"
|
||||
|
||||
# Connectivity
|
||||
info "Checking connectivity..."
|
||||
local exit_ip
|
||||
exit_ip=$(curl -s --socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 15 https://api.ipify.org 2>/dev/null || echo "FAIL")
|
||||
if [[ "$exit_ip" != "$REMOTE_IP" ]]; then
|
||||
fail "Exit IP '$exit_ip' (expected $REMOTE_IP)"
|
||||
cleanup_xray
|
||||
echo "$label|FAIL-CONNECT|—|—|—|—|—|—" >> /tmp/results.tsv
|
||||
return
|
||||
fi
|
||||
pass "Exit IP: $exit_ip"
|
||||
|
||||
# Latency — 10 samples
|
||||
info "Measuring latency (10 samples)..."
|
||||
local latencies=()
|
||||
for i in $(seq 1 10); do
|
||||
local ms
|
||||
ms=$(curl -s -o /dev/null -w "%{time_total}" --socks5-hostname 127.0.0.1:$SOCKS_PORT \
|
||||
--max-time 10 https://www.google.com 2>/dev/null | awk '{printf "%d", $1*1000}')
|
||||
if [[ -n "$ms" && "$ms" -gt 0 ]]; then
|
||||
latencies+=("$ms")
|
||||
printf " [%2d/10] %s ms\n" "$i" "$ms"
|
||||
else
|
||||
printf " [%2d/10] TIMEOUT\n" "$i"
|
||||
fi
|
||||
done
|
||||
|
||||
local n=${#latencies[@]} avg_ms=0 min_ms=0 max_ms=0 p95_ms=0
|
||||
if [[ $n -gt 0 ]]; then
|
||||
local sorted=($(printf '%s\n' "${latencies[@]}" | sort -n))
|
||||
min_ms=${sorted[0]}; max_ms=${sorted[-1]}
|
||||
local sum=0; for v in "${latencies[@]}"; do sum=$((sum+v)); done
|
||||
avg_ms=$((sum/n))
|
||||
local p95_idx=$(( n * 95 / 100 )); [[ $p95_idx -ge $n ]] && p95_idx=$((n-1))
|
||||
p95_ms=${sorted[$p95_idx]}
|
||||
fi
|
||||
pass "Latency ($n/10): min=${min_ms}ms avg=${avg_ms}ms p95=${p95_ms}ms max=${max_ms}ms"
|
||||
|
||||
# Throughput
|
||||
info "Testing throughput..."
|
||||
local dl_mbps=0 ul_mbps=0
|
||||
|
||||
# Download 10MB
|
||||
local dl_out
|
||||
dl_out=$(curl -s -o /dev/null -w "%{size_download} %{time_total}" \
|
||||
--socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 30 \
|
||||
"https://speed.cloudflare.com/__down?bytes=10485760" 2>/dev/null || echo "0 0")
|
||||
local dl_bytes dl_time
|
||||
dl_bytes=$(echo "$dl_out" | awk '{print $1}')
|
||||
dl_time=$(echo "$dl_out" | awk '{print $2}')
|
||||
if [[ "${dl_bytes:-0}" -gt 1000000 ]] 2>/dev/null; then
|
||||
dl_mbps=$(echo "scale=2; $dl_bytes * 8 / $dl_time / 1000000" | bc)
|
||||
pass "Download: ${dl_mbps} Mbps (${dl_bytes} bytes in ${dl_time}s)"
|
||||
else
|
||||
fail "Download failed (bytes=${dl_bytes:-0})"
|
||||
fi
|
||||
|
||||
# Upload 5MB
|
||||
local ul_out
|
||||
ul_out=$(dd if=/dev/urandom bs=1M count=5 2>/dev/null | curl -s -o /dev/null -w "%{size_upload} %{time_total}" \
|
||||
--socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 30 \
|
||||
-X POST --data-binary @- https://httpbin.org/post 2>/dev/null || echo "0 0")
|
||||
local ul_bytes ul_time
|
||||
ul_bytes=$(echo "$ul_out" | awk '{print $1}')
|
||||
ul_time=$(echo "$ul_out" | awk '{print $2}')
|
||||
if [[ "${ul_bytes:-0}" -gt 100000 ]] 2>/dev/null; then
|
||||
ul_mbps=$(echo "scale=2; $ul_bytes * 8 / $ul_time / 1000000" | bc)
|
||||
pass "Upload: ${ul_mbps} Mbps (${ul_bytes} bytes in ${ul_time}s)"
|
||||
else
|
||||
fail "Upload failed"
|
||||
ul_mbps=0
|
||||
fi
|
||||
|
||||
echo "$label|OK|$avg_ms|$min_ms|$p95_ms|$max_ms|$dl_mbps|$ul_mbps" >> /tmp/results.tsv
|
||||
cleanup_xray
|
||||
}
|
||||
|
||||
# ── Remote update functions for each config ───────────────────────────────
|
||||
update_remote_B() {
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
stream = {
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False, "dest": "$DEST",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "$PRIVATE_KEY",
|
||||
"shortIds": ["$SID_B", ""]
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "$XHTTP_PATH", "host": "", "mode": "auto",
|
||||
"extra": {"xPaddingBytes": "100-1000", "xmux": {"maxConcurrency": "16-32", "maxConnections": 0,
|
||||
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
|
||||
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}}
|
||||
}
|
||||
}
|
||||
client = {"id": "$UUID_B", "flow": "", "email": "test-b",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0, "enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
payload = {"id": 1, "tag": "inbound-443", "enable": True, "port": 443, "listen": "", "protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}), "remark": "inbound-443", "expiryTime": 0}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
print(" Remote updated (XHTTP):", r.json().get("success"), r.json().get("msg",""))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
update_remote_C() {
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
stream = {
|
||||
"network": "grpc",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False, "dest": "$DEST",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "$PRIVATE_KEY",
|
||||
"shortIds": ["$SID_C", ""]
|
||||
},
|
||||
"grpcSettings": {"serviceName": "$GRPC_SVC", "multiMode": True,
|
||||
"idle_timeout": 60, "health_check_timeout": 20, "initial_windows_size": 65536}
|
||||
}
|
||||
client = {"id": "$UUID_C", "flow": "", "email": "test-c",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0, "enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
payload = {"id": 1, "tag": "inbound-443", "enable": True, "port": 443, "listen": "", "protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}), "remark": "inbound-443", "expiryTime": 0}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
print(" Remote updated (gRPC):", r.json().get("success"), r.json().get("msg",""))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
update_remote_D() {
|
||||
# Config D uses same server as A but adds UUID_D as client
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
stream = {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False, "dest": "$DEST",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "$PRIVATE_KEY",
|
||||
"shortIds": ["$SID_D", ""]
|
||||
},
|
||||
"tcpSettings": {"header": {"type": "none"}}
|
||||
}
|
||||
client = {"id": "$UUID_D", "flow": "xtls-rprx-vision", "email": "test-d",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0, "enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
payload = {"id": 1, "tag": "inbound-443", "enable": True, "port": 443, "listen": "", "protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}), "remark": "inbound-443", "expiryTime": 0}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
print(" Remote updated (TCP+Fragment):", r.json().get("success"), r.json().get("msg",""))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
restore_A() {
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
stream = {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False, "dest": "$DEST",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "$PRIVATE_KEY",
|
||||
"shortIds": ["$SID_A", ""]
|
||||
},
|
||||
"tcpSettings": {"header": {"type": "none"}}
|
||||
}
|
||||
client = {"id": "$UUID_A", "flow": "xtls-rprx-vision", "email": "local-outbound",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0, "enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
payload = {"id": 1, "tag": "inbound-443", "enable": True, "port": 443, "listen": "", "protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}), "remark": "inbound-443", "expiryTime": 0}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
print(" Restored baseline (TCP+Vision):", r.json().get("success"))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
# ── Run all tests ─────────────────────────────────────────────────────────
|
||||
echo "Config|Status|Avg_ms|Min_ms|P95_ms|Max_ms|DL_Mbps|UL_Mbps" > /tmp/results.tsv
|
||||
|
||||
# Ensure we start with baseline on remote
|
||||
info "Ensuring baseline is active on remote..."
|
||||
restore_A
|
||||
|
||||
run_test "A: TCP+Reality+Vision (baseline)" write_cfg_A ""
|
||||
run_test "B: XHTTP+Reality" write_cfg_B update_remote_B
|
||||
restore_A; sleep 2
|
||||
run_test "C: gRPC+Reality" write_cfg_C update_remote_C
|
||||
restore_A; sleep 2
|
||||
run_test "D: TCP+Reality+Vision+Fragment+Noise" write_cfg_D update_remote_D
|
||||
|
||||
# Restore baseline permanently
|
||||
header "Restoring baseline on remote"
|
||||
restore_A
|
||||
pass "Baseline restored"
|
||||
|
||||
# ── Summary ───────────────────────────────────────────────────────────────
|
||||
header "RESULTS SUMMARY"
|
||||
printf "\n%-42s %-12s %-9s %-9s %-9s %-9s\n" "Configuration" "Status" "Avg ms" "DL Mbps" "UL Mbps" "P95 ms"
|
||||
printf "%-42s %-12s %-9s %-9s %-9s %-9s\n" "──────────────────────────────────────────" "──────────" "───────" "───────" "───────" "───────"
|
||||
while IFS='|' read -r name status avg min p95 max dl ul; do
|
||||
[[ "$name" == "Config" ]] && continue
|
||||
if [[ "$status" == "OK" ]]; then
|
||||
printf "${GREEN}%-42s${NC} %-12s %-9s %-9s %-9s %-9s\n" "$name" "$status" "${avg}ms" "$dl" "$ul" "${p95}ms"
|
||||
else
|
||||
printf "${RED}%-42s${NC} %-12s\n" "$name" "$status"
|
||||
fi
|
||||
done < /tmp/results.tsv
|
||||
|
||||
# ── Write markdown ────────────────────────────────────────────────────────
|
||||
{
|
||||
cat << MDEOF
|
||||
# Xray Configuration Comparison — Port 443
|
||||
|
||||
**Date**: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
**Local xray**: 25.10.15 | **Remote xray**: 26.2.6
|
||||
**Remote**: share.alogins.net (83.99.190.32), LXD container "xray"
|
||||
|
||||
## Results
|
||||
|
||||
| Configuration | Status | Avg Latency | P95 Latency | Download | Upload |
|
||||
|---------------|--------|-------------|-------------|----------|--------|
|
||||
MDEOF
|
||||
while IFS='|' read -r name status avg min p95 max dl ul; do
|
||||
[[ "$name" == "Config" ]] && continue
|
||||
if [[ "$status" == "OK" ]]; then
|
||||
echo "| $name | ✓ OK | ${avg}ms | ${p95}ms | ${dl} Mbps | ${ul} Mbps |"
|
||||
else
|
||||
echo "| $name | ✗ $status | — | — | — | — |"
|
||||
fi
|
||||
done < /tmp/results.tsv
|
||||
cat << 'MDEOF'
|
||||
|
||||
## Configuration Descriptions
|
||||
|
||||
| Config | Transport | Port | Flow | DPI Target |
|
||||
|--------|-----------|------|------|------------|
|
||||
| A | TCP + Reality | 443 | xtls-rprx-vision | Baseline — standard Russia anti-DPI |
|
||||
| B | XHTTP + Reality | 443 | none | Volume-based TCP freezing (split uploads, XMUX padding) |
|
||||
| C | gRPC + Reality | 443 | none | H2 pattern analysis (looks like enterprise API traffic) |
|
||||
| D | TCP + Reality + Fragment/Noise | 443 | xtls-rprx-vision | TLS ClientHello DPI signature (fragment chains + noise) |
|
||||
|
||||
## Methodology
|
||||
- Each config tested sequentially on the **same port 443**
|
||||
- Remote inbound swapped on-the-fly via 3x-ui API
|
||||
- 10 latency samples to google.com
|
||||
- 10 MB download from Cloudflare speed test
|
||||
- 5 MB upload to httpbin.org
|
||||
MDEOF
|
||||
} > "$RESULTS_FILE"
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}Results saved: $RESULTS_FILE${NC}"
|
||||
Reference in New Issue
Block a user