TgWitness / Документация

Что проверено →

Часть страницы пока на английском: английский оригинал изменился после перевода.

Справочник / Установка

Phala и Intel TDX: аттестация сборщика Telegram

Защищённый сервер, работающий круглосуточно на Hetzner или Phala Cloud, шлюзовой DNS и проверки, которые может повторить любая третья сторона.

TgWitness / Документация · Развертывание и восстановление

Развертывание и восстановление

Развертывание с высоким уровнем надежности добавляет независимые проверки среды сбора данных к проверке архива. Рецензент запрашивает записи о развертывании и доступе, хранящиеся у поставщика облачных услуг и Cloudflare, а развертывание с использованием Intel TDX добавляет аппаратную аттестацию среды сборщика данных.

Обычное использование локальной среды и Docker остаётся без изменений. Ничто здесь не запускается, пока вы не выполните развёртывание с помощью python -m tgwitness.cloud, а сборщик считывает данные с хоста только тогда, когда развертывание устанавливает TGWITNESS_ASSURANCE.

Блок-схемаОператор → Сервер, брандмауэр без правил входящего трафика (API провайдера); Оператор → Туннель и DNS (API Cloudflare); Сервер, брандмауэр без правил входящего трафика → Туннель и DNS (только исходящие сообщения); Сервер, брандмауэр без правил входящего трафика → Ключ подписи, созданный на сервере; Verifier, токены только для чтения → Журнал провайдера и брандмауэр; Verifier, токены только для чтения → Адрес туннельного коннектора и входной трафик; Verifier, токены только для чтения → Подписанное заявление /api/assurance; Verifier, токены только для чтения → Архив доказательств в формате ZIPОператорVerifier, токены толькодля чтенияСервер, брандмауэр безправил входящего трафикаЖурнал провайдера ибрандмауэрАдрес туннельногоконнектора и входнойтрафикПодписанное заявление/api/assuranceАрхив доказательств вформате ZIPТуннель и DNSКлюч подписи, созданный насервереAPI провайдераAPI Cloudflareтолько исходящие сообщения
Схема в текстовом формате
  1. Оператор → Сервер, брандмауэр без правил входящего трафика (API провайдера)
  2. Оператор → Туннель и DNS (API Cloudflare)
  3. Сервер, брандмауэр без правил входящего трафика → Туннель и DNS (только исходящие сообщения)
  4. Сервер, брандмауэр без правил входящего трафика → Ключ подписи, созданный на сервере
  5. Verifier, токены только для чтения → Журнал провайдера и брандмауэр
  6. Verifier, токены только для чтения → Адрес туннельного коннектора и входной трафик
  7. Verifier, токены только для чтения → Подписанное заявление /api/assurance
  8. Verifier, токены только для чтения → Архив доказательств в формате ZIP
На этой странице

Что может проверить верификатор#

Заявление Как это проверяется Ведёт
Сервер был создан с помощью API провайдера в известный момент времени Объект «Сервер» и его создание в собственном журнале провайдера Провайдер
Никто не использовал пути доступа провайдера Журнал консольных запросов, восстановление, сброс пароля, перекомпиляция, ISO, образы, резервные копии Провайдер
Ничто не смогло подключиться к нему В брандмауэре провайдера отсутствуют правила входящего трафика; SSH скрывается с момента первой загрузки Провайдер (брандмауэр), хост (SSH)
Доступ к панели осуществляется только через туннель Входящий трафик через туннель перенаправляется исключительно на панель; коннектор запускается с адреса сервера Cloudflare
Именно это программное обеспечение работает Подписанный хеш дерева исходного кода коллектора совпадает с хэшем коммита, развернутого в производственной среде. Collector, сверка с Git
Ключ подписи был создан на этом сервере Ключ подписывает заявление, в котором указываются идентификатор сервера провайдера и хеш полученного им файла cloud-init. Collector, проверенный провайдером
Журнал принадлежит этому ключу и серверу Каждый запуск процесса в доказательстве ZIP содержит показатели хоста для данного сервера Доказательства ZIP

Коллектор записывает состояние SSH, сеансы, историю входа в систему и информацию о загрузке в подписанные записи process-start и host.state. На обычной виртуальной машине это локальные инвентарные записи, которые эксперт сравнивает с независимыми записями провайдера. Приведенное ниже развертывание Intel TDX дополнительно проверяет измерения, основанные на аппаратных средствах.

Провайдеры#

--provider Учетные данные Доступ Verifier только для чтения Журнал провайдера для верификатора Хранится для
hetzner HCLOUD_TOKEN Прочитать токен того же проекта Действия сервера и брандмауэра Пока эти ресурсы существуют
digitalocean DIGITALOCEAN_TOKEN Личный токен доступа только для чтения Действия Droplet Пока Droplet существует
linode LINODE_TOKEN linodes, firewall, events области, доступные только для чтения События учетной записи, версии правил брандмауэра 90 дней
vultr VULTR_API_KEY Пользователь с доступом на чтение и activity_logs разрешением Журнал активности аккаунта (метод, путь, участник) 30 дней, а с подпиской на журнал аудита — дольше
aws AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY ec2:DescribeInstances, ec2:DescribeSecurityGroups, cloudtrail:LookupEvents История событий CloudTrail 90 дней
phala PHALA_CLOUD_API_KEY API-ключ того же рабочего пространства Версии приложений и операции с CVM: изменения конфигурации и среды Docker Compose, перезапуски, обновления ОС Пока приложение существует
generic нет нет нет: самоподтверждённый –

Используйте отдельный проект, команду, аккаунт или субаккаунт для каждого дела: тогда у верификатора будет доступ только для чтения, и он увидит только эту развертку. Учетные данные считываются из --provider-token-file или из указанной выше переменной, но ни в коем случае не из командной строки. Для AWS в файле указывается ACCESS_KEY_ID SECRET_ACCESS_KEY [SESSION_TOKEN]; регион — --location.

В каждом отчёте указывается, какую информацию не могут отобразить записи каждого провайдера. Короче говоря: Hetzner регистрирует запросы консоли; консоль восстановления DigitalOcean, Lish/Glish от Linode и веб- консоль Vultr не регистрируются как таковые, поэтому доступ root блокируется при первой загрузке, и для входа в консоль требуется сброс пароля или изменение параметров загрузки, которые регистрируются. Vultr возвращает адрес консоли при нажатии любой клавиши, позволяющей прочитать данные инстанса; ни в записи, ни в отчёте он не сохраняется.

Конфиденциальная виртуальная машина на Phala Cloud (Intel TDX)#

При этом --provider phala коллектор работает в конфиденциальной виртуальной машине Intel TDX на Phala Cloud, управляемой dstack. Хост и сотрудники Phala не могут читать её память, а процессор подписывает подтверждение того, что именно загрузила машина. Верификатор не доверяет Phala на слово: tgwitness.tdx самостоятельно проверяет каждое подтверждение, вплоть до закрепленного корневого центра сертификации Intel SGX, по спискам отзывов Intel и подписанным Intel данным о платформе, и отклоняет машины, которые могут быть отлажены или перенесены.

Запись отчёта Что здесь показано
tdx_binding Аттестация охватывает подписанное заявление сборщика и случайное значение данного запроса.
tdx_quote Intel подтверждает достоверность аттестации; она считается пройденной только в том случае, если Intel оценивает платформу как актуальную.
tdx_compose_hash RTMR3, воспроизводимый из журнала событий dstack, измеряет количество сообщений, составленных в приложении, о которых сообщает сборщик данных.
tdx_compose Этот код байт за байтом соответствует коду, скомпилированному из развернутого коммита: исходные файлы закреплены по хешу, оба изображения — по дайджесту, другого кода нет
tdx_identity Аттестация поступает от развернутого приложения и экземпляра с использованием ключей из KMS Phala и зашифрованного диска.
tdx_os Значения MRTD и RTMR0-2 соответствуют значениям, рассчитанным верификатором на основе образа ОС dstack, публикуемого Dstack-TEE, определённого по хешу образа ОС, сообщаемому CVM, а также на основе таблиц ACPI, формируемых QEMU для конфигурации виртуальной машины: прошивка, ядро, initrd, командная строка с хешем корневой файловой системы, память, виртуальные процессоры и устройства. Образ для разработки не проходит проверку

The OS image (about 180 MB, of which 21 MB are kept) is downloaded once from Dstack-TEE/meta-dstack into dstack-images beside the record; --tdx-image FOLDER uses another folder or an unpacked image, --tdx-image none skips the comparison. The measurement follows dstack-mr and the qemu-acpi crate of Dstack-TEE/dstack. Private measurement regressions compare QEMU's own ACPI output and a retained Phala Cloud quote; live qualification also needs the published image. --tdx-measurements still compares MRTD and RTMR0-2 given as JSON instead.

Каждый запуск коллектора, зафиксированный в журнале, сопровождается таким подтверждением, поэтому verify --evidence проверяет каждый запуск и образ ОС, с которого он был загружен. Ревизии приложений Phala и операции CVM служат в качестве журнала поставщика: изменение конфигурации Docker Compose после развертывания приводит к отклонению отчета, а перезапуски фиксируются для последующего анализа.

В панели выберите «Конфиденциальная виртуальная машина · Phala Cloud» в разделе «Дополнительно» → «Сервер 24/7» и вставьте ключ API Phala Cloud; быстрый туннель работает так же, как на Hetzner. Из командной строки:

python -m tgwitness.cloud deploy --provider phala --name case-1 --server-type tdx.small \
    --ref v0.8.0 --repository https://github.com/phishdestroy/TgWitness --quick-tunnel \
    --provider-token-file phala-key.txt
python -m tgwitness.cloud verify --record deployments/case-1/deployment.json \
    --provider-token-file phala-key.txt --cloud-init deployments/case-1/docker-compose.yaml \
    --source CHECKOUT_OF_COMMIT --fingerprint COLLECTOR_FINGERPRINT --report certificate.md
python -m tgwitness.cloud check-report --report certificate.pdf --verifier-fingerprint VERIFIER_KEY

--tdx-collateral считывает сертификаты и списки отзывов Intel из файла, а не загружает их с сайта Intel. Шлюз DNS здесь недоступен: у Phala нет провайдерского брандмауэра для исходящего трафика.

Сертификат аттестации#

При развёртывании Phala verify --report certificate.md также записывает сертификат: автономный файл certificate.html и файл формата A4 certificate.pdf, содержащий заключение, цепочку доверия от корневого сертификата Intel до ключа сборщика, сравнение с обычными серверами и серверами повышенной надёжности, результаты измерений рядом со значениями, рассчитанными на основе опубликованного образа, информацию о том, кто ручается за каждую часть, цепочку сертификатов Intel, все проверки, журнал поставщика, а также инструкции по повторению проверки. Отчёт в формате JSON остаётся авторитетным документом; страницы отображают его содержимое.

Отчёт заверяется цифровой печатью; данные заверения находятся в certificate.seal.json и соседних файлах .tsq/.tsr:

Печать Что это добавляет
Квалифицированная электронная временная метка, http://tsa.belgium.be/connect Метка времени RFC 3161 для точной последовательности байтов certificate.json, выданная квалифицированным поставщиком доверенных услуг федерального правительства Бельгии (FPS Policy and Support, BOSA). Его подразделение включено в бельгийский доверенный список ЕС как квалифицированная служба меток времени со статусом granted; корневой сертификат (Belgium Root CA6) и записи списка по состоянию на выпуск от 20 октября 2026 года закреплены в tgwitness/tsa_roots.py. Согласно статье 41 Регламента (ЕС) № 910/2014 такая метка времени пользуется презумпцией точности даты и времени и целостности связанных данных во всех государствах — членах ЕС
Метка времени по RFC 3161, FreeTSA Вторая, независимая отметка времени
Подпись верификатора Ed25519 над текстом, содержащим SHA-256 отчёта и каждую метку времени, с использованием собственного ключа верификатора (--sign-with FOLDER, по умолчанию ~/.tgwitness/verifier); PDF-файл содержит подпись, сгенерированную тем же ключом

--timestamp URL (повторяемый) выбирает другие центры сертификации, --timestamp none — ни один, --sign-with none оставляет печать неподписанной. check-report проверяет хеш отчёта, подпись верификатора, каждую временную метку относительно доверенного корня и её квалифицированный статус, а также подпись PDF-файла. Юридическая сила квалифицированной временной метки за пределами ЕС, а также отчёта в целом, определяется судом или органом власти, получающим данный документ; печать подтверждает момент создания отчёта и отсутствие в нём изменений.

Аттестация не может исключить наличие уязвимости в модуле TDX или микрокоде Intel, а также физический доступ к шине памяти. Тот, кто контролирует приложение в аккаунте Phala, может развернуть другой компоуз; он отображается как новая ревизия с новым хешем компоуза. Хост контролирует источник времени машины и сеть.

Развёртывание, проверка с --evidence, перезапуски, сравнение образа ОС, заверение сертификата и удаление проверены непосредственно на Phala Cloud; см. прогон от 4 ноября 2026 года.

Прежде чем начать#

  1. Зона Cloudflare, её ID учётной записи и токен API с правами Cloudflare Tunnel Edit, Zone Read и DNS Edit, указанные с помощью --cloudflare-token-file или CLOUDFLARE_API_TOKEN. Для верификатора: права Cloudflare Tunnel Read, DNS Read и, для журнала аудита, Account Settings Read. Без домена для быстрого туннеля ничего из этого не требуется.
  2. Учетные данные провайдера с правом записи в выделенный проект; lock использует то же самое:
    • Hetzner: токен API с правами на чтение и запись;
    • DigitalOcean: личный токен доступа с правом записи;
    • Linode: личный токен доступа с linodes, firewall и events областями доступа «чтение/запись»;
    • Vultr: ключ API выделенного аккаунта или суб-аккаунта;
    • AWS: разрешены учетные данные IAM ec2:DescribeVpcs, ec2:DescribeImages, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:RunInstances, ec2:CreateTags, ec2:DescribeInstances, ec2:DescribeSecurityGroupRules и ec2:RevokeSecurityGroupIngress.
  3. Кит, который нужно запустить. Тег релиза однократно сопоставляется с соответствующим китом с помощью git ls-remote; сервер всегда получает только 40-символьный коммит.

Из панели#

На вашем компьютере в меню «Дополнительно» → «Сервер 24/7» запускается то же самое deploy для Hetzner в три шага: выберите Европу или США, вставьте токен Hetzner (чтение и запись), затем проверьте тип сервера, месячную стоимость, адрес и версию, которые панель нашла по этому токену. Ничего не создается до вашего подтверждения. Панель отображает каждый шаг в виде deploy по мере их появления, а затем — адрес, токен панели и отпечаток ключа подписи. Без домена сервер получает быстрый туннель ; в разделе «Ваши серверы» → «Найти текущий адрес» он запрашивается заново после перезапуска. Для фиксированного адреса под вашим собственным доменом откройте «Дополнительно» · «Ваш собственный домен » и добавьте токен Cloudflare (подготовленная ссылка выбирает «Зона чтения», «Редактирование DNS» и «Редактирование туннеля Cloudflare»).

Токены передаются с каждым запросом из вкладки браузера на TgWitness на том же компьютере и никуда не записываются; запись развертывания, отредактированный файл cloud-init, токен панели и, для быстрого туннеля, ключ адреса хранятся в deployments/NAME внутри каталога данных. Панель предоставляет доступ к этому только главному администратору по прямому loopback-соединению (127.0.0.1без прокси или заголовков туннеля); панель, доступ к которой осуществляется через сеть, вместо этого отображает команды . По умолчанию версия соответствует тегу релиза запущенной панели, определяемому через API GitHub. Местоположение, тип сервера и цена получаются из API Hetzner: cpx22 если он предлагается, в противном случае — самый дешёвый тип x86 с объёмом памяти не менее 2 ГБ.

Быстрый туннель без домена#

--quick-tunnel заменяет --zone, --cloudflare-account и --panel-host; при этом не используется ни учётная запись Cloudflare, ни токен:

python -m tgwitness.cloud deploy --provider hetzner --name case-2026-11 --server-type cpx22 \
    --ref 0123456789abcdef0123456789abcdef01234567 --quick-tunnel --provider-token-file hetzner.token

На сервере cloudflared открывает быстрый туннель к панели: случайный https://….trycloudflare.com адрес, который меняется при каждой перезапуске cloudflared или сервера. Небольшой сервис на сервере публикует каждый адрес в случайной теме ntfy.sh , подписав его (HMAC-SHA256) ключом, хранящимся только в каталоге развёртки (address-key.txt), и повторяет это каждые три часа, поскольку ntfy.sh хранит сообщения в течение 12. deploy и Find текущий адрес принимают только подписанные сообщения, поэтому поддельное сообщение не сможет направить вас и ваш токен панели на чужой адрес. Тема находится в записи и в опубликованном cloud-init: любой, у кого они есть, может прочитать текущий адрес, который по-прежнему запрашивает токен панели. Сервер не открывает входящий порт ни в том, ни в другом случае.

Верификатор не имеет ключа адреса, и любой, кто читает тему, может публиковать в ней сообщения. Поэтому коллектор также публикует сам адрес, подписанный собственным ключом Ed25519, а verify берет самое новое сообщение, подписанное ключом коллектора в записи развертывания; сообщения упорядочиваются по времени их получения ntfy.sh, а не по времени, указанному в них. Коллектор, созданный до введения данного изменения, ничего не подписывает, и verify затем берет самое новое сообщение и указывает это в проверке statement; поддельное сообщение может только привести к сбою этой проверки, поскольку адрес по-прежнему должен отвечать ключом коллектора.

Ограничения: быстрый туннель не привязан к учётной записи Cloudflare, поэтому verify отмечает проверки туннеля, коннектора и DNS как недоступные; лучший возможный результат — incomplete. На Phala Cloud проверка проходит: коннектор работает внутри конфигурации Docker Compose, включённой в измерения. Записи провайдера, брандмауэр, подписанное заявление, измерения хоста и сравнение установщиков проверяются как обычно. Для побайтового сравнения с эталонным установщиком нужен развёрнутый коммит с поддержкой --quick-tunnel; при проверке версии 0.7.0 собирается установщик для домена и обнаруживаются различия. Cloudflare не гарантирует доступность быстрых туннелей, ограничивает очередь 200 запросами и не передаёт Server-Sent Events. Поэтому обновления панели в реальном времени (после 0.7.0) могут не проходить через такой туннель, и страницу придётся перезагружать; эта часть ещё не проверялась. Для постоянной работы используйте собственный домен.

Развертывание#

Сначала просмотрите всё, что будет отправлено. plan не отправляет запросов ни провайдеру, ни Cloudflare:

python -m tgwitness.cloud plan --provider hetzner --name case-2026-11 --server-type cpx22 \
    --ref 0123456789abcdef0123456789abcdef01234567 --zone example.org \
    --cloudflare-account CLOUDFLARE_ACCOUNT_ID --panel-host case.example.org

Затем выполните развертывание с теми же параметрами и учетными данными:

python -m tgwitness.cloud deploy --provider hetzner --name case-2026-11 --server-type cpx22 \
    --ref 0123456789abcdef0123456789abcdef01234567 --zone example.org \
    --cloudflare-account CLOUDFLARE_ACCOUNT_ID --panel-host case.example.org \
    --witness-host case-witness.example.org \
    --provider-token-file hetzner.token --cloudflare-token-file cloudflare.token

Типы серверов для начала: cpx22 (Hetzner), s-1vcpu-2gb (DigitalOcean), g6-standard-1 (Linode), vc2-1c-2gb (Vultr), t3.small (AWS). --location и --image по умолчанию для каждого провайдера — Ubuntu 24.04 в европейском регионе.

--repository принимает коммит из другого репозитория Git по протоколу https без указания учетных данных в URL (по умолчанию https://github.com/phishdestroy/TgWitness.git). deploy также принимает --out для другого каталога развертывания (по умолчанию deployments/NAME; каталог, в котором уже находится развертывание, отклоняется) и --wait, количество минут ожидания подписанного отчета сборщика: от 1 до 240, по умолчанию 20 или 60 для generic.

Команда:

  1. создаёт туннель Cloudflare, входящий трафик которого перенаправляет имя хоста панели на саму панель и, если указано, имя хоста свидетеля на /api/witness/head и /api/assurance только;
  2. создаёт проксированные записи CNAME для этих имён хостов, отклоняя имена, которые уже существуют;
  3. создаёт брандмауэр провайдера без правил входящего трафика и сервер за ним без SSH-ключа, без резервных копий, без консольного агента и с cloud-init, который маскирует SSH, блокирует root, устанавливает cloudflared, загружает именно этот коммит, проверяет его и запускает TgWitness в качестве защищённого сервиса systemd;
  4. ожидает подписанного заявления сборщика и проверяет, указаны ли в нём этот сервер и хэш данного файла cloud-init.

deployments/case-2026-11/ затем содержит:

Файл Содержание Поделиться?
deployment.json Идентификаторы, хеши, выполненные вызовы API (метод, путь, статус) и первое подписанное утверждение Да, с помощью верификатора
cloud-init.redacted.yaml Точный файл cloud-init, в котором два секрета заменены на REDACTED Да
panel-token.txt Токен панели Нет

Корневой пароль провайдера, токен туннеля и токен панели никогда не записываются deployment.json. Опубликуйте отпечаток коллектора, указанный в конце, через канал, которым вы не управляете в одиночку, например, через канал свидетеля или в сообщении получателю.

Войдите в Telegram по адресу https://case.example.org с помощью токена панели, как описано в руководстве по работе с аккаунтами. Действия панели записываются в подписанный журнал; они не являются SSH-сессиями. Свидетель может опрашивать https://case-witness.example.org.

SSH отсутствует: если начальная инициализация завершится сбоем, коллектор никогда не ответит. Удалите сервер и разверните его заново или воспользуйтесь отладочным развертыванием, чтобы найти причину.

Секреты в пользовательских данных#

Cloud-init хранит два секрета: токен панели и токен туннеля Cloudflare. Ключ подписи среди них нет; он создаётся на сервере. Hetzner, DigitalOcean и Linode не возвращают пользовательские данные через свои API. Vultr возвращает их любому ключу, который может читать инстанс, а EC2 — через DescribeInstanceAttribute. Для AWS предоставляйте верификатору только три действия из таблицы, ни в коем случае ec2:Describe*. Для Vultr следует предположить, что ключ верификатора может читать оба токена. Токен туннеля позволяет кому-либо запустить второй коннектор: verify сообщает о любом коннекторе, не находящемся на сервере, и заявления коллектора нельзя подделать таким образом, поскольку каждый из них подписывает новый челлендж. При использовании --quick-tunnel вторым секретом является ключ адреса: кто бы ни прочитал его, может опубликовать ложный адрес, который панель примет.

В публичном заявлении сборщика не указываются адрес сервера и источники логинов; оба эти элемента остаются в подписанном журнале.

Отладка развертывания и блокировка#

--debug-ssh-key KEY --debug-ssh-from 198.51.100.4 поддерживает SSH для одного ключа с одного адреса или небольшой сети, максимум /24 для IPv4 или /48 для IPv6. KEY уже зарегистрирован у провайдера: имя или ID SSH-ключа в проекте Hetzner, ID или отпечаток SSH-ключа в команде DigitalOcean, имя пользователя Linode, SSH-ключи которого добавлены в профиль root, ID SSH-ключа в учётной записи Vultr или имя пары ключей EC2 в регионе. Эти параметры не применяются к generic. Такое развертывание регистрируется как debug и никогда не отмечается как «высокого уровня безопасности». По завершении выполните sudo tgwitness-lock в качестве последней команды последнего сеанса SSH, а затем:

python -m tgwitness.cloud lock --record deployments/case-2026-11/deployment.json --provider-token-file hetzner.token

Брандмауэр теряет все правила входящего трафика. Затем в отчётах отображается, когда SSH был разрешён, а когда был закрыт; это окно остаётся видимым.

Удалить развёртку#

destroy Удаляет сервер и его брандмауэр, найденные по метке развертывания, так что развертывание, завершившееся сбоем на полпути, также удаляется, а затем — записи DNS, указывающие на его туннель, и сам туннель. Журнал сервера и ключ подписи удаляются вместе с ним: сначала экспортируйте доказательства. Запись сохраняется, помеченная removed, с указанием вызовов API, связанных с удалением.

python -m tgwitness.cloud destroy --record deployments/case-2026-11/deployment.json --confirm case-2026-11 \
    --provider-token-file hetzner.token --cloudflare-token-file cloudflare.token

Удаление через API реализовано для Hetzner. Для других провайдеров destroy процесс останавливается перед удалением и указывает метку для удаления в консоли провайдера. Ручно установленный сервер (generic) теряет только свои записи туннеля и DNS. Для быстрого развертывания туннеля не требуется токен Cloudflare: его туннель заканчивается на сервере, а его сообщения удаляются из ntfy.sh в течение 12 часов.

Любой сервер (с самоподписью)#

--provider generic предназначено для сервера, приобретённого или установленного вручную. deploy создаёт туннель и DNS, записывает install.sh (частный) и install.redacted.sh (для публикации), а затем ожидает. Скопируйте install.sh на свежеустановленный сервер Ubuntu 24.04 и запустите его там:

sudo bash install.sh

Он фиксирует состояние хоста в том виде, в каком он был (логины, аккаунты, authorized_keys, сокеты прослушивания, сервисы, запланированные задания, пакеты), устанавливает коммит, включает брандмауэр хоста, удаляет себя, маскирует SSH и завершает сессию. Отчёт по такому серверу в лучшем случае является САМОУДОСТОВЕРЕННЫМ: тот, кто запустил установщик, имел права root до этого, и у проверяющего нет доступа к записям провайдера. Это всё же лучше, чем необъяснимый сервер: инвентарь, хэш установщика и каждый последующий вход в систему подписаны.

Проверить#

Верификатору потребуются deployment.jsonопубликованный установщик, учетные данные только для чтения и, в идеале, выгрузку коммита и доказательство ZIP:

git clone -c core.autocrlf=false https://github.com/phishdestroy/TgWitness.git checkout
git -C checkout checkout 0123456789abcdef0123456789abcdef01234567
python -m tgwitness.cloud verify --record deployment.json \
    --provider-token-file read-only.token --cloudflare-token-file cloudflare-read.token \
    --fingerprint COLLECTOR_FINGERPRINT --cloud-init cloud-init.redacted.yaml \
    --source checkout --evidence tgwitness-evidence.zip --report report.md

В момент проверки верификатор запрашивает все данные у провайдера и Cloudflare; запись предоставляет только идентификаторы, по которым необходимо запросить информацию. Код завершения равен 0 для PASS, 1 для FAIL и 2 для REVIEW, INCOMPLETE или SELF-ATTESTED. --fingerprint должно поступать из независимого канала; без него ключ сравнивается только с записью оператора. python verify.py по-прежнему проверяет само доказательство ZIP, как описано в разделе «Доказательства».

Действия провайдера классифицируются: создание и запуск в течение 30 минут после создания проходят успешно; консоль, восстановление, сброс пароля, пересборка, ISO, образы, снимки, резервные копии, Systems Manager, подключение к экземпляру EC2 и открытие портов брандмауэра завершаются сбоем; действия, связанные с питанием, и всё неожиданное помечаются для проверки. Неизвестное действие никогда не проходит незаметно.

Отчёт о передаче доказательств#

--report report.md создаёт отчёт в формате Markdown и report.json рядом с ним:

  1. результат, отпечаток ключа коллектора, развёртывание, провайдер, фиксация, сервер, брандмауэр, туннель;
  2. каждая проверка с указанием её статуса и источника (API провайдера, API Cloudflare, отчёт сборщика, журнал доказательств);
  3. журнал провайдера с оценкой каждого действия и, если провайдер это фиксирует, с указанием исполнителя;
  4. конечные точки Cloudflare, хранящие соединения туннеля, конфигурацию и журнал аудита;
  5. подписанное заявление сборщика;
  6. что подтверждает отчёт, а что нет;
  7. команды для воспроизведения результата, а также SHA-256 каждого предоставленного файла.

Передайте отчет, report.json, deployment.json, опубликованный установщик и доказательства ZIP. Подготовьте отчет заранее: журналы провайдеров хранятся в течение ограниченного времени.

Cloudflare в качестве внешнего свидетеля#

Здесь всё необязательно. Без учётной записи Cloudflare сервер всё равно работает, и два из них работают уже сегодня:

Что Что здесь показано В TgWitness
Быстрый туннель или туннель вашего домена Доступ к панели осуществляется только через туннель Мастер настройки сервера, см. выше
ретранслятор drand drand.cloudflare.com записи, сделанные после раунда drand, более поздние, чем эта: дневник велся по ходу событий режим «доказательства», «Дополнительные свидетели», «без аккаунта» (формат)
Уведомления о состоянии туннеля когда туннель не работал, по электронной почте или через веб-хук от Cloudflare Настройте их в панели управления Cloudflare
DNS-шлюз (--gateway-dnsили Cloudflare Gateway DNS в мастере) каждое имя, запрос на которое обращался сервер, на который Cloudflare отвечал по протоколу TLS; брандмауэр Hetzner не пропускает DNS-запросы никуда больше; может ли политика шлюза переписать ответы Hetzner, бесплатный тарифный план Zero Trust, без домена; verify проверяет брандмауэр, местоположение, ведение журналов, политики, запросы сервера и журнал аудита; режим «evidence» копирует журнал в дневник
Шлюз с Cloudflare: один клиент на сервере, брандмауэр исходящего трафика, пропускающий только Cloudflare каждое соединение, установленное сервером, а не только DNS ещё не реализовано
Доступ перед панелью кто и когда вошёл в панель не реализовано: требуется собственный домен
Регистрация SSH-команд каждая команда в сеансе отладки ещё не реализовано

Logpush, который позволяет хранить собственную копию Cloudflare в R2, является функцией Enterprise: на бесплатном тарифном плане Cloudflare отвечает logpush is not enabled for this account. Журнал шлюза хранится там 24 часа, поэтому в режиме «доказательства» он копируется в подписанный журнал (журнал Cloudflare Gateway, содержащий DNS-запросы данного сервера, — токен только для чтения с правом «Account Analytics Read»).

Без плана «Zero Trust» у аккаунта есть одно DNS-местоположение. Когда Cloudflare отклоняет другое, сервер использует существующее, и его запросы различаются по адресу; для этого фильтра также требуется «Zero Trust PII Read», и destroy оставляет общее местоположение. Один запрос журнала охватывает не более трёх часов, поэтому копия и verify чтение данных за день в трехчасовых интервалах.

Gateway DNS отвечает за системный резолвер. Запросы DNS через HTTPS по порту 443 к другому резолверу, а также соединения с адресами, по которым поиск не проводится (например, с дата-центрами Telegram), не фиксируются в его журнале.

Cloudflare не имеет доступа к шифрованным данным Telegram, другим устройствам, привязанным к аккаунту Telegram (список устройств в режиме «evidence mode» фиксирует их со стороны Telegram) или гипервизору провайдера.

Как читать результат проверки среды#

В случае обычной виртуальной машины провайдер контролирует инфраструктуру хоста, а локальные ресурсы проверяются наряду с записями провайдера. В случае Intel TDX верификатор дополнительно проверяет характеристики оборудования, привязку коллектора, компоновку и показатели ОС. Ознакомьтесь с отдельными результатами, чтобы увидеть, какие проверки прошли успешно, а какие были недоступны.

Исторические данные о брандмауэре зависят от провайдера; Linode сохраняет версии правил. Запись валидация содержит список протестированных развертываний и оставшихся активных проверок, а область верификации связывает эти проверки среды с получением архива и проверкой его целостности.