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

5.4 KiB
Raw Blame History

Прозрачность счётчика пользователей

Версия: 2026-05-19

Что мы доказываем

Число «Уникальных пользователей» на montana.quest/vpn/не выдумано.

Что мы НЕ публикуем

IP-адреса пользователей. Это PII (персональные данные) — публиковать их незаконно (GDPR / 152-ФЗ) и аморально.

Как доказательство работает

  1. На узле Helsinki в /var/lib/montana-vpn-stats/unique-ips.txt накапливается список IP, когда-либо подключавшихся к VPN (из xray access.log). Файл root:root 600, не доступен публично.

  2. Каждую минуту скрипт /opt/montana-vpn-stats/transparency-sign.py:

    • читает список IP
    • сортирует
    • вычисляет sha256(joined-with-LF)merkle_root
    • подписывает snapshot {ts_utc, unique_users, merkle_root, algorithm} ключом ed25519
    • публикует:
      • https://montana.quest/vpn/transparency.json — последний snapshot
      • https://montana.quest/vpn/transparency-log.txt — append-only лог всех snapshot'ов
  3. Публичный ключ подписи: d9a8bf07871d35c8e85f7de4a9b62896c330ba0987732468515c7bda8bb4adde (ed25519). Лежит здесь и в репозитории. Приватный ключ — только на узле, 600 root.

Что может проверить аудитор без доступа к серверу

Свойство Как проверить
Подпись валидна verify-transparency.sh проверяет ed25519 над snapshot
Публичный ключ не сменили сравнить с публикуемым в этом репозитории
Число не подкручивается вниз transparency-log.txt — append-only, аудитор скачивает последние N снимков, проверяет монотонность
Snapshot timestamp реальный сравнить ts_utc с моментом скачивания (расхождение ≤ 60s)
Один и тот же merkle root = одни и те же IPы повторный merkle root между snapshots = новых IP нет

Что аудитор НЕ может узнать

  • Конкретные IP пользователей (они зашифрованы в merkle root).
  • Страну/время подключения отдельного пользователя.

Чтобы доказать что конкретный IP в множестве — нужен сам IP (известен только владельцу) + полный список (raw unique-ips.txt доступен только под NDA на аудит, не публично).

Запуск проверки

bash scripts/verify-transparency.sh

Скрипт:

  1. Скачивает https://montana.quest/vpn/transparency.json.
  2. Проверяет ed25519-подпись с известного EXPECTED_PUBKEY.
  3. Скачивает https://montana.quest/vpn/transparency-log.txt.
  4. Проверяет монотонность роста за последние 50 снимков.
  5. Выводит зелёные галки и текущее число.

Ограничения текущей реализации

  1. Anti-tamper только в пределах подписи. Атакующий с доступом к privateKey может выдавать любое число. Защита: ключ 600 root + сервер изолирован.
  2. Нет on-chain anchor. При желании можно anchored daily snapshot в Bitcoin через OpenTimestamps — это даст proof что snapshot существовал не позднее timestamp'а в чейне. Roadmap.
  3. IP = пользователь — приближение. Один человек с двух IP считается как 2; несколько человек за одним NAT-IP считаются как 1. Это верхняя оценка уникальных для NAT и нижняя для multi-device. Точнее без trackable user-ID (что = приватность ↓).
  4. Уязвимость к ротации файла. Если unique-ips.txt корраптится — счётчик откатывается. Защита: append-only лог сохраняет историю.

Полный список секретов

  • /etc/montana/transparency-privkey (Moscow, 600 root) — ed25519 приватный ключ подписи.
  • Только этот хост может подписывать. При компрометации — генерация нового keypair, обновление публичного ключа в репо + публикация incident notice.

Roadmap

  • P1: Bitcoin OpenTimestamps anchoring каждый день в 00:00 UTC.
  • P2: Migration на cryptographic accumulator (RSA / Merkle tree) для proof-of-membership без раскрытия списка.
  • P3: Multi-party signing (2 of 3 узлов подписывают) — устраняет single point of trust на Moscow privateKey.