Десь у вашому середовищі є скрипт, CI‑ранер або «тимчасова» робоча станція адміністратора з вшитим паролем root Proxmox. Це працює. Це також означає, що одне вкрадене значення може перезапустити продукцію, видалити резервні копії та переналаштувати мережі раніше, ніж охолоне ваша кава на виклику.
API‑токени — це спосіб перестати ставитися до пароля root як до майстер‑ключа, яким усі позичаються. Якщо зробити все правильно, вони будуть обмеженими, відкличними, піддаваними аудитуванню й нудними. Нудність — це ціль.
Що ви насправді захищаєте (і чому паролі постійно підводять)
Proxmox — це не «просто гіпервізор». Це ваша контрольна площина: дії живлення, підключення сховищ, зміни мережі, консолі ВМ, снапшоти, реплікація, резервні копії, правила фаєрвола та ідентичності користувачів. Якщо хтось може звертатися до API Proxmox з широкими повноваженнями, йому не потрібно «ламати» ваші ВМ. Він може стати вашою платформенною командою.
Паролі root підводять у передбачуваний спосіб:
- Вони розповсюджуються. Один пароль стає спільною таємницею між людьми та машинами.
- Вони не сегментують доступ. Неможливо сказати «ця автоматизація може лише увімкнути/вимкнути ці ВМ і читати ці метрики» при використанні пароля.
- Їх важко обертати. Ротація означає ламання скриптів. Люди затягують. Атакувальники — ні.
- Вони розмивають відповідальність. «root зробив це» — не журнал аудиту, це знизування плечима.
API‑токени не виправлять культуру автоматично, але зроблять хорошу поведінку дешевшою за погану. Токени можна обмежувати й обертати без того, щоб люди переписували секрети опівночі. Токени можна створювати під додаток, під конвеєр, під інтеграцію. Токен може померти сам по собі, не втягуючи всю організацію в ланцюжок скидання паролів.
Факти та контекст, які змінюють рішення
Ось конкретні факти — деякі історичні, деякі архітектурні — які мають вплинути на те, як ви проєктуєте доступ до Proxmox:
- Proxmox VE централізує управління через REST API. Веб‑інтерфейс фактично є клієнтом API. Якщо ви можете зробити це в UI, зазвичай можна зробити це й через API — і скрипти це робитимуть.
- API‑токени прив’язані до користувача, а не є незалежною ідентичністю. У Proxmox токени прикріплюються до облікового запису користувача; ваша RBAC‑модель все ще важлива.
- RBAC у Proxmox будується навколо ролей і шляхів ACL. Якщо ви не розумієте скоупінг шляхів (наприклад
/vms/100vs/), ви або зламаєте автоматизацію, або наддадите надто багато прав. - «Найменші привілеї» стали нормою через провали периметрового захисту. Коли мережі перестали бути «надійним внутрішнім середовищем», сфокусовані облікові дані стали єдиним розумним припущенням.
- Credential stuffing — старий, надійний і нудний. Атакувальники повторно використовують влиті паролі, бо це працює. Паролі root особливо повторно використовувані, бо люди повторюють їх у властиво людський спосіб.
- Інцидент‑респонс працює завдяки відкликанню. Ротація паролів повільна; відклик токена — швидкий. Швидкість перемагає під час локалізації.
- Аудит — це можливість, а не формальність для відповідності. Коли ВМ знищено, ви хочете знати «який токен» і «який сервіс», а не «якийсь адміністратор, мабуть».
- Автоматизація збільшує радіус ураження, якщо ви навмисно його не звужуєте. CI‑системи часто працюють із «cluster admin», бо так простіше. Простота — це як відбуваються багатомісні відмови.
Жарт №1: Спільний пароль root — як загальна зубна щітка: технічно працює, морально сумнівно і краще не знати, де вона побувала.
Модель загроз: три реальні атакувальники
Поради з безпеки дивні, коли їх готують проти кіношних лиходіїв. Залишимось операційними. У реальних середовищах доступ до Proxmox зазвичай ламається через одну з цих причин:
1) Доброякісний внутрішній інженер з надлишком доступу
Це не особиста вада; це системна вада. Якщо найпростіший спосіб виправити проблему — використати root, люди використовують root. Результат — випадкова шкода, яка виглядає як злісний намір: видалені диски, неправильне правило фаєрвола, міграція під час обслуговування на невірному вузлі.
2) Скомпрометований рушій автоматизації
Ваш CI‑ранер, GitOps‑агент або «контролер бекапів» — це комп’ютер в мережі або в інтернеті. Він рано чи пізно буде зламаний або неправильно налаштований. Коли це трапиться, питання не «чи він може дістатися до Proxmox», а «що він зможе зробити всередині?»
3) Зовнішній атакувальник, який отримав плацдарм в іншому місці
Більшість атакувальників не починають з Proxmox. Вони починають з пошти, VPN‑облікового запису, ноутбука розробника, веб‑застосунку або залежності постачальника. Потім вони роблять піваюти. Proxmox — хіт: доступ до контрольної площини — найкоротший шлях до стійкості та руйнування.
Ваше завдання — побудувати систему, де компрометація одного токена або одного раннера не дорівнює компрометації кластера.
API‑токени Proxmox: модель, обмеження та підводні камені
API‑токени Proxmox — це облікові дані, які ви створюєте під обліковим записом Proxmox. Їм можна надавати права через ту ж систему RBAC і ACL, що й користувачам. Токени також можна позначати як «privilege separation» (privsep), тобто вони не обов’язково успадковують усе, що має користувач. Цей перемикач — місце, де вирішується більшість питань безпеки.
Токени — не чарівники; RBAC — це чарівність
Якщо ви створюєте токени для root@pam і даєте їм широкі права на кластер, ви нічого не покращили. Ви просто змінили форму проблеми й полегшили ексфільтрацію: токени призначені для використання машинами, тому машини їх зберігатимуть.
Скоуп базується на шляхах, і помилки шляху часті
ACL у Proxmox застосовуються до шляхів, як‑от:
/(на рівні кластера)/nodes/<node>(на рівні вузла)/vms/<vmid>(на рівні ВМ)/storage/<storage-id>(на рівні сховища)/pool/<poolname>(на рівні пулів ресурсів)
Більшість інцидентів «о́пс» виникають через надання прав на /, бо хтось хотів, щоб токен зробив одну задачу і не міг знайти правильний шлях або роль. Отже, вони дали глобальний доступ. Вітаємо — ви щойно створили кнопку відмови.
Життєвий цикл токена важливіший за його створення
Створити токен — легко. Керувати ними — де програми помирають:
- Де зберігаються токени? (секрети CI, Vault, env vars, файли на диску)
- Як часто вони ротуються?
- Як ви виявляєте аномалії використання?
- Як ви відкликаєте їх за хвилини?
Парафразована ідея (Gene Kim): «Покращувати системи — означає скорочувати зворотні зв’язки й робити зміни безпечними для повторення.» Це стосується й ротації облікових даних.
Принципи проєктування: найменші привілеї, що витримують реальність
1) Токени для інтеграцій, а не для команд
Якщо існує «DevOps токен», ви побудували спільну долю. Створюйте токени для кожного інструменту й середовища: terraform-prod, backup-controller, monitoring-readonly, ci-staging. Люди не повинні ділитися токенами; машини теж не повинні їх ділити.
2) Використовуйте «privilege separation», якщо тільки це не явний адміністраторський токен
За замовчуванням токен може успадковувати привілеї користувача (залежно від способу створення). Ви хочете, щоб токен мав лише ті ACL, які ви явно прикріпили. Батьківський користувач може бути адміністратором для аварійного доступу, а токен залишатиметься сфокусованим для автоматизації.
3) Віддавайте перевагу пулам ресурсів, а не розкиданим ACL по ВМ
Надання прав для десятків окремих ВМ — це шлях до «просто дайте /» пізніше. Пули дозволяють групувати ресурси й надавати права на шлях пулу. Ваш майбутній я скаже дякую за менше правок опівночі.
4) Розділяйте обов’язки: провізіювання — не те саме, що операція
Інструменти провізіювання часто потребують прав на створення ВМ, підключення сховищ, встановлення тегів і налаштування мережі. Оператори та системи резервного копіювання потребують інших прав. Не упаковуйте все разом, бо це «один конвеєр». Конвеєри — не ідентичності.
5) Будуйте для відпрацювання відкликання
Відкликання — це не лише аварійна дія. Відпрацьовуйте його. Ви повинні вміти відкликати токен і спостерігати керований збій залежної системи з чистим повідомленням про помилку та планом відкату.
6) Проєктуйте проти найпоширенішого режиму помилки: хтось дає забагато прав
Ускладнюйте надмірне надання прав:
- Обмежте, хто може редагувати ACL на
/. - Тримайте невелику кількість заздалегідь визначених ролей (і переглядайте їх).
- Потребуйте контроль змін для прав на рівні кластера.
Жарт №2: «Тимчасовий доступ адміністратора» має такий самий термін життя, як пластикова торбинка в океані.
Практичні завдання (команди, вивід і рішення)
Нижче — практичні завдання, які ви можете виконати на вузлі Proxmox або через CLI. Кожне містить пояснення, що означає вивід, і рішення, яке треба ухвалити. Мета — операційна ясність, а не галочка у списку завдань з безпеки.
Завдання 1: Підтвердити стан кластера перед зміною автентифікації
cr0x@server:~$ pvecm status
Cluster information
-------------------
Name: prod-pve
Config Version: 17
Transport: knet
Secure auth: on
Quorum information
------------------
Date: Tue Feb 4 11:12:21 2026
Quorum provider: corosync_votequorum
Nodes: 3
Node ID: 0x00000001
Ring ID: 1.24
Quorate: Yes
Що це означає: У вас є кворум, і зміни конфігурації кластера повинні коректно реплікованись. Якщо Quorum — No, уникайте руху в RBAC; ви можете створити розбіжності між вузлами.
Рішення: Продовжуйте лише коли кворум є. Якщо ні — спочатку вирішіть проблеми зі здоров’ям кластера.
Завдання 2: Перелік користувачів, щоб знайти «автоматизацію, що ховається за людьми»
cr0x@server:~$ pveum user list
┌──────────────┬───────────┬───────────┬────────────────────────────┐
│ userid │ enable │ expire │ firstname │
╞══════════════╪═══════════╪═══════════╪════════════════════════════╡
│ root@pam │ 1 │ 0 │ │
│ alice@pve │ 1 │ 0 │ Alice │
│ ci@pve │ 1 │ 0 │ CI Runner │
│ monitor@pve │ 1 │ 0 │ Monitoring │
└──────────────┴───────────┴──────────────┴──────────────┘
Що це означає: Є локальні облікові записи. Якщо ви бачите «сервісні акаунти» як імена людей або навпаки, скоріш за все у вас є розростання токенів і невизначена відповідальність.
Рішення: Створіть виділені сервісні користувачі (або ідентичності, що підтверджуються доменом) для кожної інтеграції. Не використовуйте людські облікові записи для автоматизації.
Завдання 3: Перевірити API‑токени й виявити помилки спадкування
cr0x@server:~$ pveum user token list ci@pve
┌──────────────┬───────────────┬────────┬──────────────┐
│ tokenid │ expire │ enable │ privsep │
╞══════════════╪═══════════════╪════════╪══════════════╡
│ terraform │ 0 │ 1 │ 1 │
│ ansible │ 0 │ 1 │ 0 │
└──────────────┴───────────────┴────────┴──────────────┘
Що це означає: privsep=0 натякає, що токен може успадковувати привілеї користувача. Часто саме так «найменші привілеї» тихо помирають.
Рішення: Переключіть токени на privilege separation, якщо у вас немає задокументованої причини не робити цього. Потім явно прив’яжіть ACL до токена.
Завдання 4: Створити виділеного сервісного користувача (без шелу, без зайвого)
cr0x@server:~$ sudo pveum user add backup@pve --comment "Backup controller service user"
Що це означає: Ви створили ідентичність, яка може містити токени й ACL. Це не людина; її не слід використовувати інтерактивно.
Рішення: Використовуйте по одному сервісному користувачу на домен інтеграції (backup, monitoring, provisioning). Уникайте «одного сервісного користувача, що керує всім».
Завдання 5: Створити токен з privilege separation і зберегти його одразу
cr0x@server:~$ sudo pveum user token add backup@pve restic --privsep 1
┌──────────────┬──────────────────────────────────────────────┐
│ key │ value │
╞══════════════╪══════════════════════════════════════════════╡
│ full-tokenid │ backup@pve!restic │
│ value │ 7c9dbbb2-3e76-4b3b-8d9f-0c8af2c5d2a1 │
└──────────────┴──────────────────────────────────────────────┘
Що це означає: Це єдиний раз, коли ви побачите значення токена у відкритому вигляді. Збережіть його в менеджері секретів негайно.
Рішення: Якщо ви не можете правильно зберігати секрети — зупиніться і спочатку виправте це. Токени підсилюють ті проблеми поводження зі секретами, що вже є.
Завдання 6: Створити власну роль замість повторного використання «Administrator»
cr0x@server:~$ sudo pveum role add BackupOperator -privs "VM.Audit VM.Backup Datastore.Audit"
Що це означає: Ви визначили роль з явними привілеями. Точні рядки привілеїв мають відповідати вашій версії Proxmox і очікуваним операціям.
Рішення: Віддавайте перевагу невеликим ролям з назвами, що відповідають функції. Якщо ви не можете пояснити привілеї одним реченням — не давайте їх поки що.
Завдання 7: Застосувати ACL на звуженому шляху (пул або конкретне сховище)
cr0x@server:~$ sudo pveum acl modify /pool/prod-vms -token 'backup@pve!restic' -role BackupOperator
Що це означає: Токен отримує права лише на ресурси в пулі prod-vms (залежно від того, що там розміщено і як ви робите бекапи).
Рішення: Якщо ви не можете звузити доступ по пулу, ймовірно у вас відсутня належна організація ресурсів. Виправляйте організацію, а не видавайте /.
Завдання 8: Перевірити ACL і знайти випадкові глобальні надання
cr0x@server:~$ pveum acl list
┌───────────────┬───────────────────────┬───────────────┬─────────────┐
│ path │ ugid │ roleid │ propagate │
╞═══════════════╪═══════════════════════╪═══════════════╪═════════════╡
│ / │ root@pam │ Administrator │ 1 │
│ /pool/prod-vms│ backup@pve!restic │ BackupOperator│ 1 │
│ / │ ci@pve!ansible │ Administrator │ 1 │
└───────────────┴───────────────────────┴───────────────┴─────────────┘
Що це означає: Токен ci@pve!ansible має роль Administrator на /. Це проблема, якщо тільки це не свідомо прийнятий ризик з компенсуючими контролями.
Рішення: Видаліть широкі ACL для автоматизаційних токенів. Створіть сфокусовані ролі й шляхи.
Завдання 9: Безпечно видалити надмірний ACL
cr0x@server:~$ sudo pveum acl delete / -token 'ci@pve!ansible' -role Administrator
Що це означає: Ви відкликали права адміністратора на рівні кластера для цього токена.
Рішення: Негайно перевірте, що автоматизації ще потрібно; повторно надайте тільки мінімальні потрібні права на вузьких шляхах.
Завдання 10: Перевірити аутентифікацію токеном проти локального API
cr0x@server:~$ curl -k -s \
-H "Authorization: PVEAPIToken=backup@pve!restic=7c9dbbb2-3e76-4b3b-8d9f-0c8af2c5d2a1" \
https://127.0.0.1:8006/api2/json/version | jq
{
"data": {
"release": "8.1",
"repoid": "c6d7f9a0",
"version": "8.1.4"
}
}
Що це означає: Токен дійсний і може дістатися до API. Це базовий тест живучості/аутентифікації.
Рішення: Якщо це не працює, не починайте сліпо переробляти ролі. Спочатку перевірте синхронізацію часу, формат токена та чи звертаєтесь ви до правильного вузла/реалму.
Завдання 11: Підтвердити авторизацію, намагаючись виконати заборонену дію
cr0x@server:~$ curl -k -s \
-H "Authorization: PVEAPIToken=backup@pve!restic=7c9dbbb2-3e76-4b3b-8d9f-0c8af2c5d2a1" \
https://127.0.0.1:8006/api2/json/nodes | jq
{
"errors": {
"permission": "permission denied - invalid privileges"
}
}
Що це означає: Добре. Ваш бекап‑токен не може перераховувати вузли по всьому кластеру. Це робота найменших привілеїв.
Рішення: Залишайте заборону, якщо ваша система бекапів дійсно не потребує списку вузлів. Якщо потребує — надавайте лише читання на вузькому шляху, а не admin.
Завдання 12: Перевірити SSH‑доступ root (бо токени не врятують від відхилення через SSH)
cr0x@server:~$ sudo sshd -T | egrep 'permitrootlogin|passwordauthentication'
permitrootlogin yes
passwordauthentication yes
Що це означає: Root може заходити по SSH з паролем. Це шлях обходу вашої програми з токенами.
Рішення: Вимкніть аутентифікацію паролем і прямий root SSH. Використовуйте sudo з іменованих акаунтів або консолі для аварійного доступу.
Завдання 13: Забезпечити безпечніші параметри SSH (і фіксувати зміни)
cr0x@server:~$ sudo sh -c 'cat >/etc/ssh/sshd_config.d/99-hardening.conf <
Що це означає: Root SSH вимкнено; паролі вимкнені. Якщо хтось викрав пароль, він стає менш корисним. Якщо хтось викрав токен, це не допоможе йому зайти по SSH.
Рішення: Переконайтеся, що ви перевірили доступ за ключами для аварійних акаунтів перед включенням цього на всіх вузлах.
Завдання 14: Перевірити синхронізацію часу (бо помилки автентифікації люблять зсуви годинника)
cr0x@server:~$ timedatectl
Local time: Tue 2026-02-04 11:15:10 UTC
Universal time: Tue 2026-02-04 11:15:10 UTC
RTC time: Tue 2026-02-04 11:15:10
Time zone: UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Що це означає: Годинник синхронізований. Коли це не так, ви отримуєте періодичні проблеми з автентифікацією і TLS, що виглядає як «Proxmox нестабільний». Насправді проблема в часі.
Рішення: Якщо час не синхронізований — виправте NTP перед налагодженням токенів або TLS.
Завдання 15: Моніторити автентифікацію та помилки API в логах
cr0x@server:~$ sudo journalctl -u pveproxy -u pvedaemon --since "30 min ago" | tail -n 20
Feb 04 10:58:22 pve1 pveproxy[1832]: authentication failure; rhost=10.20.1.55 user=backup@pve msg=invalid token value
Feb 04 11:02:17 pve1 pvedaemon[1711]: api call failed: permission denied - invalid privileges
Feb 04 11:07:44 pve1 pveproxy[1832]: successful auth for user 'monitor@pve' from 10.20.2.20
Що це означає: Ви можете відрізнити неправильне значення токена від недостатніх привілеїв. Ця різниця важлива: перше — проблема розповсюдження секретів, друге — дизайн RBAC/ACL.
Рішення: Якщо «invalid token value» — ротувати й виправляти обробку секретів. Якщо «invalid privileges» — налаштовувати ACL шлях/роль, а не зберігання токена.
Завдання 16: Знайти процес, що слухає порт API Proxmox
cr0x@server:~$ sudo ss -ltnp | grep ':8006'
LISTEN 0 4096 0.0.0.0:8006 0.0.0.0:* users:(("pveproxy",pid=1832,fd=6))
Що це означає: pveproxy слухає 8006. Якщо ви бачите інше, у вас проблеми з пакетом або процесом.
Рішення: Якщо pveproxy не слухає — не звинувачуйте токени. Виправте сервіс спочатку.
Завдання 17: Повернути токен без простою (шаблон)
cr0x@server:~$ sudo pveum user token add backup@pve restic-v2 --privsep 1
┌──────────────┬──────────────────────────────────────────────┐
│ key │ value │
╞══════════════╪══════════════════════════════════════════════╡
│ full-tokenid │ backup@pve!restic-v2 │
│ value │ 5c1a4e61-9b9c-4f1f-9c7f-9d7a1b4a8d20 │
└──────────────┴──────────────────────────────────────────────┘
cr0x@server:~$ sudo pveum acl modify /pool/prod-vms -token 'backup@pve!restic-v2' -role BackupOperator
cr0x@server:~$ sudo pveum user token list backup@pve
┌──────────────┬───────────────┬────────┬──────────────┐
│ tokenid │ expire │ enable │ privsep │
╞══════════════╪══════════════════════════════════════════════╡
│ restic │ 0 │ 1 │ 1 │
│ restic-v2 │ 0 │ 1 │ 1 │
└──────────────┴──────────────┴──────────────┴──────────────┘
Що це означає: Тепер у вас є два валідні токени з ідентичними ACL. Оновіть залежну систему на v2, перевірте, потім відкличіть v1.
Рішення: Завжди ротувати з перекриттям, а не різким переключенням, якщо ви не любите виклики у нічний час.
Завдання 18: Чисто відкликати токен під час інциденту
cr0x@server:~$ sudo pveum user token remove backup@pve restic
cr0x@server:~$ sudo pveum user token list backup@pve
┌──────────────┬───────────────┬────────┬──────────────┐
│ tokenid │ expire │ enable │ privsep │
╞══════════════╪══════════════════════════════════════════════╡
│ restic-v2 │ 0 │ 1 │ 1 │
└──────────────┴──────────────┴──────────────┴──────────────┘
Що це означає: Компрометований токен мертвий. Виклики з його використанням повинні почати помилково завершуватись одразу.
Рішення: Після відкликання перевірте логи на подальші спроби. Якщо спроби продовжуються — ви знайшли скомпрометований раннер або місце витоку секрету.
Швидкий план діагностики
Коли «токен не працює» або «автоматизація зламана», не блукайте. Дотримуйтеся послідовності, яка ізолює вузьке місце за хвилини.
Перш за все: чи API досяжний і здоровий?
- Перевірте
ss -ltnp | grep :8006, щоб упевнитися, щоpveproxyслухає. - Перевірте
systemctl status pveproxy pvedaemonна предмет зациклювання або падінь. - З хоста раннера протестуйте з’єднання до
node:8006(фаєрвол/маршрутизація).
Інтерпретація: Якщо порт закритий або сервіси хворі — зміни токенів нічого не дадуть. Спочатку виправляйте здоров’я платформи.
По‑друге: це помилка автентифікації чи авторизації?
- Подивіться
journalctl -u pveproxy -u pvedaemonна повідомлення «invalid token value» vs «invalid privileges». - Спробуйте простий API‑виклик, наприклад
/api2/json/version.
Інтерпретація: Invalid token value = обробка/формат секрету. Invalid privileges = дизайн RBAC/ACL.
По‑третє: чи ви звузили ACL до правильного шляху?
- Перелічіть ACL і знайдіть, де надано токену права.
- Підтвердьте, що ресурс фактично знаходиться під тим пулом/шляхом.
- Перевірте, що роль має достатні, але не надто широкі привілеї.
Інтерпретація: Більшість помилок найменших привілеїв — через неправильний шлях. Другими за частотою — неправильні рядки привілеїв ролі.
По‑четверте: чи робить «privilege separation» те, що ви очікуєте?
- Перелікуйте токени і підтвердьте
privsep=1. - Перевірте, чи випадково не надали батьківському користувачу забагато на
/і не покладалися на спадкування.
Інтерпретація: Якщо токен надмірно привілейований — зазвичай це через спадкування або надання прав на /.
По‑п’яте: чи час/TLS викликають періодичні проблеми автентифікації?
- Перевірте
timedatectlна всіх вузлах і раннерах. - Якщо раннери перевіряють TLS, підтвердіть довіреність сертифіката та збіг імені хоста.
Інтерпретація: Зсув годинника і TLS‑невідповідність видають себе за «токен поганий», особливо під час відновлення вузлів.
Поширені помилки: симптом → корінь → виправлення
1) Симптом: «У веб‑інтерфейсі все працює, а токен отримує permission denied»
Корінь: Ви тестували як людський користувач (який має широкі привілеї) і припустили, що токен успадковує їх. Токен може бути з privsep=1 без ACL або ACL на неправильному шляху.
Виправлення: Явно прикріпіть ACL до токена на правильному шляху; перевірте мінімальним API‑викликом, що вимагає конкретного привілею.
2) Симптом: «Токен працює день, потім раптово падає»
Корінь: Значення токена оновлено в сховищі секретів, але не розгорнуто скрізь; або кілька раннерів мають застарілі значення; або зсув годинника спричиняє краєві випадки автентифікації.
Виправлення: Впровадьте ротацію з перекриттям; додайте перевірку розгортання, що підтверджує роботу токена перед релізом; забезпечте NTP на всіх хостах.
3) Симптом: «Автоматизація може видаляти ВМ, хоча не повинна»
Корінь: Токен має роль Administrator на / (часто тому, що хтось тимчасово дав для налагодження і не прибрав), або спадкування від адміністратора увімкнене.
Виправлення: Приберіть ACL на кореневому шляху; пересоздайте токен з --privsep 1; створіть вузькі ролі, як «VM.PowerMgmt» лише.
4) Симптом: «Відкликання токена не зупинило поведінку»
Корінь: Актор не використовує цей токен (помилкове припущення), або існує кілька токенів, або вони використовують пароль/SSH‑маршрут замість токена.
Виправлення: Прогляньте логи по ідентифікатору користувача/токена; інвентаризуйте всі токени; відключіть маршрути на основі пароля; відкликайте систематично.
5) Симптом: «Не можемо звузити права, не порушивши конвеєр»
Корінь: Конвеєр робить забагато: провізіювання, фаєрвол, сховище і операції ВМ під однією ідентичністю. Або відсутня організація ресурсів (немає пулів, непослідовні імена).
Виправлення: Розділіть ідентичності за функціями і стадіями; створіть пули; переробіть кроки конвеєра так, щоб кожен використовував конкретний токен.
6) Симптом: «Токени витікають у логах»
Корінь: Інструменти виводять заголовки, змінні середовища або відладочний вивід; інженери копіюють невдалі команди в чат.
Виправлення: Вимкніть детальний HTTP‑логінг; очистіть CI‑логи; використовуйте замасковані секрети; впровадьте політику «без секретів у задачах» з інструментальним контролем.
Три міні‑історії з корпоративного життя (дуже правдоподібні)
Міні‑історія 1: Інцидент через неправильне припущення
У них був кластер Proxmox, що підтримував внутрішні сервіси: білд‑агенти, сховище артефактів, кілька дрібних баз даних, які всі обіцялися «тимчасовими». Платформна команда вирішила «зробити правильно» і перенесла автоматизацію з пароля root на API‑токен.
Неправильне припущення: «Якщо користувач може зробити це в UI, токен теж зможе». Вони створили токен під адміністраторським користувачем, увімкнули privilege separation, бо це звучало безпечніше, і ніколи не додали ACL до токена. Користувач мав усе. Токен — майже нічого.
Опівночі їх CI спробував підняти ВМ для деплойменту і отримав permission denied. Логіка повторів була агресивною. Вона забила API, наповнила логи, і на чергуванні спрацювали оповіщення «Proxmox authentication failure», через що прийняли рішення про компрометацію. Почали відкликати креденшали і ламати інші інтеграції, бо перша гіпотеза була «атака», а не «помилково звужений токен».
Що це виправило — не геройство, а уважне читання логів: «invalid privileges», не «invalid token value». Вони прикріпили правильну роль на пул, потім обмежили швидкість повторів у конвеєрі. Найбільший урок був культурний: зміну автентифікації треба поводити як продакшн‑деплой, зі стаджингом, а не як правку в UI.
Міні‑історія 2: Оптимізація, яка відплатилася
Інша компанія хотіла пришвидшити провізіювання. Їхній Terraform‑конвеєр створював ВМ, ставив теги, підключав ISO, налаштовував правила фаєрвола і навіть робив обслуговування вузлів. Все через один токен. Було швидко, бо фактично це був cluster‑admin.
Вони «оптимізували» ще більше, кешуючи токен у образі спільного раннера, щоб джобам не потрібно було діставати секрети під час виконання. Це зекономило секунди. Але це означало, що кожен епhemeral раннер мав копію токена на диску, а старі образи жили в реєстрах і кешах довше, ніж хто завгодно міг згадати.
Місяці потому під час рев’ю безпеки токен знайшли в шарі образу. Не з‑за витонченої криміналістики — хтось запустив strings на образі під час рутинного сканування і він випадково «визнався». Вони відкликали токен. Половина автоматизації зупинилася. Інша половина працювала, бо мала другий токен, захардкожений в іншому місці після попередньої міграції.
Наслідок був не лише в викритті; це була втрата контролю. Вони не знали, де саме були секрети. Вони не могли чисто ротувати. Вони навіть не могли інвентаризувати. Після прибирання їх конвеєр став трохи повільнішим, але час реагування на інциденти суттєво покращився. Швидкість — добре; прогнозоване відкликання — краще.
Міні‑історія 3: Нудна, але правильна практика, що врятувала день
Ще одна організація запускала Proxmox для edge‑навантажень. Нічого гламурного. Багато малих кластерів. Багато автоматизації. Вони робили одну нудну річ послідовно: кожен токен мав власника, призначення, сферу дії і дату ротації. Вони зберігали цей метадані в простому внутрішньому реєстрі і практикували ротацію щоквартально.
Одного ранку моніторинг показав незвичну активність API: повторювані спроби з помилкою permission denied з хоста, який не мав спілкуватися з Proxmox. Логи показали ідентифікатор токена в заголовку авторизації. Вони знайшли токен у реєстрі: він належав staging CI‑ранеру, був обмежений пулом стейджингу і не мав працювати з тієї підмережі.
Вони негайно відкликали його, і нічого продуктивного не зламалося, бо токен був сфокусований і тільки для стейджингу. Потім вони простежили раннер: його перевстановили і випадково підключили до ширшої мережі. Ось і була справжня помилка. Дизайн токенів перетворив страшний сигнал на локалізований інцидент.
Їхня «нудна практика» не була дорогою. Вона була дисциплінованою. Вона не дозволила помилці в стейджингу стати продакшн‑аварією і подарувала їм спокійний вівторок замість дзвінка керівництва.
Чек‑лісти / покроковий план
Крок за кроком: перевести інтеграцію з пароля root на сфокусований токен
- Інвентаризація поточного доступу. Визначте, де використовується пароль root (CI‑змінні, скрипти, cron, управління конфігурацією).
- Створіть виділеного сервісного користувача. Назвіть його на честь інтеграції, не людини (наприклад,
backup@pve). - Створіть токен з privilege separation. Збережіть значення токена один раз у менеджері секретів.
- Створіть або повторно використайте вузьку роль. Тільки привілеї, необхідні для інтеграції.
- Звужуйте ACL по пулах/сховищах/шляхах. Уникайте
/, якщо це не справді інтеграція адміністратора кластера (рідко). - Протестуйте одним мінімальним API‑викликом. Підтвердьте автентифікацію (
/version), потім авторизований виклик, потім заборонений виклик. - Розгорніть канаркою. Один раннер, одне середовище, одна задача.
- Включіть ротацію з перекриттям з першого дня. Додайте v2 токен, розгорніть, перевірте, відкличіть v1.
- Вилучіть старе використання пароля. Видаліть його зі сховищ секретів, скриптів, образів; не лишайте «резервні» облікові дані на диску.
- Запишіть власника і дату/регламент ротації. Якщо немає власника — токен стане безсмертним.
Чек‑лист: як має виглядати «добре»
- Пароль root не використовується в автоматизації.
- Вхід root по SSH вимкнено; аутентифікація паролем відключена там, де можливо.
- Токени за замовчуванням використовують privilege separation.
- Токени звужені до пулів, ВМ, ідентифікаторів сховища або вузлів — не до
/. - Ролі — малі, іменовані та періодично переглядаються.
- Існує інвентар токенів (власник, призначення, створено, остання ротація).
- Ротація практикується, а не обіцяється.
- Логи швидко відрізняють погані секрети від поганих дозволів.
Чек‑лист: локалізація інциденту при підозрі на компрометацію облікових даних
- Визначте токен/користувача з логів (pveproxy/pvedaemon).
- Відкличте токен негайно (не «чекайте підтвердження»).
- Пошукайте подальші спроби використання відкликаного токена.
- Знайдіть точку розповсюдження секрету (CI, конфіг, диск).
- Ротувати суміжні токени, що використовувалися на тому ж раннері або в тому ж сховищі секретів.
- Підтвердьте відсутність широких ACL на
/для автоматизаційних токенів. - Перегляньте недавні дії API (хто що робив і звідки) та перевірте цілісність ВМ і сховища.
Питання й відповіді
1) Чи слід створювати токени під root@pam?
Ні для автоматизації. Використовуйте виділених сервісних користувачів і privilege separation. Root має бути для аварійного людського доступу, а не CI.
2) Що дає «privilege separation» насправді?
Воно перешкоджає автоматичному успадкуванню прав користувача токеном. Це змушує явно надавати те, що токену потрібно — і в цьому вся суть.
3) Чи можу я обмежити токен лише на конкретну ВМ?
Так, прикріпивши ACL на /vms/<vmid> з вузькою роллю. На практиці пуми масштабуються краще, але на рівні окремої ВМ це корисно для критичних систем.
4) Як ротувати токени, не порушивши продакшн?
Використовуйте ротацію з перекриттям: створіть другий токен з ідентичними ACL, розгорніть його, перевірте, потім відкличіть старий. Не «перемикайте» без підготовки, якщо ви не готові до простою.
5) Чи замінюють токени двоетапну аутентифікацію (2FA)?
Ні. Токени — для machine‑to‑machine автентифікації. 2FA — для людей. Вам потрібні обидва: сильний людський вхід і сфокусовані машинні креденшали.
6) Де найбезпечніше зберігати токени?
У належному менеджері секретів з політиками доступу й журналами аудиту. Якщо доводиться використовувати змінні CI, забезпечте маскування і заборону друку заголовків у відладочних логах.
7) Чому не просто заховати Proxmox за VPN і продовжувати використовувати паролі?
Тому що внутрішні мережі і VPN вже не є довіреними кордонами. Потрібні сфокусовані, відкличні креденшали навіть у «приватній» мережі. VPN — шар, а не стратегія.
8) Скільки ролей нам потрібно?
Менше, ніж ви думаєте, але більше, ніж одна. Почніть з 5–10 ролей, орієнтованих на робочі задачі (read‑only monitoring, VM power control, provisioning, backup, network admin). Розширюйте лише коли не можете чітко висловити потребу.
9) Що робити, якщо інтеграції потрібен широкий доступ до багатьох ВМ?
Сгрупуйте ці ВМ у пул і звузьте доступ до /pool/<name>. Якщо дійсно потрібні права на весь кластер — поводьтеся з таким токеном як з критичним обліковим записом: додаткові контролі, коротша ротація, суворіше зберігання й явне погодження.
10) Як дізнатися, які токени існують і хто їх власник?
Proxmox може перерахувати токени, але власність — це процесна проблема. Тримайте внутрішній реєстр (навіть просту таблицю), що зіставляє ID токена з власником, системою і графіком ротації.
Висновок: наступні кроки, що дійсно працюють
API‑токени — це не трофей безпеки. Це спосіб зробити компрометацію пережитною і операції передбачуваними. Якщо ви тримаєте пароль root як стандартний креденшал автоматизації, ви фактично кажете атакувальникам — і втомленим інженерам — що контрольна площина в один втіклий секрет.
Практичні наступні кроки:
- Виберіть одну інтеграцію (CI, бекап, моніторинг) і переведіть її на виділеного сервісного користувача + токен з privilege separation цього тижня.
- Створіть одну вузьку кастомну роль, що відповідає реальній роботі інтеграції, а не вашим страхам.
- Звузьте ACL до пулу або конкретних шляхів. Видаліть будь‑які
Administratorпризначення на/для автоматизаційних токенів. - Вимкніть root SSH входи та аутентифікацію паролем там, де можливо, і перевірте наявність резервного шляху для аварій.
- Реалізуйте ротацію з перекриттям і проведіть тренування ротації. Ставте це як деплой: поетапно, протестовано, відкатно.
- Почніть інвентар токенів з власниками та датами ротації. Якщо ви не можете назвати власника — у вас не токен, а ризик.
Якщо ви зробите лише одне: припиніть робити «root скрізь» найпростішим шляхом. Замініть це сфокусованими токенами й аудиторським слідом, який каже правду.