# План тестов для аудитора Версия: **2026-05-18** Все тесты — read-only (кроме раздела «Active»). Аудитор не получает админ-доступ. ## Passive (без прав) ### P-1. DNS multi-A ``` dig @1.1.1.1 cdn.montana.quest A # expected: >=2 A-records, TTL <= 120 ``` ### P-2. TLS handshake к каждому IP ``` for ip in $(dig +short cdn.montana.quest A); do echo "--- $ip ---" timeout 5 openssl s_client -connect $ip:443 -servername www.googletagmanager.com -tls1_3 &1 \ | grep -E "subject=|Verification|TLS_AES" done # expected: на каждом IP — subject=*.google-analytics.com, Verification: OK, TLSv1.3 ``` ### P-3. Подписка отдаёт ровно один URL с тем же pbk ``` curl -s https://montana.quest/vpn/sub | base64 -d # expected: одна строка vless://e6d355e2-…@cdn.montana.quest:443?…pbk=EkTs2aGKnFNgFZ0f7wgft2sJp3VjwFQqIrwkZKM4gD8…sid=302805bc0c25e504… ``` ### P-4. /vpn/node/pool отвечает и согласован с DNS ``` curl -s https://montana.quest/vpn/node/pool | jq '.records[].ip' | sort dig +short cdn.montana.quest A | sort # expected: одинаковые списки ``` ### P-5. /vpn/node/health ``` curl -s https://montana.quest/vpn/node/health | jq # expected: {"ok": true, "in_pool": N, "tracked": M} где N == |records| ``` ### P-6. SNI не отвечает HTTP error при TLS-only probe (Reality маскировка) ``` curl -sk --resolve www.googletagmanager.com:443:91.132.142.42 https://www.googletagmanager.com/ -o /tmp/g.html -w "%{http_code}\n" # expected: 200 — Reality успешно проксирует на реальный Google ``` ### P-7. Версии открытых артефактов ``` curl -sI https://montana.quest/vpn/ | grep -i server # expected: nginx, без CVE-known версии ``` ## Active (с тестовым узлом, без права писать на боевые) ### A-1. E2E auto-prune Симулируем падение одного узла (если у аудитора есть тестовый узел в pool): ``` ssh test-node 'systemctl stop xray' # Через 30s: start=$(date +%s); while sleep 5; do IPS=$(curl -s https://montana.quest/vpn/node/pool | jq -r '.records[].ip' | sort | xargs) echo "$(($(date +%s)-start))s: $IPS" echo "$IPS" | grep -q "" || break done # expected: исчезает за ≤ 120 секунд ssh test-node 'systemctl start xray' # Через 30–60s аналогично — IP возвращается за ≤ 120 секунд ``` ### A-2. Reality probe от подделанного клиента (negative) ``` # Использовать корректный pbk, но неверный shortId: xray run -config <(cat <&1 | grep -E "subject=|Verification" # expected: cert от www.googletagmanager.com (или fallback на dest); не уникальный «Montana» fingerprint ``` ## Security ### S-1. Утечка privateKey ``` cd /Users/kh./Python/Ничто/Montana grep -rE 'cL7D6FCqH5|montana-vpn-privkey' . \ --exclude-dir=External-Audit --exclude-dir=.git --exclude='*.bak*' 2>/dev/null # expected: 0 совпадений в публичных текстах (allowed только в этом аудит-пакете как описание) ``` ### S-2. Утечка admin token ``` grep -rE 'orchestrator-admin' . --exclude-dir=External-Audit 2>/dev/null # expected: 0 в коде (только в memory + Keychain refs) ``` ### S-3. Открытые порты узла ``` nmap -Pn -p- -T4 91.132.142.42 | grep open # expected: 22, 80, 443, 8444 — и ничего постороннего ``` ### S-4. fail2ban статус ``` ssh 'fail2ban-client status sshd | grep "Currently banned"' # expected: число (фейл2бан работает) ``` ### S-5. Версии xray/Reality ``` ssh 'xray version | head -1' # expected: ≥ Xray 26.x (актуальное на дату аудита) ``` ## Производительность ### Q-1. Время handshake ``` for ip in $(dig +short cdn.montana.quest A); do for i in 1 2 3; do /usr/bin/time -f "%E" timeout 5 openssl s_client -connect $ip:443 \ -servername www.googletagmanager.com -tls1_3 /dev/null 2>&1 done 2>&1 | grep -v "^$" done # expected: < 500ms p99 для каждого узла ``` ### Q-2. Throughput через узел ``` # С клиента, подключённого через VPN: curl -o /dev/null https://speed.cloudflare.com/__down?bytes=104857600 -w "%{speed_download}\n" # expected: > 10 MB/s ``` ## Готовый скрипт ``` bash scripts/audit-probe.sh ``` Запускает P-1, P-2, P-3, P-4, P-5, S-1, S-3 и формирует отчёт.