Як створювався бекенд хакерської гри про знищення сервера

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

Усього бекенд гри був 6 архітектурних одиниць, які ми і розберемо в цій статті:

  1. Бекенд ігрових сутностей, які відповідали за ігрові механізми
  2. Шина обміну даних бекенда та майданчики на VPS
  3. Транслятор із запитів бекенду (ігрових елементів) на ардуїно та залізо на майданчику
  4. Ардуїно, яка займалася управлінням реліжками, отримувала команди з транслятора та робила фактичну роботу
  5. Фактичні пристрої: вентилятор, гірлянди, торшери та інше
  6. Фронтенд - сам сайт Сокола, з якого гравці керували пристроями

Давайте пройдемося по кожній із них.

Бекенд ігрових сутностей

Бекенд був реалізований, як spring boot-додаток: він мав кілька rest-контролерів, websocket endpoint та сервіси з ігровою логікою.

Контролерів було лише три:

  • Мегатрон. Через GET-запити надавалась актуальна сторінка Мегатрону: до та після включення харчування. Через POST-запит лазер стріляв.
  • Мапінг сторінок тильдів, щоб вони віддавалися на ім'я сторінки. У тильди на експорт видаються сторінки не з оригінальними назвами, а внутрішнім ID та відповідною інформацією.
  • Контролер для капчі, щоб віддавати псевдо-завантажувальну сервер капчу.

Websocket endpoint використовувався для управління гаджетами: лампами, гірляндою та літерами. Його вибрали, щоб синхронно відображати всім гравцям поточний статус пристрою: увімкнено чи вимкнено, активно чи ні, який колір літери зараз горить на стіні. Для того щоб трохи ускладнити завдання включення лазера, ми накинули авторизацію на гірлянду та лазер з однаковим логіном та пароль admin/admin.

Гравці могли протестувати його на включенні гірлянди і повторити те саме на лазері.

Нами було обрано настільки тривіальну пару логін-пароль для того, щоб не мучити гравців зайвим підбором.

Щоб зробити завдання трохи цікавішим, як ідентифікатори пристроїв у кімнаті використовувалися object ID з mongodb.

ObjectId містить timestamp: два випадкових значення, одне з яких береться на підставі ідентифікатора пристрою, а друге на підставі pid-процесу, який генерує його і значення лічильника. Хотілося зробити ідентифікатори згенерованими через рівні проміжки часу та з різними pid-процесами, але загальним лічильником, щоб підбір ідентифікатора пристрою лазера був цікавішим. Однак у результаті всі запустилися з ідентифікаторами, які різняться лише значення лічильника. Можливо, це зробило етап надто простим і не вимагає аналізу структури ідентифікаторів об'єкта.

Транслятор із запитів бекенда

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

Скрипт підключався до черги RabbitMQ і передавав запити із черги на Ардуїно. Також на ньому була реалізована логіка паралельного включення світла: разом із деякими пристроями на них включалося світло, наприклад, при первинній подачі живлення на Мегатрон, він підсвічувався сценічним світлом. Дизайн світла для кінематографічності всієї сцени - окрема історія про велику роботу нашого співпродюсера проекту та художника-постановника Іллі Сєрова, і про неї ми розповімо в окремому пості.

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

Як було влаштовано логіку генерації токена мегатрону

Тестовий постріл

Кожні 25 секунд генерувався новий токен, його можна було використовувати для включення лазера на 10 секунд на потужності 10/255. Посилання на гітхаб з кодом Мегатрону.

Потім лазер охолоджувався 1 хвилину - у цей час він був недоступний і не приймав нових запитів на постріл.

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

Для генерації токена використовувався алгоритм хешування MD5. І схема виходила MD5 від MD5 + лічильник + секрет для бойового токена та без секрету для тестового.

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

Бойовий постріл

Бойовий режим Мегатрону - це 100% потужність лазера 3 Вт. Цього цілком достатньо на 2 хвилини, щоб перепалити мотузку, яка тримала гирю, щоб розбити акваріум та залити сервер водою.

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

Знаючи ці дані, можна було перебрати 2 останні символи солі і фактично з'ясувати, що для неї використовувалися числа з Lost, переведені в 16-річну систему.

Далі гравцям залишалося зловити значення лічильника (проаналізувавши тестовий токен) та згенерувати бойовий токен, використовуючи наступне значення лічильника та підібрану на минулому кроці сіль.

Лічильник просто інкрементувався при кожному тестовому пострілі кожні 25 секунд. Про це ми ніде не писали, це мало бути невеликою ігровою несподіванкою.

Сервіс взаємодії з капчею

В ігровому світі це була та сама капча, яку треба було навантажити, щоб увімкнути вентилятор і відкрити фліпчарт із підказкою. Поруч із камерою стояв ноутбук із моніторингом навантаження.

Як створювався бекенд хакерської гри про знищення сервера

Сервіс підраховував, що відображати у моніторингу як поточне навантаження: температуру та CPU Fan. Метрики передавалися в timebase database і відмальовувалися графаною.

Якщо за останні 5 секунд надходило понад 50 запитів на відображення капчі, то навантаження зростало на фікс + рандомну кількість кроків. Розрахунок був на те, щоб 100% навантаження можна було отримати за дві хвилини.

Насправді логіки в сервісі було більше, ніж відобразилось у кінцевій грі: ми поставили монітор таким чином, що було видно лише обертання CPU Fan.

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

Хостинг та шина обміну даних

Інструмент передачі з бекенда на майданчик, VPS-сервер у якому було запущено RabbitMQ.

Бекенд та шина даних трималися на наших VPS. Його потужність була порівнянна з комп'ютером, який ви бачили на екрані: 2-х ядерна VPS з двома гігабайтами оперативної пам'яті. Тариф брали за ресурси, оскільки пікове навантаження планувалося лише кілька днів — так і чинять наші клієнти, які планують навантажувати VPS на короткий термін. Потім виявилося, що навантаження вище, ніж ми припускали, і фіксований тариф був би вигіднішим. Робитимете квест — обирайте тарифи лінійки турбо.

Для захисту сервера від DDoSa ми використовували Cloudflare.

Варто сказати, що VPS із честю витримала все.

Ардуїно, яка займалася управлінням реліжками, отримувала команди з транслятора та робила фактичну роботу

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

Фронтенд

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

Спочатку ми думали просто експортувати сайт і накинути логіку, що нам не вистачає, але нарвались на terms of use, які нам це забороняли.

Ми не були готові порушувати ліцензію, тому було два варіанти: зверстати все самим або безпосередньо зв'язатися з Тільдою, розповісти про проект та попросити дозволу змінювати код.

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

У результаті ми прикрутили до фронтенду js-логіку на відправку запитів на елементарні пристрої, трохи змінили стилі клавіш включення і вимкнення ігрових елементів.

Дизайн сайту

Історія пошуків, що стоїть окремого розділу.

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

Спочатку дизайн робила я сама, намагаючись встромити більше гіфок і блискучих елементів. Але мій чоловік-дизайнер із 10-річним стажем, зазирнувши через плече, забракував його як «надто хороший». Щоб порушувати правила дизайну, треба знати їх.

Як створювався бекенд хакерської гри про знищення сервера

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

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

Фактичні пристрої

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

Але про це розповімо в наступному пості, про хардварну частину гри та власне забудову майданчика.

Залишайтеся з нами!

Інші статті про квест зі знищенням сервера

Як створювався бекенд хакерської гри про знищення сервера

Джерело: habr.com

Додати коментар або відгук