Add all project files, configs, scripts and results

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alvis
2026-03-08 07:09:56 +00:00
parent 803823c370
commit c1bcf3d85e
19 changed files with 4917 additions and 0 deletions

459
benchmark_improvements.sh Executable file
View File

@@ -0,0 +1,459 @@
#!/usr/bin/env bash
# benchmark_improvements.sh
# Tests each DPI-resistance improvement independently against baseline.
# Metrics: avg/P95 latency, jitter (std dev), download Mbps, upload Mbps.
set -euo pipefail
XRAY_BIN="/usr/local/x-ui/bin/xray-linux-amd64"
SOCKS_PORT=11083
REMOTE_IP="83.99.190.32"
VENV="/home/alvis/ai-xray/venv"
RESULTS_FILE="/home/alvis/ai-xray/improvement_results.md"
LATENCY_SAMPLES=20
# Current config values
PUBLIC_KEY="58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw"
PRIVATE_KEY="KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY"
UUID_B="6e422ab5-070a-43f6-8241-38cd56d23d24"
SID_B="6036d37d12c443c4"
XHTTP_PATH="/xt-6036d37d"
DEST="www.delfi.lv:443"
SNI="www.delfi.lv"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
hdr() { echo ""; echo -e "${BOLD}${CYAN}══ $1 ══${NC}"; }
pass() { echo -e " ${GREEN}${NC} $1"; }
fail() { echo -e " ${RED}${NC} $1"; }
info() { echo -e " ${YELLOW}${NC} $1"; }
XRAY_PID=""
cleanup() {
if [[ -n "$XRAY_PID" ]]; then
kill "$XRAY_PID" 2>/dev/null || true
wait "$XRAY_PID" 2>/dev/null || true
XRAY_PID=""
fi
}
trap 'cleanup; rm -f /tmp/bench-cfg.json' EXIT
# ── Remote inbound updater ─────────────────────────────────────────────────
remote_update() {
local stream_json="$1"
local uuid="$2"
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": "", "email": "bench",
"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)
ok = r.json().get("success")
print(f" Remote updated: {ok}")
PYEOF
}
restore_remote() {
remote_update '{
"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"'", "48b4c16249ad44ff", ""]
},
"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"}}
}
}' "$UUID_B"
sleep 2
}
# ── Core benchmark runner ──────────────────────────────────────────────────
bench() {
local label="$1"
local cfg_file="$2"
# Validate
if ! "$XRAY_BIN" -test -c "$cfg_file" &>/dev/null; then
fail "Config invalid — skipping"
echo "$label|INVALID|—|—|—|—|—" >> /tmp/bench.tsv
return
fi
# Start xray
cleanup
"$XRAY_BIN" -c "$cfg_file" >/tmp/bench-xray.log 2>&1 &
XRAY_PID=$!
sleep 2
if ! kill -0 "$XRAY_PID" 2>/dev/null; then
fail "Xray failed to start"
echo "$label|FAIL|—|—|—|—|—" >> /tmp/bench.tsv
return
fi
# Connectivity check
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 "No connectivity (exit IP: $exit_ip)"
cleanup
echo "$label|NO-CONN|—|—|—|—|—" >> /tmp/bench.tsv
return
fi
pass "Connected via $exit_ip"
# Latency — N samples
info "Latency ($LATENCY_SAMPLES samples)..."
local lats=()
for i in $(seq 1 $LATENCY_SAMPLES); do
local ms
ms=$(curl -s -o /dev/null -w "%{time_total}" --socks5-hostname 127.0.0.1:$SOCKS_PORT \
--max-time 8 https://www.gstatic.com/generate_204 2>/dev/null \
| awk '{printf "%d", $1*1000}')
if [[ -n "$ms" && "$ms" -gt 0 ]]; then
lats+=("$ms")
fi
done
local n=${#lats[@]} avg=0 p95=0 jitter=0 min=0 max=0
if [[ $n -gt 0 ]]; then
local sorted=($(printf '%s\n' "${lats[@]}" | sort -n))
min=${sorted[0]}; max=${sorted[-1]}
local sum=0; for v in "${lats[@]}"; do sum=$((sum+v)); done
avg=$((sum/n))
local p95i=$((n*95/100)); [[ $p95i -ge $n ]] && p95i=$((n-1))
p95=${sorted[$p95i]}
# Jitter = std dev (via python for float math)
local csv_lats
csv_lats=$(printf '%s,' "${lats[@]}" | sed 's/,$//')
jitter=$(python3 -c "
import math
d=[$csv_lats]
m=sum(d)/len(d)
print(int(math.sqrt(sum((x-m)**2 for x in d)/len(d))))
")
fi
pass "Latency: avg=${avg}ms p95=${p95}ms jitter=${jitter}ms (n=$n)"
# Download 10MB
info "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 1")
local dl_bytes dl_time dl_mbps=0
dl_bytes=$(echo "$dl_out" | awk '{print $1}')
dl_time=$(echo "$dl_out" | awk '{print $2}')
if [[ "${dl_bytes:-0}" -gt 1000000 ]]; then
dl_mbps=$(echo "scale=1; $dl_bytes*8/$dl_time/1000000" | bc)
pass "Download: ${dl_mbps} Mbps"
else
fail "Download failed"
fi
# Upload 5MB
info "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 1")
local ul_bytes ul_time ul_mbps=0
ul_bytes=$(echo "$ul_out" | awk '{print $1}')
ul_time=$(echo "$ul_out" | awk '{print $2}')
if [[ "${ul_bytes:-0}" -gt 100000 ]]; then
ul_mbps=$(echo "scale=1; $ul_bytes*8/$ul_time/1000000" | bc)
pass "Upload: ${ul_mbps} Mbps"
else
fail "Upload failed"
ul_mbps=0
fi
echo "$label|OK|$avg|$p95|$jitter|$dl_mbps|$ul_mbps" >> /tmp/bench.tsv
cleanup
sleep 1
}
# ══════════════════════════════════════════════════════════════════════════
# CONFIGS
# ══════════════════════════════════════════════════════════════════════════
# Baseline config writer helper
write_xhttp_cfg() {
local fp="$1" use_frag="$2" host_hdr="$3" path="$4" sni_val="$5"
local frag_sockopt=""
[[ "$use_frag" == "yes" ]] && frag_sockopt='"sockopt": {"dialerProxy": "frag-chain1"},'
cat > /tmp/bench-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": {
$frag_sockopt
"network": "xhttp",
"security": "reality",
"realitySettings": {
"fingerprint": "$fp",
"serverName": "$sni_val",
"publicKey": "$PUBLIC_KEY",
"shortId": "$SID_B",
"spiderX": "/"
},
"xhttpSettings": {
"path": "$path",
"host": "$host_hdr",
"mode": "auto",
"extra": {
"xPaddingBytes": "100-1000",
"xmux": {"maxConcurrency": "16-32", "maxConnections": 0,
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}
}
}
}
},
{
"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"}}
},
{"tag": "direct", "protocol": "freedom"}
]
}
EOF
}
# ══════════════════════════════════════════════════════════════════════════
# MAIN
# ══════════════════════════════════════════════════════════════════════════
echo "label|status|avg_ms|p95_ms|jitter_ms|dl_mbps|ul_mbps" > /tmp/bench.tsv
# Ensure baseline remote config is active
info "Ensuring baseline remote config..."
restore_remote
# ── 0. BASELINE ────────────────────────────────────────────────────────────
hdr "0. BASELINE (current config)"
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
bench "0-baseline" /tmp/bench-cfg.json
# ── 1. fingerprint=randomized ──────────────────────────────────────────────
hdr "1. fingerprint: randomized"
write_xhttp_cfg "randomized" "no" "" "$XHTTP_PATH" "$SNI"
bench "1-fp-randomized" /tmp/bench-cfg.json
# ── 2. fingerprint=firefox ────────────────────────────────────────────────
hdr "2. fingerprint: firefox"
write_xhttp_cfg "firefox" "no" "" "$XHTTP_PATH" "$SNI"
bench "2-fp-firefox" /tmp/bench-cfg.json
# ── 3. + TLS ClientHello fragment chain ───────────────────────────────────
hdr "3. fragment chain on TLS ClientHello"
write_xhttp_cfg "chrome" "yes" "" "$XHTTP_PATH" "$SNI"
bench "3-fragment-chain" /tmp/bench-cfg.json
# ── 4. + host header = SNI domain ─────────────────────────────────────────
hdr "4. host header = www.delfi.lv"
write_xhttp_cfg "chrome" "no" "www.delfi.lv" "$XHTTP_PATH" "$SNI"
bench "4-host-header" /tmp/bench-cfg.json
# ── 5. realistic XHTTP path + host header (needs server update) ───────────
hdr "5. realistic path /api/v2/stream + host header"
info "Updating remote path to /api/v2/stream ..."
remote_update '{
"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": "/api/v2/stream", "host": "www.delfi.lv",
"mode": "auto",
"extra": {"xPaddingBytes": "100-1000", "xmux": {
"maxConcurrency": "16-32", "maxConnections": 0,
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}}
}
}' "$UUID_B"
sleep 2
write_xhttp_cfg "chrome" "no" "www.delfi.lv" "/api/v2/stream" "$SNI"
bench "5-realistic-path" /tmp/bench-cfg.json
restore_remote
# ── 6. SNI = e-klase.lv (highest throughput in SNI test) ──────────────────
hdr "6. SNI = e-klase.lv (top SNI from previous benchmark)"
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "e-klase.lv"
bench "6-sni-eklase" /tmp/bench-cfg.json
# ── 7. SNI = www.lmt.lv ───────────────────────────────────────────────────
hdr "7. SNI = www.lmt.lv"
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "www.lmt.lv"
bench "7-sni-lmt" /tmp/bench-cfg.json
# ── 8. BBR check + enable on remote ───────────────────────────────────────
hdr "8. BBR congestion control on remote server"
source "$VENV/bin/activate"
BBR_STATUS=$(python3 << 'PYEOF'
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("83.99.190.32", username="juris", password="VitaIeva2A.")
_, out, _ = ssh.exec_command("lxc exec xray -- sysctl net.ipv4.tcp_congestion_control 2>/dev/null")
cc = out.read().decode().strip()
_, out2, _ = ssh.exec_command("lxc exec xray -- sysctl net.core.default_qdisc 2>/dev/null")
qd = out2.read().decode().strip()
print(f"cc={cc} | qd={qd}")
ssh.close()
PYEOF
)
info "Current: $BBR_STATUS"
if echo "$BBR_STATUS" | grep -q "bbr"; then
info "BBR already enabled — testing as-is"
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
bench "8-bbr-already-on" /tmp/bench-cfg.json
else
info "Enabling BBR on remote container..."
python3 << 'PYEOF'
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("83.99.190.32", username="juris", password="VitaIeva2A.")
for cmd in [
"lxc exec xray -- sysctl -w net.core.default_qdisc=fq",
"lxc exec xray -- sysctl -w net.ipv4.tcp_congestion_control=bbr",
"lxc exec xray -- sysctl -w net.core.rmem_max=16777216",
"lxc exec xray -- sysctl -w net.core.wmem_max=16777216",
]:
_, out, err = ssh.exec_command(cmd)
print(f" {cmd.split('--')[1].strip()}: {(out.read()+err.read()).decode().strip()}")
ssh.close()
PYEOF
sleep 1
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
bench "8-bbr-enabled" /tmp/bench-cfg.json
fi
# ── Restore remote to canonical state ─────────────────────────────────────
hdr "Restoring remote to baseline"
restore_remote
pass "Remote restored"
# ══════════════════════════════════════════════════════════════════════════
# SUMMARY
# ══════════════════════════════════════════════════════════════════════════
hdr "RESULTS SUMMARY"
echo ""
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" "Test" "Avg ms" "P95 ms" "Jitter ms" "DL Mbps" "UL Mbps"
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" "────────────────────────────────" "───────" "───────" "─────────" "───────" "───────"
BASELINE_AVG=0; BASELINE_P95=0; BASELINE_JIT=0; BASELINE_DL=0; BASELINE_UL=0
while IFS='|' read -r label status avg p95 jit dl ul; do
[[ "$label" == "label" ]] && continue
if [[ "$status" == "OK" ]]; then
if [[ "$label" == "0-baseline" ]]; then
BASELINE_AVG=$avg; BASELINE_P95=$p95; BASELINE_JIT=$jit
BASELINE_DL=$dl; BASELINE_UL=$ul
printf "${BOLD}%-32s${NC} %-7s %-7s %-9s %-9s %-9s\n" \
"$label" "${avg}ms" "${p95}ms" "${jit}ms" "${dl}" "${ul}"
else
# Delta indicators
local_delta_avg="" local_delta_jit="" local_delta_dl=""
[[ -n "$BASELINE_AVG" && "$BASELINE_AVG" -gt 0 ]] && {
diff=$((avg - BASELINE_AVG))
[[ $diff -lt 0 ]] && local_delta_avg="${GREEN}${diff}${NC}" || local_delta_avg="${RED}+${diff}${NC}"
}
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" \
"$label" "${avg}ms" "${p95}ms" "${jit}ms" "${dl}" "${ul}"
fi
else
printf "${RED}%-32s${NC} %s\n" "$label" "$status"
fi
done < /tmp/bench.tsv
# Write markdown
{
cat << MDEOF
# DPI Resistance Improvement Benchmark
**Date**: $(date '+%Y-%m-%d %H:%M')
**Baseline**: VLESS+XHTTP+Reality, fingerprint=chrome, SNI=www.delfi.lv, path=/xt-6036d37d
**Latency samples per test**: $LATENCY_SAMPLES
**Jitter**: standard deviation of latency samples
## Results
| Test | Avg ms | P95 ms | Jitter ms | DL Mbps | UL Mbps | Notes |
|------|--------|--------|-----------|---------|---------|-------|
MDEOF
while IFS='|' read -r label status avg p95 jit dl ul; do
[[ "$label" == "label" ]] && continue
notes=""
case "$label" in
0-baseline) notes="Current active config" ;;
1-fp-randomized) notes="uTLS fingerprint rotated per connection" ;;
2-fp-firefox) notes="Firefox uTLS profile" ;;
3-fragment-chain) notes="TLS ClientHello split 100-200B + micro-frag 1-5B" ;;
4-host-header) notes="HTTP Host header = www.delfi.lv" ;;
5-realistic-path) notes="Path=/api/v2/stream + Host header" ;;
6-sni-eklase) notes="SNI switched to e-klase.lv" ;;
7-sni-lmt) notes="SNI switched to www.lmt.lv" ;;
8-bbr*) notes="BBR congestion control on remote" ;;
esac
if [[ "$status" == "OK" ]]; then
echo "| $label | ${avg}ms | ${p95}ms | ${jit}ms | ${dl} | ${ul} | $notes |"
else
echo "| $label | — | — | — | — | — | $status |"
fi
done < /tmp/bench.tsv
cat << 'MDEOF'
## What Each Test Changes
- **fingerprint=randomized**: uTLS fingerprint rotated per connection — defeats fingerprint-based blocking
- **fingerprint=firefox**: Firefox uTLS profile instead of Chrome
- **fragment chain**: TLS ClientHello split into 100-200B chunks, then micro-fragmented 1-5B + noise — defeats handshake DPI
- **host header**: Sets HTTP `Host:` header to match SNI — makes request look more legitimate
- **realistic path**: Changes XHTTP path from synthetic to `/api/v2/stream` with matching host header
- **SNI e-klase.lv / lmt.lv**: Alternative SNIs from previous benchmark (dest stays www.delfi.lv)
- **BBR**: Linux BBR congestion control + larger TCP buffers on remote — improves throughput under loss
MDEOF
} > "$RESULTS_FILE"
echo ""
echo -e "${BOLD}Results: $RESULTS_FILE${NC}"