Жалеза праекта: як мы будавалі пакой з хакерскім квэстам
Пару тыдняў таму мы правялі анлайн-квест для хакераў: пабудавалі пакой, які запоўнілі разумнымі прыладамі і запусцілі з яго YouTube-трансляцыю. Гульцы маглі кіраваць IoT-дэвайсамі з сайта гульні; мэтай было знайсці схаванае ў пакоі зброю (магутную лазерную ўказку), хакнуць яе і задаволіць у пакоі кароткае замыканне.
Каб дадаць вострасюжэтнасці, мы паставілі ў пакоі Шродэр, у які загрузілі 200 000 рублёў: Шродэр з'ядаў па купюры ў гадзіну. Выйграўшы гульню, можна было спыніць Шродэр і забраць усе астатнія грошы.
Было вельмі шмат запытаў паказаць момант уборкі пакоя - паказваем, як мы яе разбіраем
Архітэктура жалеза: кіраванне пакоем
Праектаваць апаратнае рашэнне мы пачалі, калі быў ужо прыблізна зразумелы сцэнар, гатовы бэкенд і ў нас стаяў пусты пакой, гатовы для мантажу абсталявання.
Успамінаючы стары анекдот "The S in IoT stands for Security" ("Літара S у абрэвіятуры IoT абазначае Security") мы прынялі рашэнне, што ў гэты раз гульцы па сцэнары гульні ўзаемадзейнічаюць толькі з франтэндам і бэкендам сайта, але не атрымліваюць магчымасці дабрацца непасрэдна да жалеза.
Гэта было зроблена з меркаванняў бяспекі і відовішчнасці таго, што адбываецца на экране: пры непасрэдным доступе гульцоў да жалеза, было б значна складаней ізаляваць бяспечныя і патэнцыйна небяспечныя дзеянні, напрыклад, паскораную пракрутку Шродэра або кіраванне піратэхнікай.
Перад пачаткам праектавання ў нас сфармуляваліся некалькі прынцыпаў кіравання гульнявымі прыладамі, якія сталі базай канструкцыі:
Не выкарыстоўваць бесправадныя рашэнні
Уся гульнявая прастора знаходзіцца ў адным кадры, да кожнага кутка якога можна дацягнуцца. Рэальнай неабходнасці ў бесправадных падключэннях не было і яны б проста сталі яшчэ адной кропкай адмовы.
Не выкарыстоўваць нейкія спецыяльныя прылады ад разумнага дома
У асноўным, дзеля гнуткасці наладкі. Зразумела, што можна наладзіць пад нашу задачу мноства скрынкавых версій сістэм разумнай хаты з гатовай адмінкай і кіраваннем, але працавыдаткі былі б супастаўныя са стварэннем свайго простага рашэння.
Акрамя таго, трэба было прыдумаць прылады, па якіх будзе відавочна відаць, што менавіта гульцы мяняюць яго стан: уключылі/выключылі або праставілі канкрэтнае святло на літарах СОКОЛ.
Мы сабралі ўсе элементы з агульнадаступнага жалеза, якое можна купіць у звычайных крамах радыёдэталяў: паміж дастаўкай піцы і дыетычнай колы, на пляцоўку ўвесь час прыязджалі кур'еры Чып і Дып і Леруа.
Выбар сабраць усё самім спрашчаў адладку, маштабаванасць, аднак, патрабаваў большай акуратнасці пры мантажы.
Усё рэле і арудзіна не павінна быць відаць у кадры
Мы вырашылі звесці ўсе кіраваныя элементы ў адно месца і схаваць за кадрам, каб мець магчымасць кантраляваць працаздольнасць і, калі спатрэбіцца, акуратна прапаўзці па-за зонай бачнасці камеры і замяніць які выйшаў з ладу блок.
У выніку ўсё схавалі пад сталом, а камеру ўсталявалі так, каб ніжэй стала нічога не было відаць. Гэта была наша "сляпая зона" для падпаўзання інжынера
У выніку ў нас атрымалася фактычна адна разумная прылада: яно атрымлівала ад бэкенда стан кожнай сваёй часткі і змяняла яго адпаведнай камандай.
З пункту гледжання апаратнай рэалізацыі гэтая прылада кіравала 6 элементамі:
Некалькі настольных лямпаў, яны маюць стан вкл/выкл і кіруюцца гульцамі
Літары на сцяне, яны могуць мяняць свой колер па камандзе гульцоў
Вентылятары, якія круцяцца і адчыняюць фліпчарт пры нагрузцы на сервер
Лазер, які кіруецца праз ШІМ
Шродэр які зжыраў грошы па раскладзе
Дым-машына, якая спрацоўвала перад кожным стрэлам лазера
Тэсціруем дым-машыну разам з лазерам
Пазней дадалося яшчэ сцэнічнае святло, якое стаяла за кадрам і кіравалася роўна як свяцільні з пункта 1. Сцэнічнае святло спрацоўвала ў двух выпадках: падсвятляў лазер пры падачы на яго харчавання і падсвятляў гіру перад тым, як лазер запускаўся ў баявым рэжыме.
Што з сябе ўяўляла гэта разумная прылада
Усю дарогу Юра, наш хардваршчык, стараўся не ўскладняць і прыдумаць самае простае, мінімалістычнае рашэнне з магчымых.
Меркавалася, што на VPS будзе круціцца проста скрыпт, які атрымлівае json са станам прылад і перасылае яго на падлучаную па usb ардуінку.
Да партоў падключаліся:
16 звычайных рэле (менавіта яны выдавалі той шчоўканне, якое было чуваць на відэа. У асноўным мы выбралі іх з-за гэтага гуку)
4 цвёрдацельных рэле для кіравання каналаў з ШІМ, напрыклад вентылятараў,
асобны ШІМ выхад для лазера
выснова, які фармуе сігнал на святлодыёдную стужку
Вось прыклад json-каманды, якая прыходзіла да рэле ад сервера
Каб адсачыць момант, калі лазер нарэшце перапаліць вяроўку і гіра паляціць на акварыум, мы зрабілі невялікую кнопку, якая спрацоўвала на падзенне гіры і давала сігнал сістэме.
Кнопка-маніторынг руху гіры
Пры гэтым сігнале павінны былі загарэцца дымавыя шашкі, зробленыя з шарыкаў для пінг-понгу. Мы ўклалі 4 дымавухі прама ў корпус сервера і падвялі да іх ніхромавую нітку, якая павінна была распаліцца і спрацаваць як запал.
Корпус з дымавымі шашкамі і кітайскай гірляндай
Ардуіна
На ардуінцы па першапачатковай задуме адбывалася два дзеянні.
Першае - пры атрыманні новага запыту, запыт парыўся з дапамогай бібліятэкі ArduinoJson. Далей кожнаму кіраванай прыладзе супастаўляліся дзве яго ўласцівасці:
стан харчавання "уключаны" або "выключаны" (стандартны стан)
перыяд, на які прылада ўключана - час у мікрасекундах ад старту платы, калі ўжо пара яе выключаць, гэта значыць прыводзіць стан да стандартнага
Апошнім часам задавалася пры атрыманні адпаведнага параметру ў JSON, аднак яго можна было і не перадаваць, тады значэнне ўсталёўвалася ў 0 і абнуленні не адбывалася.
Другое дзеянне, якое вырабляла ардуінка кожны цыкл - гэта актуалізацыя станаў, гэта значыць праверка, ці няма неабходнасці нешта ўключыць ці не прыйшоў час выключаць якое-небудзь прылада.
Лазерная ўказка - той самы Мегатрон 3000
Гэта звычайны лазерны модуль для рэзкі і маркіроўкі LSMVR450-3000MF 3000мВт 450нм з ручной факусоўкай.
Літары Сокал
Зроблены вельмі проста - мы проста скапіявалі літары з лагатыпа, выразалі іх з кардона, а потым абляпілі led-стужкай. Пры гэтым прыйшлося спайваць кавалкі стужкі паміж сабой, па 4 кантакты на кожным шве, але вынік таго каштаваў. Наш бекендер Паша паказаў цуды ўмеласці, зрабіўшы гэта менш чым за некалькі гадзін.
Першыя тэсты iot-прылады і дапілоўванне
Мы зрабілі першыя тэсты і заадно нам пад'ехалі новыя задачы. Справа ў тым, што ў сярэдзіне працэсу да каманды далучыўся сапраўдны кінапрадзюсер і аператар з ВДІКа Ілля Сяроў — ён выбудаваў кадр, дадаў дадатковае кіношнае асвятленне і крыху змяніў сцэнар гульні, каб сюжэт атрымліваўся больш эмацыйным, а карцінка больш драматычнай і тэатральнай.
Гэта істотна павялічыла якасць, але з'явіліся элементы, якія таксама спатрэбілася далучаць да рэле і прапісваць алгарытм працы.
Іншы праблемай аказаўся лазер: мы правялі некалькі эксперыментаў з рознымі тыпамі вяроўкі і лазерамі рознай магутнасці. Для цеста мы проста вертыкальна падвешвалі груз на вяроўцы.
Пры запуску з тэставым токенам магутнасць рэгуляваная праз шым складала менш за 10% і вяроўку не пашкоджвала нават пры працяглай экспазіцыі.
Для баявога рэжыму лазер расфакусавалі прыкладна да плямы дыяметрам 10 мм і ён упэўнена перапальваў вяроўку з грузам, з адлегласці каля метра.
Так лазер спрацоўваў выдатна на цестах
Калі мы ўжо пачалі тэставаць усё прама ў пакоі на падвешанай гіры, аказалася, што надзейна замацаваць лазер не вось так проста. Затым, што калі вяроўка гарыць - яна плавіцца, расцягваецца і ссоўваецца з-пад першапачатковага фокусу.
А вось так ён ужо не працаваў: вяроўка ссоўвалася
Ілля перамясціў лазер на супрацьлеглым ад вяроўкі канец пакоя, каб лазерны прамень ішоў праз усю сцэну і прыгожа глядзеўся ў кадры, з-за чаго адлегласць павялічылася ўдвая.
Правёўшы яшчэ некалькі эксперыментаў з перапальваннем вяроўкі ўжо ў баі, мы вырашылі не катаваць лёс і падстрахаваць разразанне вяроўкі з дапамогай ніхромавага дроту. Яна знішчала нітку праз 120 секунд пасля ўключэння лазера ў баявым рэжыме. Гэта, а таксама адключэнне дроту і запал дымавых шашак пры спрацоўванні кантакту адрыву мы вырашылі жорстка прапісаць прама ў жалезе мікракантролера.
Нітка, якая ў выніку перапальвала вяроўку за кадрам
Такім чынам з'явілася трэцяя задача якую вырашала ардуінка - адпрацаваць паслядоўнасці, звязаныя з выкананнем гэтых каманд.
Таксама мы вырашылі аддаць ардуінцы неабходнасць весці адлік грошай на тэлевізары і запускаць Шродэр. Першапачаткова меркавалася, што гэтым зоймецца бэкэнд і на сайце будзе бачны бягучы баланс, а на тэлевізары мы будзем паказваць каментары з ютуба, як дадатковы інтэрактыўны элемент, які падказвае гледачам, што падзеі ў пакоі адбываюцца ў рэальным часе.
Але на тэставым прагоне Ілля адгледзеў сцэну і прапанаваў на самым вялікім экране паказваць гульнявы баланс: колькі грошай яшчэ засталося, колькі з'едзена і зваротны адлік да наступнага запуску Шродэра.
Ардуіна мы завязалі на бягучы час: кожную поўную гадзіну запускаўся Шродэр. Малюнак на тэлевізар выдавалася з дапамогай распіры, якая ў той момант ужо атрымлівала з сервера запыты і перасылала іх на выкананне ў ардуінку. Малюнкі з грашовымі паказчыкамі маляваліся з дапамогай выкліку кансольнай утыліты fim прыкладна вось так
image = subprocess.Popen(["fim", "-q", "-r", "1920×1080", fim_str]), где fim_str
І фармавалася зыходзячы з патрэбнай сумы або часу.
Малюнкі мы згенеравалі загадзя: проста ўзялі гатовае відэа з таймерам і экспартавалі 200 карцінак.
Вось такая механіка была запраграмавана ў крыжы. Да моманту, як запусціўся фінальны адлік, мы ўсё выехалі на пляцоўку, узброіліся вогнетушыцелямі і селі чакаць пажар (які на ўсю моц палаў толькі ў дыскардзе)
Як зрабіць трансляцыю, якая працуе тыдзень: выбар камеры
Для квэста нам патрэбна была бесперапынная трансляцыя на ютубе на працягу 7 дзён - менавіта столькі мы закладвалі як максімальную працягласць гульні. Было дзве рэчы, якія нам маглі перашкодзіць:
Перагрэў камеры ад бесперапыннай працы
Абрыў інтэрнэту
Камера павінна была аддаваць карцінку як мінімум Full HD, каб гуляць і назіраць за пакоем было камфортна.
Першапачаткова мы глядзелі ў бок вэб-камер, якія выпускаюць для стрымераў. Мы рэзалі бюджэт, таму купляць камеру не хацелася, а ў арэнду, як аказалася, іх не даюць. У гэты ж момант мы цудам знайшлі ляжалую ў мяне дома камеру Xbox Kinect, паставілі ў пакоі і запусцілі тэставую трансляцыю на тыдзень.
Камера спраўлялася нармальна і не перагравалася, але Ілля амаль адразу заўважыў, што ў ёй не хапае налад, у прыватнасці нельга выставіць экспазіцыю.
Ілля імкнуўся наблізіць від трансляцыі да стандартаў кіна-відэа вытворчасці: перадаваць дынамічна якая змяняецца светлавую сцэну з яркімі крыніцамі святла, прыцемненым фонам і прадметамі ў кадры. Пры гэтым хацелася захаваць прапрацоўку выявы як у святла так і ў ценях, з мінімальным лічбавым шумам.
Таму, хоць кінект і паказаў сябе надзейным пры тэстах і яму не патрабавалася плата відэазахопу (яшчэ адна кропка адмовы), ад яго мы вырашылі адмовіцца. Пасля трох дзён тэстаў розных камер, Ілля абраў Sony FDR-AX53 – невялікі надзейны камкордэр, бюджэтны ў арэндзе, але пры гэтым які валодае дастатковай надзейнасцю і выяўленчымі характарыстыкамі.
Мы арандавалі камеру, уключылі яе на тыдзень у звязку з платай відэазахопу і зразумелі, што з ёй можам разлічваць на бесперапынную трансляцыю на працягу ўсяго квэста.
Які робіцца кіно: пастаноўка сцэны і святла
Праца над асвятленнем патрабавала вызначанай вытанчанасці, нам патрабавалася мінімальнымі сродкамі выбудаваць светлавую партытуру:
1. Падсвятленне прадметаў, калі іх знаходзяць гульцы (лазер, гіра), а таксама пастаяннае святло на Шродэр. Тут выкарыстоўваліся dedolight 150 - надзейныя і кампактныя асвятляльныя кінапрыборы з нізкавольтнымі галагенавымі лямпамі, якія дазваляюць акцэнтна сфакусаваць прамень на пэўным прадмеце, не кранаючы фон і астатнія прадметы.
2. Практычнае гульнявое святло - настольная лямпа, таршэр, зорка, гірлянда. Усё практычнае святло было гарманічна размеркаваны ў кадры, каб асвятляць сваю вобласць малюнка, усярэдзіне стаялі led лямпы з каляровай тэмпературай 3200К, лямпа ў таршэры была зачынена чырвоным фалійным фільтрам Rosco, для стварэння незвычайнага каляровага акцэнту-падказкі.
Я ў мамы інжынер ці запуск заўтра
Як мы рэзервавалі інтэрнэт і электрычнасць
Да пытання адмоваўстойлівасці падышлі амаль як у дата-цэнтры: вырашылі не адыходзіць ад асноўных прынцыпаў і зарэзервавалі па звыклай схеме N+1.
Калі на ютубе трансляцыя спыняецца, гэта значыць, што зноўку падлучыцца па той жа спасылцы і працягнуць стрым ужо будзе немагчыма. Гэта быў крытычны момант, да таго ж пакой знаходзіўся ў звычайным офісе.
Для гэтага мы выкарыстоўвалі роўтэр на базе OpenWRT і пакет mwan3. Ён аўтаматычна тэставаў кожныя 5 секунд даступнасць канала і, у выпадку абрыву, перамыкаўся на рэзервовы мадэм з Yota. У выніку пераключэнне на рэзервовы канал адбывалася менш чым за хвіліну.
Таксама не менш важна было выключыць перабоі з электрычнасцю, бо нават кароткачасовы скок напругі выклікаў бы перазагрузку ўсіх кампутараў.
Таму мы ўзялі бесперабойнік ippon innova g2 3000, які рэзерваваў бы ўсе гульнявыя прылады: сумарная спажываная магутнасць нашай сістэмы была ў раёне 300 Ват. Яго хапіла б на 75 хвілін, цалкам дастаткова для нашых мэт.
Мы вырашылі ахвяраваць дадатковым асвятленнем у выпадку, калі ў памяшканні адключыцца электрычнасць - яго да бесперабойніка не падключалі.
падзякі
Усёй камандзе РУВДС, якая прыдумляла і рэалізоўвала гульню.
Асобна адмінам RUVDS, за тое, што сачылі за працай сервакоў, нагрузка была прымальнай і ўсё працавала штатна ў звычайным рэжыме.
Лепшаму босу ntsaplin за тое, што ў адказ на званок "ёсць ідэя: мы возьмем сервер, на яго паставім акварыум, а над ім падвесім гіру, бум, бах, усё заліло вадой, кароткае замыканне, пажар!" ён заўсёды ўпэўнена кажа "рабіце!"
Дзякуй Выдавецтва Тыльда і асобна Міхасю Карпаву за тое, што ён не проста пайшоў насустрач і дазволіў парушыць Terms of use, але нават падарылі нам бізнэс-акаунт на год, калі мы распавялі аб праекце.
Ілье Сярову S_ILya за тое, што ён далучыўся і стаў супрадзюсарам праекту, гатовым поўначы поўзаць, прыклейваючы святлодыёдную стужку, шукаць тэхнічныя рашэнні і зрабіць усё, каб у нас атрымалася сапраўднае кіно.
zhovner за тое, што заўсёды быў гатовы выратаваць сітуацыю, калі іншыя разводзілі рукамі, боршчык, маральную падтрымку і размовы да раніцы.
самат за тое, што звязаў нас з лепшым пентэстэрам краіны, які пракансультаваў нас і дапамог з задачкамі.