montana/Node/External-Audit/TEST-PLAN.md
2026-05-21 03:44:38 +03:00

5.6 KiB
Raw Blame History

План тестов для аудитора

Версия: 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 </dev/null 2>&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 "<test-node-ip>" || break
done
# expected: <test-node-ip> исчезает за ≤ 120 секунд

ssh test-node 'systemctl start xray'
# Через 3060s аналогично — IP возвращается за ≤ 120 секунд

A-2. Reality probe от подделанного клиента (negative)

# Использовать корректный pbk, но неверный shortId:
xray run -config <(cat <<JSON
{"inbounds":[{"port":1090,"protocol":"socks","settings":{"auth":"noauth"}}],
"outbounds":[{"protocol":"vless","settings":{"vnext":[{"address":"cdn.montana.quest","port":443,
  "users":[{"id":"e6d355e2-2d79-4c96-a373-3b0e6b6f4b0d","encryption":"none","flow":"xtls-rprx-vision"}]}]}},
  "streamSettings":{"network":"tcp","security":"reality","realitySettings":{
    "fingerprint":"chrome","serverName":"www.googletagmanager.com",
    "publicKey":"EkTs2aGKnFNgFZ0f7wgft2sJp3VjwFQqIrwkZKM4gD8",
    "shortId":"0000000000000000"}}}]}
JSON
)
# expected: trafic просто прокатывается на www.googletagmanager.com (Reality fallback) — наш VPN недоступен

A-3. Active probing (DPI emulation)

# Стандартный TLS-handshake к нашему :443 со случайным SNI:
echo | timeout 5 openssl s_client -connect 91.132.142.42:443 -servername example.com 2>&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 <node> 'fail2ban-client status sshd | grep "Currently banned"'
# expected: число (фейл2бан работает)

S-5. Версии xray/Reality

ssh <node> '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 >/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 и формирует отчёт.