Як ствараўся бэкенд хакерскай гульні пра знішчэнне сервера
Працягваем расказваць, як быў уладкованы наш лазерны квэст са знішчэннем сервера. Пачатак у папярэдняй артыкуле пра разгадку квэста.
Усяго ў бэкенда гульні было 6 архітэктурных адзінак, якія мы і разбяром у гэтым артыкуле:
Бэкенд гульнявых сутнасцяў, якія адказвалі за гульнявыя механізмы
Шына абмену дадзеных бэкенда і пляцоўкі на VPS
Транслятар з запытаў бэкенда (гульнявых элементаў) на ардуіна і жалеза на пляцоўцы
Ардуіна, якая займалася кіраваннем рэлёшкамі, атрымлівала каманды з транслятара і рабіла фактычную працу
Фактычныя прылады: вентылятар, гірлянды, таршэры і іншае
Франтэнд - сам сайт Сокала, з якога гульцы кіравалі прыладамі
Давайце пройдземся па кожнай з іх.
Бэкенд гульнявых сутнасцяў
Бэкенд быў рэалізаваны, як spring boot-дадатак: яно мела некалькі rest-кантролераў, websocket endpoint і сэрвісы з гульнявой логікай.
Кантралёраў было ўсяго тры:
Мегатрон. Праз GET-запыты аддавалася актуальная старонка Мегатрона: да і пасля ўключэння харчавання. Праз POST-запыт лазер страляў.
Мапінг тыльдаўскіх старонак, каб яны аддаваліся па імені старонкі. У тыльды на экспарт выдаюцца старонкі не з арыгінальнымі назвамі, а унутраным ID і інфармацыяй па адпаведнасці.
Кантролер для капчы, каб аддаваць псеўда-высоказагружальную сервер капчу.
Websocket endpoint выкарыстоўваўся для кіравання гаджэтамі: лямпамі, гірляндай і літарамі. Яго выбралі, каб сінхронна адлюстроўваць усім гульцам бягучы статус прылады: ці ўключана яно ці выключана, актыўна ці не, які колер літары зараз гарыць на сцяне. Для таго каб крыху ўскладніць задачу ўключэння лазера, мы накінулі аўтарызацыю на гірлянду і лазер з аднолькавым лагінам і пароль admin/admin.
Гульцы маглі пратэставаць яго на ўключэнні гірлянды і паўтарыць тое ж самае на лазеры.
Намі была абрана настолькі трывіяльная пара лагін-пароль для таго, каб не мучыць гульцоў лішнім падборам.
Каб зрабіць задачу крыху цікавей, у якасці ідэнтыфікатараў прылад у пакоі выкарыстоўваліся object ID з mongodb.
ObjectId утрымоўвае ў сабе timestamp: два выпадковых значэння, адно з якіх бярэцца на падставе ідэнтыфікатара прылады, а другое на падставе pid-працэсу, які генеруе яго і значэнне лічыльніка. Жадалася зрабіць ідэнтыфікатары згенераванымі праз роўныя прамежкі часу і з рознымі pid-працэсаў, але агульным лічыльнікам, каб падбор ідэнтыфікатара прылады лазера быў цікавей. Аднак у выніку ўсе запусціліся з ідэнтыфікатарамі, якія адрозніваюцца толькі ў значэнні лічыльніка. Магчыма, гэта зрабіла этап занадта простым і не патрабавальным аналізу структуры ідэнтыфікатараў objectId.
Транслятар з запытаў бэкенда
Пітонаўскі скрыпт, які займаўся таймерамі і пераводзіў з абстракцый гульнявых у фізічную мадэль. Напрыклад уключыць таршэр → уключыць рэле 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 фатаграфіі самога Сакалова. У мяне было толькі некалькі патрабаванняў: мужчына сярэдніх гадоў, у дрэнна які сядзіць гарнітуры на пару памераў больш і ў позе «прафесійная фотасесія ў студыі». Для цеста паказвалі яе сябрам і пыталіся "ну як табе?".
У працэсе распрацоўкі дызайну мужу даводзілася кожныя паўгадзіны адыходзіць паляжаць, пачынала верталяціць. Паша стараўся адчыняць кансоль распрацоўніка на большую частку экрана, пакуль дапілоўваў фронтэнд - бярог вочы.
Фактычныя прылады
Вентылятары і святло мантавалі праз цвёрдацельныя рэле, каб яны ўключаліся не адразу на поўную магутнасць - каб нарастанне магутнасці адбывалася паралельна з маніторынгам.
Але пра гэта раскажам у наступным пасце, пра хардварную частку гульні і ўласна забудову пляцоўкі.