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

Що було протестовано →

Деякі частини цієї сторінки досі залишаються англійською мовою: англійський оригінал зазнав змін після перекладу.

Довідка / Налаштування

Phala / Intel TDX · Розгортання з високим рівнем безпеки

Захищений сервер, що працює цілодобово без вихідних, на 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, токени тільки для читання → ЗIP-архів доказівОператорVerifier, токени тількидля читанняСервер, брандмауер безправил вхідного трафікуЖурнал провайдера табрандмауерАдреса тунельногоконнектора та вхіднийтрафікПідписана заява/api/assuranceЗIP-архів доказівТунель і DNSКлюч підпису, створений насерверіAPI-інтерфейс провайдераAPI Cloudflareтільки вихідні повідомлення
Діаграма у вигляді тексту
  1. Оператор → Сервер, брандмауер без правил вхідного трафіку (API-інтерфейс провайдера)
  2. Оператор → Тунель і DNS (API Cloudflare)
  3. Сервер, брандмауер без правил вхідного трафіку → Тунель і DNS (тільки вихідні повідомлення)
  4. Сервер, брандмауер без правил вхідного трафіку → Ключ підпису, створений на сервері
  5. Verifier, токени тільки для читання → Журнал провайдера та брандмауер
  6. Verifier, токени тільки для читання → Адреса тунельного коннектора та вхідний трафік
  7. Verifier, токени тільки для читання → Підписана заява /api/assurance
  8. Verifier, токени тільки для читання → ЗIP-архів доказів
На цій сторінці

Що може перевіряти верифікатор#

Заява Як це перевіряється Веде
Сервер було створено за допомогою 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 немає немає none: самозасвідчений –

Для кожної справи використовуйте окремий проєкт, команду, обліковий запис або підобліковий запис: тоді доступ верифікатора «тільки для читання» показуватиме лише це розгортання. Повноваження зчитуються з --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 Root CA, порівнюючи його зі списками відкликаних сертифікатів 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). Ця організація вказана як кваліфікована служба маркування часом зі статусом «надано» у бельгійському списку довірених суб’єктів ЄС; кореневий сертифікат (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, її ідентифікатор облікового запису та токен 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 всередині каталогу даних. Панель надає доступ до цього лише головному адміністратору через пряме з’єднання з петлею зворотного зв’язку (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 та «Знайти поточну адресу» приймають лише підписані публікації, тому підроблена публікація не може перенаправити вас та ваш токен панелі на чужу адресу. Тема міститься у записі та опублікованому 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 Instance Connect та відкриття брандмауера — не проходять перевірку; дії з живленням та все непередбачуване позначаються для перевірки. Невідома дія ніколи не проходить непоміченою.

Звіт про передачу доказів#

--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 One на сервері — вихідний брандмауер, що пропускає лише трафік через Cloudflare кожен з’єднання, встановлене сервером, а не лише DNS ще не створено
Доступ перед панеллю хто та коли увійшов до панелі не реалізовано: потрібно мати власний домен
Реєстрація SSH-команд кожна команда в сеансі налагодження ще не створено

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

Без плану «Zero Trust» обліковий запис має одне DNS-розташування. Коли Cloudflare відхиляє інше, сервер використовує існуюче, а його запити розрізняються за адресою; цей фільтр також потребує доступу до персональних даних за принципом «Zero Trust», і destroy залишає спільне розташування. Один запит до журналу охоплює не більше трьох годин, тому копіювання та verify читання даних за день у тригодинних вікнах.

DNS-шлюз охоплює системний резолвер. DNS через HTTPS на порту 443 до іншого резолвера, а також з’єднання з адресами, які ніде не шукаються (наприклад, у дата-центрах Telegram), не фіксуються у його журналі.

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

Перегляд результатів розгортання#

Для звичайної віртуальної машини провайдер контролює інфраструктуру хоста, а локальний інвентар перевіряється разом із записами провайдера. Для Intel TDX верифікатор додатково перевіряє характеристики апаратного забезпечення, прив’язку колектора, компоновку та вимірювання ОС. Ознайомтеся з окремими результатами, щоб дізнатися, які перевірки пройшли успішно або були недоступні.

Історія налаштувань брандмауера залежить від провайдера; Linode зберігає версії правил. Запис Validation містить перелік протестованих розгортань та решти активних перевірок, а Verification scope пов’язує ці перевірки середовища з отриманням архівів та їхньою цілісністю.