Files
probe/probe.sh

706 lines
25 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/data/data/com.termux/files/usr/bin/bash
# ══════════════════════════════════════════════════════
# WHITELIST PROBE v1.0
# Определяет доступные методы обхода whitelist
# Платформа: Termux (Android) / Linux
# Зависимости: curl, nc (ncat), openssl, nslookup
# ══════════════════════════════════════════════════════
set -o pipefail
# ── Конфигурация ──────────────────────────────────────
VPS_IP="194.87.245.138" # Ирландия (exit node)
MOSCOW_IP="94.141.253.12" # Москва (relay)
DNSTT_DOMAIN="t.chatsquad.ru"
DNSTT_NS="ns-t.chatsquad.ru"
TIMEOUT=3 # секунд на каждый тест
RESULT_DIR="./results"
TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S')
RESULT_FILE="${RESULT_DIR}/probe_${TIMESTAMP}.txt"
JSON_FILE="${RESULT_DIR}/probe_${TIMESTAMP}.json"
# ── Цвета ─────────────────────────────────────────────
if [ -t 1 ]; then
G='\033[0;32m' # green
R='\033[0;31m' # red
Y='\033[0;33m' # yellow
C='\033[0;36m' # cyan
B='\033[1m' # bold
N='\033[0m' # reset
else
G='' R='' Y='' C='' B='' N=''
fi
# ── Счётчики ──────────────────────────────────────────
declare -A RESULTS
TOTAL=0
PASS=0
FAIL=0
# ── Утилиты ───────────────────────────────────────────
ok() { echo -e " ${G}${N} $1"; RESULTS["$2"]="ok"; ((PASS++)); ((TOTAL++)); }
fail() { echo -e " ${R}${N} $1"; RESULTS["$2"]="fail"; ((FAIL++)); ((TOTAL++)); }
skip() { echo -e " ${Y}${N} $1"; RESULTS["$2"]="skip"; ((TOTAL++)); }
info() { echo -e " ${C}${N} $1"; }
hdr() { echo -e "\n${B}[$1]${N}"; }
# Ping с таймаутом
do_ping() {
local host=$1
local result
result=$(ping -c 1 -W $TIMEOUT "$host" 2>/dev/null | grep -oP 'time=\K[0-9.]+')
if [ -n "$result" ]; then
echo "${result}ms"
return 0
fi
return 1
}
# TCP connect
do_tcp() {
local host=$1 port=$2
timeout $TIMEOUT bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null
return $?
}
# UDP test (отправить пакет, ждать ответ)
do_udp() {
local host=$1 port=$2
echo -n "test" | timeout $TIMEOUT nc -u -w $TIMEOUT "$host" "$port" 2>/dev/null
# UDP "успех" если nc не вернул ошибку (не гарантирует доставку)
return $?
}
# HTTPS test
do_https() {
local host=$1
local code
code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout $TIMEOUT --max-time $((TIMEOUT+2)) "https://$host" 2>/dev/null)
if [ "$code" -ge 100 ] 2>/dev/null && [ "$code" -lt 600 ] 2>/dev/null; then
echo "$code"
return 0
fi
return 1
}
# DNS resolve
do_resolve() {
local domain=$1 server=$2
local result
if [ -n "$server" ]; then
result=$(nslookup "$domain" "$server" 2>/dev/null | grep -A1 "Name:" | grep "Address:" | head -1 | awk '{print $2}')
else
result=$(nslookup "$domain" 2>/dev/null | grep -A1 "Name:" | grep "Address:" | head -1 | awk '{print $2}')
fi
if [ -n "$result" ]; then
echo "$result"
return 0
fi
return 1
}
# TLS handshake с кастомным SNI
do_tls_sni() {
local ip=$1 port=$2 sni=$3
echo | timeout $TIMEOUT openssl s_client -connect "$ip:$port" -servername "$sni" 2>/dev/null | grep -q "BEGIN CERTIFICATE"
return $?
}
# HTTP/2 check
do_h2() {
local host=$1
local proto
proto=$(curl -s -o /dev/null -w '%{http_version}' --connect-timeout $TIMEOUT --max-time $((TIMEOUT+2)) "https://$host" 2>/dev/null)
echo "$proto"
[ "$proto" = "2" ] && return 0
return 1
}
# ══════════════════════════════════════════════════════
# УСТАНОВКА ЗАВИСИМОСТЕЙ
# ══════════════════════════════════════════════════════
install_deps() {
local missing=()
command -v curl >/dev/null || missing+=(curl)
command -v nc >/dev/null || missing+=(nmap-ncat)
command -v openssl >/dev/null || missing+=(openssl-tool)
command -v nslookup >/dev/null || missing+=(dnsutils)
command -v ping >/dev/null || missing+=(inetutils)
if [ ${#missing[@]} -gt 0 ]; then
echo -e "${Y}Установка: ${missing[*]}${N}"
if command -v pkg >/dev/null; then
pkg install -y "${missing[@]}" 2>/dev/null
elif command -v apt-get >/dev/null; then
sudo apt-get install -y "${missing[@]}" 2>/dev/null
fi
fi
}
# ══════════════════════════════════════════════════════
# ТЕСТЫ
# ══════════════════════════════════════════════════════
test_provider() {
hdr "ПРОВАЙДЕР"
local ext_ip isp asn
ext_ip=$(curl -s --connect-timeout $TIMEOUT ifconfig.me 2>/dev/null)
if [ -z "$ext_ip" ]; then
ext_ip=$(curl -s --connect-timeout $TIMEOUT api.ipify.org 2>/dev/null)
fi
if [ -z "$ext_ip" ]; then
ext_ip=$(curl -s --connect-timeout $TIMEOUT ident.me 2>/dev/null)
fi
if [ -n "$ext_ip" ]; then
info "Внешний IP: ${B}$ext_ip${N}"
RESULTS["ext_ip"]="$ext_ip"
local ipinfo
ipinfo=$(curl -s --connect-timeout $TIMEOUT "http://ip-api.com/json/$ext_ip?fields=isp,as,country" 2>/dev/null)
if [ -n "$ipinfo" ]; then
isp=$(echo "$ipinfo" | grep -oP '"isp"\s*:\s*"\K[^"]+')
asn=$(echo "$ipinfo" | grep -oP '"as"\s*:\s*"\K[^"]+')
local country
country=$(echo "$ipinfo" | grep -oP '"country"\s*:\s*"\K[^"]+')
info "ISP: ${B}$isp${N}"
info "ASN: ${B}$asn${N}"
info "Страна: ${B}$country${N}"
RESULTS["isp"]="$isp"
RESULTS["asn"]="$asn"
fi
else
fail "Не удалось определить внешний IP" "ext_ip"
fi
}
test_icmp() {
hdr "ICMP (Ping)"
local -A targets=(
["VPS Ирландия"]="$VPS_IP"
["Москва relay"]="$MOSCOW_IP"
["yandex.ru"]="yandex.ru"
["ya.ru"]="ya.ru"
["vk.com"]="vk.com"
["mail.ru"]="mail.ru"
["ok.ru"]="ok.ru"
["sber.ru"]="sber.ru"
["gosuslugi.ru"]="gosuslugi.ru"
["mos.ru"]="mos.ru"
["Google 8.8.8.8"]="8.8.8.8"
["Cloudflare 1.1.1.1"]="1.1.1.1"
["Yandex DNS 77.88.8.8"]="77.88.8.8"
["Telegram"]="149.154.167.99"
)
local order=("yandex.ru" "ya.ru" "vk.com" "mail.ru" "ok.ru" "sber.ru" "gosuslugi.ru" "mos.ru" "Yandex DNS 77.88.8.8" "VPS Ирландия" "Москва relay" "Google 8.8.8.8" "Cloudflare 1.1.1.1" "Telegram")
for name in "${order[@]}"; do
local target="${targets[$name]}"
local t
t=$(do_ping "$target")
if [ $? -eq 0 ]; then
ok "$(printf '%-22s %s' "$name" "$t")" "icmp_$name"
else
fail "$(printf '%-22s' "$name")" "icmp_$name"
fi
done
}
test_dns() {
hdr "DNS RESOLUTION"
# Системный DNS
local r
r=$(do_resolve "yandex.ru")
if [ $? -eq 0 ]; then
ok "System DNS yandex.ru → $r" "dns_system"
else
fail "System DNS yandex.ru" "dns_system"
fi
# Через разные DNS-серверы
local -A dns_servers=(
["Yandex 77.88.8.8"]="77.88.8.8"
["Yandex 77.88.8.1"]="77.88.8.1"
["Google 8.8.8.8"]="8.8.8.8"
["Google 8.8.4.4"]="8.8.4.4"
["Cloudflare 1.1.1.1"]="1.1.1.1"
["Quad9 9.9.9.9"]="9.9.9.9"
)
local dns_order=("Yandex 77.88.8.8" "Yandex 77.88.8.1" "Google 8.8.8.8" "Google 8.8.4.4" "Cloudflare 1.1.1.1" "Quad9 9.9.9.9")
for name in "${dns_order[@]}"; do
local server="${dns_servers[$name]}"
r=$(do_resolve "yandex.ru" "$server")
if [ $? -eq 0 ]; then
ok "$(printf '%-22s yandex.ru → %s' "$name" "$r")" "dns_$name"
else
fail "$(printf '%-22s' "$name")" "dns_$name"
fi
done
# DNSTT домен
echo ""
r=$(do_resolve "$DNSTT_DOMAIN")
if [ $? -eq 0 ]; then
ok "DNSTT domain $DNSTT_DOMAIN$r" "dns_dnstt"
else
# Попробуем NS запись
local ns_result
ns_result=$(nslookup -type=NS "$DNSTT_DOMAIN" 2>/dev/null | grep -i "nameserver" | head -1)
if [ -n "$ns_result" ]; then
ok "DNSTT domain (NS) $DNSTT_DOMAIN → delegated" "dns_dnstt"
else
fail "DNSTT domain $DNSTT_DOMAIN" "dns_dnstt"
fi
fi
r=$(do_resolve "$DNSTT_NS")
if [ $? -eq 0 ]; then
ok "DNSTT NS $DNSTT_NS$r" "dns_dnstt_ns"
else
fail "DNSTT NS $DNSTT_NS" "dns_dnstt_ns"
fi
}
test_dns_tunnel() {
hdr "DNS TUNNEL VIABILITY"
# DoH (DNS over HTTPS) — через Яндекс
local r
r=$(curl -s --connect-timeout $TIMEOUT --max-time $((TIMEOUT+2)) \
-H 'Accept: application/dns-json' \
"https://dns.yandex.net/dns-query?name=example.com&type=A" 2>/dev/null)
if echo "$r" | grep -q "Answer\|Status"; then
ok "DoH Яндекс dns.yandex.net" "doh_yandex"
else
fail "DoH Яндекс dns.yandex.net" "doh_yandex"
fi
# DoH Google
r=$(curl -s --connect-timeout $TIMEOUT --max-time $((TIMEOUT+2)) \
"https://dns.google/resolve?name=example.com&type=A" 2>/dev/null)
if echo "$r" | grep -q "Answer\|Status"; then
ok "DoH Google dns.google" "doh_google"
else
fail "DoH Google dns.google" "doh_google"
fi
# DoH Cloudflare
r=$(curl -s --connect-timeout $TIMEOUT --max-time $((TIMEOUT+2)) \
-H 'Accept: application/dns-json' \
"https://cloudflare-dns.com/dns-query?name=example.com&type=A" 2>/dev/null)
if echo "$r" | grep -q "Answer\|Status"; then
ok "DoH Cloudflare cloudflare-dns.com" "doh_cf"
else
fail "DoH Cloudflare cloudflare-dns.com" "doh_cf"
fi
# DoT (DNS over TLS) — порт 853
echo ""
for name_server in "Yandex:77.88.8.8" "Google:8.8.8.8" "CF:1.1.1.1"; do
local label="${name_server%%:*}"
local ip="${name_server##*:}"
if do_tcp "$ip" 853; then
ok "DoT $label $ip:853" "dot_$label"
else
fail "DoT $label $ip:853" "dot_$label"
fi
done
}
test_tcp_our_servers() {
hdr "TCP — НАШИ СЕРВЕРЫ"
local -A ports=(
["VPS:443 (VLESS)"]="$VPS_IP:443"
["VPS:38246 (SS)"]="$VPS_IP:38246"
["VPS:8443 (Chisel)"]="$VPS_IP:8443"
["VPS:22 (SSH)"]="$VPS_IP:22"
["VPS:53 (DNS)"]="$VPS_IP:53"
["Moscow:2053 (relay)"]="$MOSCOW_IP:2053"
["Moscow:443 (HTTPS)"]="$MOSCOW_IP:443"
["Moscow:22 (SSH)"]="$MOSCOW_IP:22"
)
local order=("VPS:443 (VLESS)" "VPS:38246 (SS)" "VPS:8443 (Chisel)" "VPS:22 (SSH)" "VPS:53 (DNS)" "Moscow:2053 (relay)" "Moscow:443 (HTTPS)" "Moscow:22 (SSH)")
for name in "${order[@]}"; do
local hp="${ports[$name]}"
local host="${hp%%:*}"
local port="${hp##*:}"
if do_tcp "$host" "$port"; then
ok "$(printf '%-25s' "$name")" "tcp_$name"
else
fail "$(printf '%-25s' "$name")" "tcp_$name"
fi
done
}
test_udp() {
hdr "UDP"
local -A targets=(
["VPS:53 (DNSTT)"]="$VPS_IP:53"
["VPS:443 (QUIC)"]="$VPS_IP:443"
["VPS:43742 (WG)"]="$VPS_IP:43742"
["VPS:47426 (AWG)"]="$VPS_IP:47426"
["VPS:48253 (AWG2)"]="$VPS_IP:48253"
)
local order=("VPS:53 (DNSTT)" "VPS:443 (QUIC)" "VPS:43742 (WG)" "VPS:47426 (AWG)" "VPS:48253 (AWG2)")
info "UDP-тесты ненадёжны без ответа сервера"
for name in "${order[@]}"; do
local hp="${targets[$name]}"
local host="${hp%%:*}"
local port="${hp##*:}"
# Для DNS порта — отправляем реальный DNS запрос
if [ "$port" = "53" ]; then
local dns_r
dns_r=$(do_resolve "yandex.ru" "$host")
if [ $? -eq 0 ]; then
ok "$(printf '%-25s (DNS ответил: %s)' "$name" "$dns_r")" "udp_$name"
else
fail "$(printf '%-25s' "$name")" "udp_$name"
fi
else
if do_udp "$host" "$port"; then
skip "$(printf '%-25s (отправлено, ответ неизвестен)' "$name")" "udp_$name"
else
fail "$(printf '%-25s' "$name")" "udp_$name"
fi
fi
done
}
test_https() {
hdr "HTTPS / TLS"
local -A sites=(
# Российские
["yandex.ru"]="yandex.ru"
["ya.ru"]="ya.ru"
["vk.com"]="vk.com"
["mail.ru"]="mail.ru"
["ok.ru"]="ok.ru"
["sber.ru"]="sber.ru"
["gosuslugi.ru"]="gosuslugi.ru"
["mos.ru"]="mos.ru"
["rutube.ru"]="rutube.ru"
# Зарубежные
["google.com"]="google.com"
["cloudflare.com"]="cloudflare.com"
["microsoft.com"]="microsoft.com"
["apple.com"]="apple.com"
["github.com"]="github.com"
["telegram.org"]="telegram.org"
# CDN
["cdn.jsdelivr.net"]="cdn.jsdelivr.net"
["cdnjs.cloudflare.com"]="cdnjs.cloudflare.com"
["unpkg.com"]="unpkg.com"
# Облака
["cloud.yandex.ru"]="cloud.yandex.ru"
["functions.yandexcloud.net"]="functions.yandexcloud.net"
["cloud.vk.com"]="cloud.vk.com"
# DoH
["dns.yandex.net"]="dns.yandex.net"
)
local order=(
"yandex.ru" "ya.ru" "vk.com" "mail.ru" "ok.ru" "sber.ru" "gosuslugi.ru" "mos.ru" "rutube.ru"
"---РУ/Зарубеж---"
"google.com" "cloudflare.com" "microsoft.com" "apple.com" "github.com" "telegram.org"
"---CDN---"
"cdn.jsdelivr.net" "cdnjs.cloudflare.com" "unpkg.com"
"---Облака---"
"cloud.yandex.ru" "functions.yandexcloud.net" "cloud.vk.com" "dns.yandex.net"
)
for name in "${order[@]}"; do
if [[ "$name" == ---* ]]; then
echo ""
continue
fi
local target="${sites[$name]}"
local code
code=$(do_https "$target")
if [ $? -eq 0 ]; then
local h2
h2=$(do_h2 "$target")
local proto_tag=""
[ "$h2" = "2" ] && proto_tag=" HTTP/2" || proto_tag=" HTTP/$h2"
ok "$(printf '%-28s %s%s' "$name" "$code" "$proto_tag")" "https_$name"
else
fail "$(printf '%-28s' "$name")" "https_$name"
fi
done
}
test_sni() {
hdr "SNI FILTERING"
info "TLS handshake к VPS ($VPS_IP:443) с разными SNI"
local snis=("yandex.ru" "ya.ru" "vk.com" "mail.ru" "google.com" "$VPS_IP")
for sni in "${snis[@]}"; do
if do_tls_sni "$VPS_IP" 443 "$sni"; then
ok "$(printf 'SNI=%-20s → TLS OK' "$sni")" "sni_$sni"
else
fail "$(printf 'SNI=%-20s' "$sni")" "sni_$sni"
fi
done
echo ""
info "TLS handshake к Москве ($MOSCOW_IP:2053)"
for sni in "yandex.ru" "ya.ru"; do
if do_tls_sni "$MOSCOW_IP" 2053 "$sni"; then
ok "$(printf 'SNI=%-20s → TLS OK' "$sni")" "sni_moscow_$sni"
else
fail "$(printf 'SNI=%-20s' "$sni")" "sni_moscow_$sni"
fi
done
}
test_cdn() {
hdr "CDN REACHABILITY"
# Cloudflare IP ranges
local cf_ips=("104.16.0.1" "104.17.0.1" "172.64.0.1" "172.67.0.1")
info "Cloudflare IP ranges"
for ip in "${cf_ips[@]}"; do
if do_tcp "$ip" 443; then
ok "$(printf '%-22s TCP:443' "$ip")" "cdn_cf_$ip"
else
fail "$(printf '%-22s' "$ip")" "cdn_cf_$ip"
fi
done
echo ""
info "Yandex CDN"
local ycdn
ycdn=$(do_resolve "yastatic.net")
if [ $? -eq 0 ]; then
if do_tcp "$ycdn" 443; then
ok "yastatic.net $ycdn TCP:443" "cdn_yandex"
else
fail "yastatic.net $ycdn" "cdn_yandex"
fi
else
fail "yastatic.net (не резолвится)" "cdn_yandex"
fi
local vkcdn
vkcdn=$(do_resolve "st.vk.com")
if [ $? -eq 0 ]; then
if do_tcp "$vkcdn" 443; then
ok "st.vk.com $vkcdn TCP:443" "cdn_vk"
else
fail "st.vk.com $vkcdn" "cdn_vk"
fi
else
fail "st.vk.com (не резолвится)" "cdn_vk"
fi
}
test_advanced() {
hdr "ADVANCED"
# WebSocket upgrade test через доступные хосты
info "WebSocket upgrade"
local ws_code
ws_code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout $TIMEOUT \
-H "Upgrade: websocket" -H "Connection: Upgrade" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
-H "Sec-WebSocket-Version: 13" \
"https://yandex.ru" 2>/dev/null)
if [ "$ws_code" = "101" ]; then
ok "WebSocket yandex.ru → 101 Switching" "ws_yandex"
else
fail "WebSocket yandex.ru → $ws_code (не поддерживает)" "ws_yandex"
fi
# QUIC / HTTP3
echo ""
info "QUIC (HTTP/3)"
local quic
quic=$(curl -s -o /dev/null -w '%{http_version}' --connect-timeout $TIMEOUT \
--http3-only "https://yandex.ru" 2>/dev/null)
if [ "$quic" = "3" ]; then
ok "HTTP/3 yandex.ru → работает" "quic_yandex"
else
skip "HTTP/3 yandex.ru → curl без HTTP/3 или заблокирован" "quic_yandex"
fi
# ECH support
echo ""
info "ECH (Encrypted Client Hello)"
local ech
ech=$(echo | timeout $TIMEOUT openssl s_client -connect cloudflare.com:443 \
-ech grease 2>&1 | grep -i "ech")
if [ -n "$ech" ]; then
ok "ECH → поддерживается" "ech"
else
skip "ECH → не поддерживается данной версией openssl" "ech"
fi
}
# ══════════════════════════════════════════════════════
# РЕКОМЕНДАЦИИ
# ══════════════════════════════════════════════════════
recommendations() {
hdr "РЕКОМЕНДАЦИИ"
echo ""
local rec=()
local rec_detail=()
# S-тир: CDN tunnel
if [ "${RESULTS[https_cloudflare.com]}" = "ok" ] || [ "${RESULTS[cdn_cf_104.16.0.1]}" = "ok" ]; then
rec+=("S")
rec_detail+=("${G}S-тир${N} │ VLESS + WebSocket + Cloudflare CDN │ CF доступен, быстро и надёжно")
fi
if [ "${RESULTS[https_cdn.jsdelivr.net]}" = "ok" ]; then
rec+=("S")
rec_detail+=("${G}S-тир${N} │ CDN-туннель через jsDelivr │ CDN доступен")
fi
# S-тир: Direct VLESS
if [ "${RESULTS[tcp_VPS:443 (VLESS)]}" = "ok" ]; then
rec+=("S")
rec_detail+=("${G}S-тир${N} │ VLESS + XHTTP + Reality (прямой) │ TCP к VPS:443 открыт")
fi
# A-тир: Moscow relay
if [ "${RESULTS[tcp_Moscow:2053 (relay)]}" = "ok" ]; then
rec+=("A")
rec_detail+=("${Y}A-тир${N} │ VLESS через Moscow relay │ TCP к Москве:2053 открыт")
fi
# A-тир: Hysteria2
if [ "${RESULTS[udp_VPS:443 (QUIC)]}" = "ok" ]; then
rec+=("A")
rec_detail+=("${Y}A-тир${N} │ Hysteria2 + Salamander (UDP) │ UDP к VPS работает")
fi
# B-тир: Yandex Cloud Functions
if [ "${RESULTS[https_functions.yandexcloud.net]}" = "ok" ]; then
rec+=("B")
rec_detail+=("${C}B-тир${N} │ Serverless proxy (YC Functions) │ Yandex Cloud доступен")
fi
# B-тир: DNSTT
if [ "${RESULTS[dns_dnstt]}" = "ok" ] || [ "${RESULTS[dns_system]}" = "ok" ]; then
rec+=("B")
rec_detail+=("${C}B-тир${N} │ DNSTT (DNS-туннель) │ DNS работает, ~50-100 Кбит/с")
fi
# B-тир: DoH tunnel
if [ "${RESULTS[doh_yandex]}" = "ok" ]; then
rec+=("B")
rec_detail+=("${C}B-тир${N} │ DoH tunnel (dns.yandex.net) │ DNS-over-HTTPS через Яндекс")
fi
# C-тир: ICMP tunnel
local icmp_to_vps="${RESULTS[icmp_VPS Ирландия]}"
local icmp_to_moscow="${RESULTS[icmp_Москва relay]}"
if [ "$icmp_to_vps" = "ok" ] || [ "$icmp_to_moscow" = "ok" ]; then
rec+=("C")
rec_detail+=("${R}C-тир${N} │ ICMP tunnel (ptunnel-ng) │ Ping к серверу работает, очень медленно")
fi
# Shadowsocks
if [ "${RESULTS[tcp_VPS:38246 (SS)]}" = "ok" ]; then
rec+=("A")
rec_detail+=("${Y}A-тир${N} │ Shadowsocks │ TCP к VPS:38246 открыт")
fi
# Chisel
if [ "${RESULTS[tcp_VPS:8443 (Chisel)]}" = "ok" ]; then
rec+=("B")
rec_detail+=("${C}B-тир${N} │ Chisel (HTTP tunnel) │ TCP к VPS:8443 открыт")
fi
# WireGuard / AmneziaWG
if [ "${RESULTS[udp_VPS:43742 (WG)]}" = "ok" ] || [ "${RESULTS[udp_VPS:47426 (AWG)]}" = "ok" ]; then
rec+=("B")
rec_detail+=("${C}B-тир${N} │ AmneziaWG / WireGuard │ UDP к VPS работает")
fi
if [ ${#rec_detail[@]} -eq 0 ]; then
echo -e " ${R}Ни один метод не определён как рабочий${N}"
echo -e " ${Y}Варианты:${N}"
echo " • Спутниковый интернет (Starlink)"
echo " • Физический доступ к незаблокированной сети"
echo " • Mesh-сети"
else
local i=0
for detail in "${rec_detail[@]}"; do
((i++))
echo -e " $i. $detail"
done
fi
}
# ══════════════════════════════════════════════════════
# СОХРАНЕНИЕ РЕЗУЛЬТАТОВ
# ══════════════════════════════════════════════════════
save_results() {
mkdir -p "$RESULT_DIR"
# JSON
echo "{" > "$JSON_FILE"
echo " \"timestamp\": \"$TIMESTAMP\"," >> "$JSON_FILE"
echo " \"results\": {" >> "$JSON_FILE"
local first=true
for key in $(echo "${!RESULTS[@]}" | tr ' ' '\n' | sort); do
if [ "$first" = true ]; then
first=false
else
echo "," >> "$JSON_FILE"
fi
printf ' "%s": "%s"' "$key" "${RESULTS[$key]}" >> "$JSON_FILE"
done
echo "" >> "$JSON_FILE"
echo " }" >> "$JSON_FILE"
echo "}" >> "$JSON_FILE"
info "Результаты: $JSON_FILE"
}
# ══════════════════════════════════════════════════════
# MAIN
# ══════════════════════════════════════════════════════
main() {
echo -e "${B}══════════════════════════════════════════${N}"
echo -e "${B} WHITELIST PROBE v1.0 — $(date '+%Y-%m-%d %H:%M')${N}"
echo -e "${B}══════════════════════════════════════════${N}"
install_deps
test_provider
test_icmp
test_dns
test_dns_tunnel
test_tcp_our_servers
test_udp
test_https
test_sni
test_cdn
test_advanced
recommendations
save_results
echo ""
echo -e "${B}══════════════════════════════════════════${N}"
echo -e " Тестов: $TOTAL ${G}$PASS${N} ${R}$FAIL${N}"
echo -e "${B}══════════════════════════════════════════${N}"
}
main "$@"