Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 30
×

Як ми запускали OSINT-базу втрат російської техніки

Привіт. Мене звати Костя, я — UX-дизайнер, який іноді займається веброзробкою, про що люблю розповідати. Цього разу — як ми з командою волонтерів запустили та підтримуємо WarSpotting.net, OSINT-базу документованих втрат техніки — звісно ж, передусім ворожої — на цій війні. Нижче про те, навіщо ми це зробили, як будували роботу та що цікавого вдалося реалізувати, але спочатку...

FAQ

Який ще OSINT? Про що взагалі мова?

Ще пів року тому я і сам був максимально віддалений від цієї теми: чув лише про Bellingcat, якийсь там InformNapalm та про Lost Armour, на якому руzzня смакувала наші втрати починаючи з 2014. Проте лютий 2022 брутально нас зблизив: десь на другий-третій тиждень війни почав помічати в стрічці щоденні звіти одного віддаленого знайомого про втрати російської техніки, що він їх збирав по якихось невідомих каналах. Свої знахідки він передавав одному не дуже відомому на той момент блогеру, аудиторія якого при цьому зростала вибухово.

Стало зрозуміло, що існує цілий двіж ентузіастів, які ставлять за мету збір та систематизацію даних про російські втрати з відкритих джерел (власне Open Source INTelligence), та суспільний інтерес до їх роботи. Якість самих даних тим часом бажала кращого, але головне, що засмучувало, — наша лише дотична в усьому цьому участь.

Навіщо це потрібно — хіба мало звітів Генштабу?

Це питання має сенс, якщо вас цікавлять тільки цифри. І якщо вас цікавлять тільки вони, то, мабуть, цифр Генштабу дійсно буде достатньо. Проте цей проєкт не про цифри, а про дані, за якими можна шукати і отримувати відповіді на більш конкретні питання: хто саме, де саме, коли саме і що саме.

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

Хіба фоткам можна вірити? Там же фейків повно

Не можна. Але ще менше можна вірити заявам без фоток. Певні «пруфи» не проходять модераторський фільтр, деякі інші проходять його з «натяжкою». Саме фейків — фоток з якої-небудь Сирії або з 2014-2015, що видаються за нібито свіжі, — не так вже й багато. І є ще помилки з ідентифікацією. Проте дані згодом вдосконалюються, головне — почати їх систематично збирати.

Але навіщо, якщо вже є Oryx?

Для відповіді на це питання достатньо подивитись на його «дані» — і побачити купу склеєних фоток з прифотошопленими датами. Нічого знайти за ними практично неможливо. Скільки саме ворог втратив в Гостомелі? Яка динаміка втрат у небі? Це — перша проблема, яку ми взялися вирішити.

Друга — це існування різних джерел. Наприклад, той самий Lost Armour. Забігаючи наперед, скажу, що вони на 90% повторюються, проте решта 10% — це нові, відсутні на Oryx втрати, при чому, часто саме російські.

Як все почалося

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

Проблему я для себе окреслив отими двома пунктами:

  • консолідація даних з різних джерел,
  • їх доступність.

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

Сама ж база підтверджених втрат рф як доказ спроможності ЗСУ — це наша зброя в інформаційній війні, яку ворогу просто немає чим бити, тим більш частину даних РАПТОВО взято у нього самого.

Як ми працювали й, до речі, хто це — ми?

З готовими дизайнами я першим ділом пішов до товариша, з яким раніше запускали пару проєктів на Python/Django/MariaDB/JS/React: він займався бекендом, я — фронтом. Була впевненість, що і цього разу зможемо: подивились і прикинули, що десь за місяць маємо впоратись (я з майбутнього). А ще в нас було 70 ампул мескаліна трохи місця та потужностей на dedicated сервері. Все це окреслило технічний стек і подальші опції деплойменту.

За участі тимчасового консультанта з незрозумілих питань одразу ж накидали схему БД з прицілом на майбутнє:

Рішення виглядало доволі примітивним — база фоток з адмінкою — проте вже в середині квітня, коли було готово не більш як 20%, стало ясно, що удвох ми не вивозимо, і я перейшов до «плану Б». Ще один девелопер швидко знайшовся, ми зідзвонились, обговорили основне і тут же почали ділити задачі приблизно порівну.

Ось що він каже тепер, завбачливо обравши лишитись за кулісами

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

Проєкт власне всім цим і виявився.

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

Оскільки ми не писали тестів, з різних причин, було дуже складно щось порефакторити: майже кожного разу доводилось заново тестити руками всі кейси, які міг зачепити. Часто відсутність тестів ставала причиною нічого не чіпати взагалі.

Нарешті детально попрацював з Django. Більше, ніж колись до того, попрацював з реляційною БД і вперше для себе з MariaDB/MySQL. Немало довелося попрацювати взагалі з крудами, з html-формами і навіть трохи з JS. Мій попередній досвід якось це все оминав.

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

Отже для роботи удвох та більше я зазвичай заводжу репозиторій на GitHub і борд в Trello з п’ятьма стандартними кошиками. Як не обмежуй MVP, але Must чомусь при цьому все одно має тенденцію ніколи не лишатися порожнім.

У нас все по-дорослому

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

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

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

Але в середині липня я, нарешті, привітав всіх учасників з офіційним завершенням розробки та подякував — і є за що!

Що вдалося зробити

Купу всього. Окрім того, що видно неозброєним оком, це:

  • Крута адмінка. Воно й не дивно: одну форму модерації ми робили декілька тижнів. Вона апдейтить одночасно 7 різних записів: не знаю, добре це чи погано, але магія чисел зачаровує.
  • Одразу два (!) парсери, кожний заточений під окремий ресурс. Обидва можна зручно запускати з UI в адмінпанелі. Обидва повертають туди ж зручний лог.
  • Інтеграція з твіттером через Twitter API v2 для напівавтоматичної публікації дайджестів, знову ж таки, кнопкою з UI.
  • Автодеплой через Github Actions, що вирішує цілу купу проблем, якщо у вас свій сервер. Навколо нього нам довелося станцювати румбу удвох, але воно було того варте.
  • Інтегрований з бекендом Telegram-бот на базі python-telegram-bot і̶ ̶т̶а̶к̶о̶ї̶-̶т̶о̶ ̶м̶а̶т̶е̶р̶і̶.

«Ця сторінка — бос цього проєкту» ©

Що ще хочеться зробити? Багато чого. З найважливішого — подумати над захистом від атак, розібравшись хоча б у базових інструментах Cloudflare (anyone?). З найболючішого — переробити все фронтенд адмінки, бо забагато логіки розділилося між вьюхою, темплейтом і JS. Зрозуміти, що саме і за яких умов показується, вже майже неможливо.

Тим часом прикручую різноманітні зручності типу галереї або модераторських позначок, керуючись вже власним досвідом роботи з сайтом. User-centered дизайн, який я заслужив.

Що далі

Далі — робота з даними: об’єднання датасетів з різних джерел, відловлювання повторів, ідентифікація нових та деталізація опублікованих втрат за підрозділами, датами та локаціями.

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

В модераторській команді наразі четверо людей плюс інтерн. Всі з різних країн і часових поясів. Для розуміння ступеня фанатизму: в нас є людина, що спеціалізується на втратах конкретно 200-ї ОМСБр (номер символізує). Двері нашого клубу, між іншим, відчинені: якщо ви розумієтесь на техніці та подіях останніх місяців, стукайте в особисті, задачі є.

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

👍ПодобаєтьсяСподобалось15
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

На oryx російських втрат 11к, у вас 10к. Чому така різниця?

Сбор данных это хорошо. Как применяется(или будет применяться) эта база данных для построения прогностических (предсказательных) моделей аналитики?

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

Історичної цінності в тому взагалі небагато. Тим більше, якщо це дійсно лише OSINT, тобто робота з відкритими джерелами.

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

Де гарантії, що «служба побуту» не звинуватить у роботу на ворога

Це до речі можливо, бо деякі компіляції відкритих документів — можуть бути таємними, хоча самі документи окремо — відкриті. Але, думаю, малоймовірно в цьому випадку.

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

Сортування, фільтрації і графіків би ще

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

А, побачив.
Ще: Твітерські картинки не показуються, якщо у ФФ обрано рівень приватності Надійний
Може дублюйте картинку на власний сервер (заливайте на github? )

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

чекаемо на графіки per day!:)

Самому цікаво. Проте це скоріш хом’як-контент бо воно все одне буде неточним: дати втрат дуже часто невідомі, замість цього використовуємо найранішню дату зйомки. Наприклад, оце все далеко не квітень і не березень: ukr.warspotting.net/...​belligerent=2&location=15

Підписатись на коментарі