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

Canonical page: https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/

Захищений сервер, що працює цілодобово без вихідних, на Hetzner або Phala Cloud, шлюз DNS та перевірки, які може повторити третя сторона.

[Project context and measured scale](https://phishdestroy.github.io/TgWitness/docs/reference/overview/)

[Documentation index](https://phishdestroy.github.io/TgWitness/uk/llms.txt)

Translation coverage: this edition includes material from the English original.

Захищений сервер, що працює цілодобово без вихідних, на Hetzner або Phala Cloud, шлюз DNS та перевірки, які може повторити третя сторона.

[TgWitness](https://github.com/phishdestroy/TgWitness/blob/main/README.md) / [Документація](https://github.com/phishdestroy/TgWitness/blob/main/docs/README.md) · [Розгортання та відновлення](https://phishdestroy.github.io/TgWitness/uk/docs/reference/deployment/)

![Розгортання та відновлення](https://phishdestroy.github.io/TgWitness/assets/chapter-operate.svg)

Розгортання з високим рівнем надійності додає незалежні перевірки середовища збору даних до верифікації архіву. Рецензент запитує записи про розгортання та доступ, що зберігаються у хмарного провайдера та 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-архів доказів

**На цій сторінці**

- [Що може перевірити верифікатор](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#what-a-verifier-can-check)
- [Провайдери](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#providers)
- [Конфіденційна віртуальна машина на Phala Cloud (Intel TDX)](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#confidential-vm-on-phala-cloud-intel-tdx)
- [Перед початком роботи](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#before-you-start)
- [З панелі](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#from-the-panel)
- [Швидкий тунель без домену](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#quick-tunnel-without-a-domain)
- [Розгортання](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#deploy)
- [Налагодження розгортання та блокування](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#debug-deployment-and-lock)
- [Видалити розгортання](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#remove-a-deployment)
- [Будь-який сервер (самосертифікований)](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#any-server-self-attested)
- [Перевірити](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#verify)
- [Звіт про передачу доказів](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#report-for-evidence-handover)
- [Cloudflare як зовнішній свідок](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#cloudflare-as-an-outside-witness)
- [Зчитування результату розгортання](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#reading-the-deployment-result)

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

| Заява | Як це перевіряється | Веде |
| --- | --- | --- |
| Сервер було створено за допомогою 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](https://phala.com/), якою керує 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](https://github.com/Dstack-TEE/meta-dstack/releases) 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 року,](https://phishdestroy.github.io/TgWitness/uk/docs/reference/verification/#live-phala-cloud-deployment--4-november-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**». Без домену [швидкий тунель](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#quick-tunnel-without-a-domain) не потребує нічого з цього.
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` з’являється у звіті, а потім — адресу, токен панелі та відбиток ключа підпису. Без домену сервер отримує [швидкий тунель](https://phishdestroy.github.io/TgWitness/uk/docs/reference/high-assurance/#quick-tunnel-without-a-domain) ; **у розділі «Ваші сервери» → «Знайти поточну адресу»** його можна перевірити знову після перезапуску. Щоб отримати фіксовану адресу під власним доменом, відкрийте **«Додатково» · «Ваш власний домен»** і додайте токен 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://developers.cloudflare.com/tunnel/get-started/quick-tunnels/) до панелі: випадкова `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` за допомогою токена панелі, як зазначено в [посібнику з налаштування облікового запису](https://phishdestroy.github.io/TgWitness/uk/docs/reference/accounts/). Дії панелі записуються у підписаному журналі; це не сесії SSH. [Свідок](https://phishdestroy.github.io/TgWitness/uk/docs/reference/witness/) може запитувати `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, як описано в розділі [«Докази](https://phishdestroy.github.io/TgWitness/uk/docs/reference/evidence/)».

Дії провайдера класифікуються: створення та запуск протягом 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 є новішими за нього: щоденник велося по ходу подій | режим доказів, **більше свідків**, без облікового запису ([формат](https://phishdestroy.github.io/TgWitness/uk/docs/reference/evidence/#optional-records-in-evidence-mode-drand-and-telegram-devices)) |
| Повідомлення про стан тунелю | коли тунель не працював, електронною поштою або через веб-хук від 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](https://phishdestroy.github.io/TgWitness/uk/docs/reference/verification/) містить перелік протестованих розгортань та решти активних перевірок, а [Verification scope](https://phishdestroy.github.io/TgWitness/uk/docs/reference/evidence/#verification-scope) пов’язує ці перевірки середовища з отриманням архівів та їхньою цілісністю.
