335 lines
11 KiB
Bash
Executable File
335 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# test_sni_configs.sh — Test multiple SNI configurations for juris-reality
|
|
# Runs test_xray_connection.sh for each SNI and collects results
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
XRAY_BIN="/usr/local/x-ui/bin/xray-linux-amd64"
|
|
SOCKS_PORT=11080
|
|
REMOTE_IP="83.99.190.32"
|
|
RESULTS_FILE="/home/alvis/ai-xray/sni_test_results.md"
|
|
CONFIGS_DIR="/home/alvis/ai-xray/configs"
|
|
|
|
mkdir -p "$CONFIGS_DIR"
|
|
|
|
# SNI configurations to test
|
|
declare -A SNIS
|
|
SNIS["www.delfi.lv"]="Latvia news #1"
|
|
SNIS["www.lmt.lv"]="Latvia telecom #1"
|
|
SNIS["www.tele2.lv"]="Latvia telecom #2"
|
|
SNIS["www.lsm.lv"]="Latvia public broadcasting"
|
|
SNIS["www.inbox.lv"]="Latvia webmail"
|
|
SNIS["e-klase.lv"]="Latvia education"
|
|
SNIS["share.alogins.net"]="Custom domain"
|
|
SNIS["www.microsoft.com"]="Worldwide baseline"
|
|
|
|
# Ordered list for consistent iteration
|
|
SNI_ORDER=(
|
|
"www.delfi.lv"
|
|
"www.lmt.lv"
|
|
"www.tele2.lv"
|
|
"www.lsm.lv"
|
|
"www.inbox.lv"
|
|
"e-klase.lv"
|
|
"share.alogins.net"
|
|
"www.microsoft.com"
|
|
)
|
|
|
|
generate_config() {
|
|
local sni="$1"
|
|
local file="$2"
|
|
cat > "$file" << JSONEOF
|
|
{
|
|
"log": { "loglevel": "error" },
|
|
"inbounds": [{
|
|
"listen": "127.0.0.1",
|
|
"port": $SOCKS_PORT,
|
|
"protocol": "socks",
|
|
"settings": { "auth": "noauth", "udp": true },
|
|
"tag": "test-socks"
|
|
}],
|
|
"outbounds": [{
|
|
"tag": "juris-reality",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [{
|
|
"address": "share.alogins.net",
|
|
"port": 443,
|
|
"users": [{
|
|
"id": "64522a14-54aa-4b3c-8071-8c8b17aa1f08",
|
|
"flow": "xtls-rprx-vision",
|
|
"encryption": "none"
|
|
}]
|
|
}]
|
|
},
|
|
"streamSettings": {
|
|
"network": "tcp",
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "$sni",
|
|
"publicKey": "58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw",
|
|
"shortId": "48b4c16249ad44ff",
|
|
"spiderX": "/"
|
|
},
|
|
"tcpSettings": { "header": { "type": "none" } }
|
|
}
|
|
}]
|
|
}
|
|
JSONEOF
|
|
}
|
|
|
|
run_test() {
|
|
local sni="$1"
|
|
local config="$2"
|
|
local xray_pid=""
|
|
|
|
# Start xray
|
|
$XRAY_BIN -config "$config" > /dev/null 2>&1 &
|
|
xray_pid=$!
|
|
sleep 2
|
|
|
|
if ! kill -0 "$xray_pid" 2>/dev/null; then
|
|
echo "XRAY_FAIL"
|
|
return
|
|
fi
|
|
|
|
local proxy="socks5h://127.0.0.1:$SOCKS_PORT"
|
|
|
|
# 1. Connectivity
|
|
local exit_ip
|
|
exit_ip=$(curl -s --connect-timeout 10 --max-time 15 -x "$proxy" https://ifconfig.me 2>/dev/null || echo "FAIL")
|
|
|
|
if [[ "$exit_ip" != "$REMOTE_IP" ]]; then
|
|
kill "$xray_pid" 2>/dev/null; wait "$xray_pid" 2>/dev/null || true
|
|
echo "CONN_FAIL|$exit_ip|0|0|0|0|0|0"
|
|
return
|
|
fi
|
|
|
|
# 2. Latency — 10 samples
|
|
local latencies=()
|
|
for i in $(seq 1 10); do
|
|
local t
|
|
t=$(curl -s -o /dev/null -w '%{time_total}' --connect-timeout 10 --max-time 15 -x "$proxy" https://www.gstatic.com/generate_204 2>/dev/null || echo "0")
|
|
local ms
|
|
ms=$(echo "$t * 1000" | bc 2>/dev/null | cut -d. -f1)
|
|
if [[ -n "$ms" && "$ms" -gt 0 ]]; then
|
|
latencies+=("$ms")
|
|
fi
|
|
done
|
|
|
|
local lat_min=0 lat_avg=0 lat_p95=0 lat_max=0
|
|
if [[ ${#latencies[@]} -gt 0 ]]; then
|
|
local sorted
|
|
sorted=($(printf '%s\n' "${latencies[@]}" | sort -n))
|
|
local cnt=${#sorted[@]}
|
|
lat_min=${sorted[0]}
|
|
lat_max=${sorted[$((cnt - 1))]}
|
|
local sum=0
|
|
for v in "${sorted[@]}"; do sum=$((sum + v)); done
|
|
lat_avg=$((sum / cnt))
|
|
local p95_idx
|
|
p95_idx=$(echo "($cnt * 95 + 99) / 100 - 1" | bc)
|
|
[[ $p95_idx -ge $cnt ]] && p95_idx=$((cnt - 1))
|
|
lat_p95=${sorted[$p95_idx]}
|
|
fi
|
|
|
|
# 3. Throughput — download 10MB
|
|
local dl_result
|
|
dl_result=$(curl -s -o /dev/null -w '%{size_download} %{time_total} %{speed_download}' \
|
|
--connect-timeout 15 --max-time 60 \
|
|
-x "$proxy" "http://speedtest.tele2.net/10MB.zip" 2>/dev/null || echo "0 0 0")
|
|
local dl_bytes dl_speed
|
|
dl_bytes=$(echo "$dl_result" | awk '{print $1}')
|
|
dl_speed=$(echo "$dl_result" | awk '{print $3}')
|
|
local dl_mbps="0"
|
|
if [[ "$dl_bytes" -gt 0 ]] 2>/dev/null; then
|
|
dl_mbps=$(echo "scale=2; $dl_speed * 8 / 1048576" | bc)
|
|
fi
|
|
|
|
# 3b. Throughput — upload 5MB
|
|
local ul_result
|
|
ul_result=$(dd if=/dev/urandom bs=1M count=5 2>/dev/null | \
|
|
curl -s -o /dev/null -w '%{size_upload} %{time_total} %{speed_upload}' \
|
|
--connect-timeout 15 --max-time 60 \
|
|
-x "$proxy" -X POST -H "Content-Type: application/octet-stream" \
|
|
--data-binary @- "http://speedtest.tele2.net/upload.php" 2>/dev/null || echo "0 0 0")
|
|
local ul_bytes ul_speed
|
|
ul_bytes=$(echo "$ul_result" | awk '{print $1}')
|
|
ul_speed=$(echo "$ul_result" | awk '{print $3}')
|
|
local ul_mbps="0"
|
|
if [[ "$ul_bytes" -gt 0 ]] 2>/dev/null; then
|
|
ul_mbps=$(echo "scale=2; $ul_speed * 8 / 1048576" | bc)
|
|
fi
|
|
|
|
kill "$xray_pid" 2>/dev/null; wait "$xray_pid" 2>/dev/null || true
|
|
|
|
echo "OK|$exit_ip|$lat_min|$lat_avg|$lat_p95|$lat_max|$dl_mbps|$ul_mbps"
|
|
}
|
|
|
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
|
echo "============================================"
|
|
echo " SNI Configuration Benchmark"
|
|
echo " $(date -u '+%Y-%m-%d %H:%M UTC')"
|
|
echo "============================================"
|
|
echo ""
|
|
|
|
declare -A RESULTS
|
|
|
|
for sni in "${SNI_ORDER[@]}"; do
|
|
desc="${SNIS[$sni]}"
|
|
config="$CONFIGS_DIR/${sni//[^a-zA-Z0-9._-]/_}.json"
|
|
|
|
echo "[$sni] ($desc)"
|
|
echo -n " Generating config... "
|
|
generate_config "$sni" "$config"
|
|
echo "done"
|
|
echo -n " Running tests... "
|
|
|
|
result=$(run_test "$sni" "$config")
|
|
RESULTS["$sni"]="$result"
|
|
|
|
status=$(echo "$result" | cut -d'|' -f1)
|
|
if [[ "$status" == "OK" ]]; then
|
|
avg=$(echo "$result" | cut -d'|' -f4)
|
|
dl=$(echo "$result" | cut -d'|' -f7)
|
|
ul=$(echo "$result" | cut -d'|' -f8)
|
|
echo "OK (avg=${avg}ms, dl=${dl}Mbps, ul=${ul}Mbps)"
|
|
else
|
|
echo "FAILED ($status)"
|
|
fi
|
|
echo ""
|
|
done
|
|
|
|
# ── Write results ─────────────────────────────────────────────────────────────
|
|
{
|
|
echo "# SNI Configuration Test Results"
|
|
echo ""
|
|
echo "Date: $(date -u '+%Y-%m-%d %H:%M UTC')"
|
|
echo "Server: share.alogins.net (83.99.190.32)"
|
|
echo "Protocol: VLESS + XTLS-Reality + Vision"
|
|
echo "Reality dest: www.delfi.lv:443"
|
|
echo ""
|
|
echo "## Results"
|
|
echo ""
|
|
echo "| # | SNI | Type | Conn | Latency Min | Latency Avg | Latency P95 | Latency Max | Download | Upload |"
|
|
echo "|---|-----|------|------|-------------|-------------|-------------|-------------|----------|--------|"
|
|
|
|
idx=0
|
|
best_sni=""
|
|
best_score=999999
|
|
for sni in "${SNI_ORDER[@]}"; do
|
|
idx=$((idx + 1))
|
|
desc="${SNIS[$sni]}"
|
|
result="${RESULTS[$sni]}"
|
|
status=$(echo "$result" | cut -d'|' -f1)
|
|
|
|
if [[ "$status" == "OK" ]]; then
|
|
ip=$(echo "$result" | cut -d'|' -f2)
|
|
lat_min=$(echo "$result" | cut -d'|' -f3)
|
|
lat_avg=$(echo "$result" | cut -d'|' -f4)
|
|
lat_p95=$(echo "$result" | cut -d'|' -f5)
|
|
lat_max=$(echo "$result" | cut -d'|' -f6)
|
|
dl=$(echo "$result" | cut -d'|' -f7)
|
|
ul=$(echo "$result" | cut -d'|' -f8)
|
|
echo "| $idx | \`$sni\` | $desc | OK | ${lat_min}ms | ${lat_avg}ms | ${lat_p95}ms | ${lat_max}ms | ${dl} Mbps | ${ul} Mbps |"
|
|
|
|
# Score: lower avg latency + higher throughput = better
|
|
# score = avg_latency - (dl_mbps + ul_mbps) (lower is better)
|
|
score=$(echo "$lat_avg" | bc)
|
|
if [[ $score -lt $best_score ]]; then
|
|
best_score=$score
|
|
best_sni=$sni
|
|
fi
|
|
else
|
|
echo "| $idx | \`$sni\` | $desc | FAIL | — | — | — | — | — | — |"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "## Best Configuration"
|
|
echo ""
|
|
if [[ -n "$best_sni" ]]; then
|
|
result="${RESULTS[$best_sni]}"
|
|
lat_avg=$(echo "$result" | cut -d'|' -f4)
|
|
dl=$(echo "$result" | cut -d'|' -f7)
|
|
ul=$(echo "$result" | cut -d'|' -f8)
|
|
echo "**Winner: \`$best_sni\`** (${SNIS[$best_sni]})"
|
|
echo ""
|
|
echo "- Average latency: ${lat_avg}ms"
|
|
echo "- Download: ${dl} Mbps"
|
|
echo "- Upload: ${ul} Mbps"
|
|
echo ""
|
|
echo "### Recommended client outbound config"
|
|
echo ""
|
|
echo '```json'
|
|
echo "{"
|
|
echo ' "tag": "juris-reality",'
|
|
echo ' "protocol": "vless",'
|
|
echo ' "settings": {'
|
|
echo ' "vnext": [{'
|
|
echo ' "address": "share.alogins.net",'
|
|
echo ' "port": 443,'
|
|
echo ' "users": [{'
|
|
echo ' "id": "64522a14-54aa-4b3c-8071-8c8b17aa1f08",'
|
|
echo ' "flow": "xtls-rprx-vision",'
|
|
echo ' "encryption": "none"'
|
|
echo ' }]'
|
|
echo ' }]'
|
|
echo ' },'
|
|
echo ' "streamSettings": {'
|
|
echo ' "network": "tcp",'
|
|
echo ' "security": "reality",'
|
|
echo ' "realitySettings": {'
|
|
echo ' "fingerprint": "chrome",'
|
|
echo " \"serverName\": \"$best_sni\","
|
|
echo ' "publicKey": "58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw",'
|
|
echo ' "shortId": "48b4c16249ad44ff",'
|
|
echo ' "spiderX": "/"'
|
|
echo ' },'
|
|
echo ' "tcpSettings": { "header": { "type": "none" } }'
|
|
echo ' }'
|
|
echo "}"
|
|
echo '```'
|
|
else
|
|
echo "No configuration passed all tests."
|
|
fi
|
|
|
|
echo ""
|
|
echo "## All Configurations"
|
|
echo ""
|
|
echo "Individual config files are stored in \`configs/\` directory."
|
|
echo ""
|
|
for sni in "${SNI_ORDER[@]}"; do
|
|
config_name="${sni//[^a-zA-Z0-9._-]/_}.json"
|
|
echo "- \`configs/$config_name\` — SNI: \`$sni\`"
|
|
done
|
|
|
|
echo ""
|
|
echo "## Server-Side Reality Settings"
|
|
echo ""
|
|
echo '```json'
|
|
echo '"realitySettings": {'
|
|
echo ' "dest": "www.delfi.lv:443",'
|
|
echo ' "serverNames": ['
|
|
echo ' "www.delfi.lv",'
|
|
echo ' "www.lmt.lv",'
|
|
echo ' "www.tele2.lv",'
|
|
echo ' "www.lsm.lv",'
|
|
echo ' "www.inbox.lv",'
|
|
echo ' "e-klase.lv",'
|
|
echo ' "share.alogins.net",'
|
|
echo ' "www.microsoft.com"'
|
|
echo ' ],'
|
|
echo ' "privateKey": "KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY",'
|
|
echo ' "shortIds": ["48b4c16249ad44ff", ""]'
|
|
echo '}'
|
|
echo '```'
|
|
} > "$RESULTS_FILE"
|
|
|
|
echo "============================================"
|
|
echo "Results written to: $RESULTS_FILE"
|
|
echo "============================================"
|