Перейти до вмісту

Блог ·

Один справжній агент, один шлюз розробки

Пʼять раундів закінчилися тим самим застереженням: не доведено на дроті. Закриття вимагало справжнього агента, підкладеного пароля і двох порожніх мірок.

Автор: Provibr

Пʼять раундів поспіль завершили свій звіт варіантом тієї самої фрази: зміна протоколу є додатковою, модульні тести зелені, і нічого з цього не випробувано проти справжнього агента. Адаптери моніторингу, запечатаний конверт, автоматичні оновлення агента, крок автоматизації, що чекає на команду. Усі пʼять були правильні настільки, наскільки хтось міг побачити, і всі пʼять несли застереження, яке успадковував наступний раунд.

Таке застереження дешево написати, і воно накопичується. Кожен раунд додає одне, ніхто не помиляється, а після пʼятьох лишається стос поведінки, що існувала тільки на випробувальному стенді. Цей раунд пішов на прибирання стосу, а не на його збільшення: жодної функції, жодної зміни протоколу, жодної публікації. Вісімдесят дві мірки проти одного справжнього агента.

Устаткування, одним реченням

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

Усе в цьому реченні несе вагу. Двійковий файл є тим, що ми постачаємо, а не збіркою для випробувань, бо цікаві збої мешкають у серіалізації та TLS, а не в логіці. Шлюз навмисно є примірником розробки на інших портах, бо промисловий слухає на очевидних, а агент, що постукав би не з того боку, означав би дуже поганий пообідній час. Служби є одноразовими контейнерами зі справжнім програмним забезпеченням у справжніх версіях, а не підробками, бо весь сенс вправи полягає в тому, що підробки є саме тим, що ми вже мали.

Служби баз даних отримали пароль-канарку, і саме цей вибір уможливив наступний розділ.

ГрупаМіркиЩо це вирішує
Адаптери моніторингу44Шість протоколів баз даних і каталогів, правильні та хибні облікові дані, і стан правила, що з цього випливає
Автоматичні оновлення19Планування, застосування, перезапуск і відмова від підробленої збірки
Крок автоматизації11Команда, що завершується в межах очікування, і команда, що не завершується
Розміщений зонд4Той самий файл, записаний як зонд платформи, а не як агент клієнта
Джерело зникло4Відʼєднаний агент дає власний стан, ніколи хибну аварію

Пошук із підкладеним значенням

Твердження, яке ми найдужче хотіли випробувати, є запереченням: секрет моніторингу мандрує запечатаним і ніколи не записується в рядок команди, у журнал подій, у шину повідомлень чи в будь-який із двох журналів процесів.

Заперечення є саме тими твердженнями, що хиблять мовчки. Тому паролі не були випадковими рядками, чия відсутність нічого не доводить; це були підкладені значення, дібрані так, щоб одна поява будь-де була беззаперечною. Далі просіяли сім шарів: збережені корисні навантаження команд, таблицю подій, збережену конфігурацію перевірки, збережені результати, шину повідомлень у тексті та в закодованому вигляді, журнал шлюзу і журнал агента. Разом це близько півмільйона символів матеріалу.

Нуль збігів, і це та відповідь, якої ми хотіли, і водночас та, яку дає зламаний пошук.

Тому той самий пошук пустили на файл, що напевно містив слово, і він його знайшов. Цей додатний контроль є різницею між «ми шукали і нічого не було» та «ми не шукали». Він коштує один рядок і є найціннішим рядком у сценарії.

Ще дві вимоги накривають той самий збій з іншого боку: виконання має спостерегти щонайменше десяток справжніх команд перевірки і кілька десятків повідомлень шини, перш ніж йому дозволено щось висновувати. Обидві бували червоними в певний момент раунду, на прогонах, які інакше повідомили б про чисте просіювання цілковитої порожнечі. Просіювання, що не знаходить порушень у порожній множині, не є доказом, а виглядає точно як успіх.

Два способи бути зеленим, нічого не вимірявши

Обидва трапилися в цьому раунді, у сценаріях, написаних тим, хто знає цю форму збою і регулярно про неї пише.

Перший: запит вибрав один стовпець, а код потім читав іншу властивість на рядках результату. У типізованій мові це помилка; тут це undefined, назавжди, мовчки, і будь-яке порівняння з цим значенням хибить у спосіб, схожий на твердження, що ніколи не спрацьовує, а не на твердження, що завжди справджується. Перевірка повідомила про успіх, бо їй не було чого порівнювати.

Другий: перевірка належності до порожнього переліку. Це твердження ні про що, воно виконується тривіально і є природним кінцевим станом будь-якого сценарію, попередній етап якого мовчки дав нуль рядків. Обидва накриваються дешево: перевірте форму того, що ви отримали, і перевірте, що множина для дослідження не порожня.

Пʼять назв стовпців у тих сценаріях були вгадані, а не знайдені. Ті впали гучно, і це дешевий різновид тієї самої помилки, але це та сама помилка: одна команда каже, як зветься стовпець, а версія, у якій здогад опиняється в переліку, що його ніхто не виконує, і є тією версією, яка переживає перегляд.

Агент, що відмовляється записуватися вдруге

Посеред випробувань оновлення агент перестав повертатися. Ззовні це виглядало як цикл перезапуску, і перша година пішла на шлях оновлення.

Агент робив саме те, що треба. Запис створює файл стану, а створений сценарій встановлення перевіряє цей файл і відмовляється записуватися знову, якщо той є. Повторний запис уже записаного вузла заміняє особистість, і зробити це випадково є способом, у який машина втрачає свій сертифікат і свою скриньку за один крок. Наш наглядовий цикл, написаний до нагоди, такої брами не мав, і кожна спроба перезапуску впиралася у власну і правильну відмову агента.

Наука тут не про браму. Вона про те, що правильна відмова і вада здалеку мають ту саму форму, а розділяє їх читання того, що насправді сказала інша сторона, а не того, на що натякав симптом.

Із тих самих днів вийшли ще три несподіванки, усі три є проєктними рішеннями, що зустріли дійсність:

Заплановані години оновлення живуть на сітці по пʼять хвилин, накинутій обмеженням бази даних. «За одну хвилину», чого хоче той, хто пише випробування, не існує. Придатним це робить вікно надолуження: пропущену годину виконують ще чверть години поспіль. Саме тому повторна мірка в межах тієї самої чверті години має обрати невикористану годину сітки, адже кожну годину займають унікально на агента, а другий прогін по тій самій справедливо відхиляють.

Перевірка TCP типово має ввімкнений TLS. Спрямована на нешифрований порт, вона хибить із помилкою TLS, і це правильно, а читається як зламана перевірка, доки не подивитися, що таке типове значення.

А рядок аудиту кроку автоматизації, чиє очікування збігло, застигає на стані, який побачив потік. Команда перейшла в збіглий час на шістдесят мілісекунд пізніше, а рядок далі казав те, що казав. Це не вада рядка, це вада коментаря над ним, який обіцяв, що там можна прочитати остаточний наслідок. Ту обіцянку прибрано і належно відповіджено в іншому місці.

Сповіщення, що групує, і підрахунок, що каже нуль

Найгостріша з дрібних знахідок. Після вдалого оновлення платформа пише сповіщення. Мірка порахувала сповіщення, створені від початку виконання, і дістала нуль.

Сповіщення групуються. Друга поява того самого збільшує лічильник на наявному рядку і лишає позначку створення недоторканою, і саме цього хочуть у панелі: «цей агент зник» із числом поруч, а не сорок рядків. Це також саме те, через що підрахунок за позначкою створення не повідомляє нічого, поки сповіщення стоїть на видноті.

Мірка помилялася, виріб мав рацію, і єдина причина, чому ми знаємо, у який бік це було, полягає в тому, що хтось відкрив панель замість вірити запиту. Кожне зведення має форму, і випробування, яке цієї форми не знає, випробовує власне припущення.

Що ми записали б

  1. «Не доведено на дроті» є боргом, і він накопичується. Один раунд може його нести. Пʼять раундів є стосом поведінки, що поза стендом ніколи не існувала.
  2. Доводьте заперечення підкладеним значенням і додатним контролем. Без нього нуль збігів і зламаний пошук не розрізнити.
  3. Дайте кожному просіюванню підлогу. Перевірте, що вхід не порожній, перш ніж щось із нього висновувати.
  4. Правильна відмова здалеку виглядає як вада. Прочитайте, що сказала інша сторона, перш ніж переписувати свою.
  5. Не вгадуйте ані назви стовпця, ані типового значення, ані сітки. Усі три лежать за одну команду, а здогад, що доходить до переліку, і є тим, який ніколи не спрацьовує.
  6. Знайте форму того, що рахуєте. Згруповані рядки не несуть позначки створення, за якою ви фільтруєте.

Для ясності: у цьому раунді нічого не опубліковано. Жодної зміни виробу, жодної зміни протоколу, жодної публікації агента. Вийшло з нього те, що пʼять застережень зникли, а жменю дрібних вад виправлено, і прибирання перелічили, а не припустили: жодних залишених рядків, жодних залишених контейнерів, жодних залишених файлів.

Дещо лишилося недоведеним. Шлях уприскування автоматизації випробувано через її ядро, а не через панель, адаптери не працювали з розміщеного зонда, і досі немає мірки проти справжнього гіпервізора.

Із платформної роботи над Provibr. Чому секрет моніторингу запечатують на кожну спробу, описано в секрет, що мандрує один раз, а як підписане оновлення агента відмовляє підробленій збірці, описано в як підписане оновлення агента відмовляє саме собі.

Читати далі

Почніть з одного хоста й одного агента

Створіть обліковий запис, встановіть агента однією командою та підключіть свій перший хост Proxmox. Пробний період триває 14 днів і не потребує платіжних даних.