Add all project files, configs, scripts and results
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
334
test_sni_configs.sh
Executable file
334
test_sni_configs.sh
Executable file
@@ -0,0 +1,334 @@
|
||||
#!/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 "============================================"
|
||||
Reference in New Issue
Block a user