Meshtastic – оперативно-тактический радиочат без сотовой связи и интернета. Часть 3. Радиомодемы самодельные

ОГЛАВЛЕНИЕ:

Часть 1. Знакомство с темой.

Часть 2. Радиомодемы фирменные.

>>> Часть 3. Радиомодемы самодельные.

Часть 4. Сборка и прошивка радиомодема. (Запланировано)

ИЗУЧАЕМ. ДУМАЕМ. ГОТОВИМСЯ.

Уважаемые коллеги, если вы добрались до 3-ей части, и тема Meshtastic-сети вас завлекла настолько, что руки чешутся уже, наконец, что-то собрать самому, то — добро пожаловать! В этой части мы рассмотрим комплектующие для самостоятельной сборки модема и автор поделится своими схемотехническими наработками.

Как только автор статьи увидел в Meshtastic-проекте знакомые слова типа LoRa, ESP32 и другие, немедленно был проведён схемотехнический анализ фирменных Meshtastic-модемов, благо, информация не секретная и все схемы лежат в открытом доступе на GiHub проекта и страницах производителей LoRa-модулей. Выяснились интересные детали – практически все принципиальные схемы разных производителей Meshtastic-модемов типовые, строятся на основе одних и тех же LoRa-модулях, на основе одного из известных и распространённых микропроцессорных блоков ESP-WROOM-32 и ESP-WROWER-32. Так появилась мысль о том, что можно попробовать собрать радиомодем самостоятельно из DEVKIT модулей и того, что есть под рукой. Проведя несколько недель за вдумчивым исследованием темы с паяльником и компьютером, делясь мыслями с заинтересованными коллегами, выяснилось, что энтузиасты радиолюбители даже самой минимальной квалификации могут радиомодем легко собрать сами, не тратя денег на готовое устройство из возможно скромного семейного бюджета.

Ещё одним фактором влияния на ваше возможное решение заняться совместным творчеством, может стать открытость проекта для самостоятельного освоения на уровне исходного кода прошивки. Все исходные коды проекта Meshtastic выложены на Github. Прошивка радиомодема написана на С++, имеет открытое API для подключения внешних устройств, совсем недавно автор проекта включил возможность интеграции в радиомодем работу в сеть интернет по протоколу MQTT.

Автор уверен, в сообществе найдётся множество желающих развить тему до более глобального масштаба, возможно, в свои индивидуальные стороны и на новых технологических решениях. Присоединяйтесь!

СОСТАВ КОМПЛЕКТА ДЛЯ САМОСТОЯТЕЛЬНОЙ СБОРКИ

Для самостоятельной сборки минимально-рабочего радиомодема понадобятся следующие комплектующие:

  • ESP32-WROOM-32 модуль в формате DevKit – 1шт.

  • LoRa-модуль – 1шт.

  • I2C OLED LCD экран – 1шт.

В расширенном варианте радиомодема с дополнительным сервисом нужно будет добавить ещё несколько простых компонентов:

  • GPS-модуль NEO-6M или NEO-8M – 1шт.

  • Кнопка – 1шт.

  • Светодиод – 1шт.

  • Резистор, номиналом 10ком – 1 шт. 

  • Резистор, номиналом 1ком – 1 шт.

  • Конденсатор, номиналом 47…100нФ – 3шт.

  • Конденсатор электролитический 47…470мкФ – 3шт.

Кнопки со светодиодами и другую мелкую рассыпуху, автор описывать не будет, надеясь, что вы сами разберётесь в данном вопросе или спросите более компетентных друзей. А вот, информацию про основные функциональные модули рассмотрим подробно. Вполне вероятно, что у заинтересованных профессиональных коллег кое-какие компоненты уже присутствуют где-нибудь в столе и тогда, создание своего радиомодема — дело пары часов с перерывом на чай.

LoRa-модули

Обычно, LoRa-модули покупаются на Aliexpress, там они стоят не дорого, но бывает и в «робошопных» магазинах встречаются, правда, по цене в 2…3 раза выше, чем на Ali. Если у вас шило в седалищном месте и вы не стеснены в финансах, то в большом городе быстрое решение с покупкой, обычно, всегда присутствует. Модемов бывает несколько разных типов и фирм. Как было описано выше, первое – нужно определиться на каких частотах планируется построения сети. В России используется участок 433МГц и 868МГц, соответственно, модем выбираем на нужный вам участок частот. Существуют модемы и на американский участок 915МГц, но зачем нам проблемы с радио-надзорными органами?  Большинство модемов на Aliexpress — это NONAME клоны фирменных изделий, собранных по типовой схеме из datasheet на радиочип. Так же, можно найти и фирменные модели. Они стоят немного дороже и, как правило, выглядят более качественно.

Китайский LoRa NONAME

Самые распространённые маломощные LoRa-модули собраны на чипах SX1276/1278 и RFM95W/98W на частотные диапазоны 868/433МГц. Модули выпускают открытые и закрытые экраном. Закрытые экраном, понятно, лучше защищены от помех. Часто на модулях пишут про мощность +20…+22дБм – это в 99% случаев обман. Обычно модемы выдают около +15…+17дБм мощности на максимальных настройках и зависит мощность от качества деталей, из которых эти модули собраны. Обычная цена — 300…500руб.

Автор опробовал и обмерил дешёвые модули на «синих» платах с маркировкой SX1276, остался ими вполне доволен. «Зелёные» модули показали пониженную мощность, и автор их не рекомендует приобретать. В фирменных радиомодемах применяются экранированные фирменные LoRa-модули HPDTeK. К ним удалось найти даже даташит на китайском языке. В продаже на Aliexpress эти модули есть, но цена их в районе 1000р. за штуку.

Маломощные модули фирмы G-NiceRF

Маломощные LoRa-модули на чипах SX1262/1268 фирмы G-NiceRF. Собраны на новых радиочипах и имеют более качественные параметрами, обладают лучшей чувствительностью и, повышенным выходным уровнем до +22дБм. (Автор ещё не замерял, подтвердить не может) Главная особенность этих модулей – аппаратная возможность отображать уровень принимаемого сигнала в приложении. Очень удобно при развёртывании сети. Наличие в модуле высокостабильного генератора TCXO позволяет без проблем использовать узкополосные, а значит, более дальнобойные режимы LoRa. Минус – модули довольно дорогие, на Aliexpress их цена начинается от 700р.

Мощные модули фирмы G-NiceRF

Мощные модули фирмы G-NiceRF собранные на радиочипе SX1262. Мощность модулей на 868МГц заявляется около 1 Вт (+30дБм). По замерам автора с них удалось выжать +25…+27дБм при питании 5V. На 433МГц они, возможно, и дадут 1 честный Ватт. Схемотехника модуля внутри достаточно примитивна. Опять же минус — примерная цена: 1800р за 2шт. Так как их продают по 2шт, то планируйте сразу делать себе пару Meshtastic-модемов. Будет стимул привлечь в абоненты сети кого-нибудь из друзей. Хорошо подходят для необслуживаемого ретрансляционного узла, но нужно продумывать питание. Потребляют они на передачу аж 0.5А

 

Мощные модули фирмы E-BYTE

Самые качественные и мощные LoRa-модули фирмы E-BYTE на чипах SX1262. Имеют гарантированно на выходе мощность +30дБм на частоте 868МГц (Подтверждено замерами). Большой и жирный плюс к лучшему радиочипу — эти модули имеют в составе схему малошумящего усиления МШУ, что выгодно отличает эти модули по чувствительности, а значит дальности приёма. Минус – нужно самостоятельно править и пересобирать прошивку для управления режимом приём/передача (RX\TX). (Решения имеются) Второй минус – эти модули довольно дорогие, на Aliexpress их цена начинается от 900р, а в наших радиомагазинах от 3т.р.

На Aliexpress присутствует большое количество модификаций этих модулей, а в последнее время ещё и подделок. Под Meshtastic-сеть выбирать нужно конкретно модули E22_900M30S для 868МГц или E22_433M30S под 433МГц.

ESP32-модули

Для самостоятельной сборки Meshtastic-модема понадобится плата разработчика ESP32, она же именуется DevKit V1. Обычно, такие платы покупаются на Aliexpress или в местных «робошопных» магазинах. Подбираем модуль ESP-WROOM-32 DEVKIT с 30 или 38 контактами и встроенной антенной. Для максимальной простоты сборки Meshtastic-модема нужна именно DEVKIT-плата с USB-интерфейсом, а не голая плата ESP-WROOM-32. Цена на Aliexpress примерно 300…400р.

На Aliexpress сегодня появилось большое количество различных модификаций подобных DEVKIT-плат. Интерес представляют платы со встроенными Li-Ion контроллерами типа WeMos Mini D1 LOLIN32, но у автора пока отсутствует достаточное количество материала по ним.

Пожалуй, один из самых маленьких найденных ESP32-модулей – WEMOS Lite V1.0.0 Wifi Bluetooth макетная плата, антенна ESP32 ESP-32 REV1 CH340G MicroPython 4MB Micro USB для Arduino. Информации по работе этого модуля так же, пока отсутствует.

Присоединяйтесь к группе энтузиастов, возможно, конкретно вы сможете дополнить наш опыт.

GPS-модуль

Для передачи координат можно воспользоваться встроенным GPS-модулем телефона (координаты автоматически подтягиваются) или можно применить внешний модуль с Aliexpress. Ставить или не ставить модуль на самодельное устройство – вопрос открытый и выбирается от конкретных условий использования радиомодема. GPS-модулей на Aliexpress так же, великое множество, разной цены и комплектации. Для построения расширенной версии радиомодема достаточно простых модулей типа NEO-6M или NEO-8M. Выбирать модули желательно с большой квадратной антенной. С ней спутники ловятся быстрее и координаты в мобильном варианте фиксируются стабильнее. К сожалению, на Aliexpress сейчас большое количество контрафактной продукции с негативными отзывами конкретно на GPS-модули, потому, конкретных ссылок на магазины автор не даёт, так как сам пару раз попал на не рабочие подделки.

I2C OLED LCD экран

Самый простой и распространённый графическом дисплей на процессоре SSD1306. Понадобится для Meshtastic-модема без дисплея или для самостоятельной сборки. На дисплее отображается код для сопряжения телефона с радиомодемом по ВТ и разнообразная сервисная информация. При работе со смартфоном или на ретрансляционном узле экран особо не нужен и для большей автономности модема его можно делать на разъёме, снимаемым. Продаётся в разных «робошопных» магазинах, на Aliexpress и даже на AVITO можно найти горсть экранов за шапку сухарей.


РАДИОМОДЕМ — СХЕМА ЭЛЕКТРИЧЕСКАЯ ПРИНЦИПИАЛЬНАЯ

Итак, ожидания доставки комплектующих с Китая закончилось? Все комплектующие наконец приехали? Будем надеяться, что вам прислали рабочие изделия, а не контрафакт в целости и сохранности. Теперь, заказанные модули надо собрать воедино — то есть спаять их. Минимальный вариант быстро получить результат – это спаять всё на проводках типа МГТФ (так сказать сколхозить на коленке доступно всем и каждому) или всё сделать чинно-благородно на ардуино-образной плате.

Работы над созданием полноценных печатных плат под разные вариации самодельного радиомодема в сообществе уже ведутся, автор статьи планирует в ближайшем будущем представить свой концепты. Если вы профессиональный разработчик РЭА, умеете мастерски в ALTIUM, KiСAD или, даже в EasyEDA, то добро пожаловать в сообщество, вы можете представить свои варианты печатных плат. Все от этого только выиграют, особенно Китайцы… 🙂

На настоящий момент автор статьи готов поделиться своими схемотехническими наработками. Если вы практикующий радиолюбитель-конструктор, то для самостоятельной сборки Meshtastic-модема их вполне достаточно:

Схема радиомодема для модуля ESP32-PICO-D4 под прошивку TTGO Lora32
Схема радиомодема для модуля ESP32-DEVKIT-30 под прошивку TBeam 0.7
Схема радиомодема для модуля ESP32-DEVKIT-38 под прошивку TBeam 0.7
Схема радиомодема для модуля ESP32-DEVKIT-30 под прошивку Heltec V2
Схема радиомодема для модуля ESP32-DEVKIT-38 под прошивку Heltec V2
Схема радиомодема для модуля ESP-Lolin32 под прошивку TTGO 0.7 (не проверялось!)

Скачать все схемы высокого качества одним файлом PDF можно с Я-диска

У пытливого читателя может возникнут резонный вопрос: а какая из схем лучше? Однозначного ответа на данный вопрос нет. Все схемы рабочие, радиомодем работает на любой из них под соответствующей прошивкой. Выбор дан для расширения охвата потенциальных абонентов Meshtastic-сети. Никто не знает, что у вас есть в рабочем столе. У одного конструктора может быть один модуль, у второго – другой, у третьего – третий. Главное – автор протестировал работоспособность всех схем. Они будут работать с постоянно обновляемыми релизами прошивок (если автор проекта что-то в коде специально не поменяет или ненароком не сломает).

Первым из доступных DEVKIT-модулей ESP32 у автора оказался ESP32-PICO-D4. Как выяснилось – это самый беспроблемный ESP32-модуль, и он «завёлся» моментально. С модулями ESP32-Devkit-30/38 пришлось немного повозиться и разобраться как они работают на разных версиях прошивок. В результате экспериментов, было решено остановиться на описанных вариантах схем для прошивок Heltec V2 и TTGO V0.7.

Для запуска в расширенном функционале удобнее схема на основе модуля ESP32-DEVKIT-38, т.к. на ней присутствуют все выводы, описанные в прошивке. Так, для прошивки Heltec V2, запустить расширенную версию схемы на плате с 30 пинами без самостоятельной правки и сборке прошивки не получится – на плате не предусмотрен вывод DIO 0, к которому подключается кнопка.

В настоящий момент идут работы по проверке схемы на основе платы Lolin32 и Wemos Lite.

Рабочий вариант быстрого старта типа «колхоз на коленке»

ПИТАНИЕ… ПИТАНИЕ…

В заключении остановимся на важном моменте. Остаётся открытым вопрос энергоэффективности и питания радиомодемов. В первой части введения говорится о сверх длительном времени работы радиомодемов. Для этого в фирменных радиомодемах на аппаратном и программном уровнях проведена колоссальная работа по оптимизации энергопотребления. Наиболее продвинутые в аспекте энергоэффективности – модули TTGO T-beam. В схемотехнике радиомодемов T-beam применён специальный высокоэффективный контроллер питания, который управляет всеми потребителями энергии по программе. Когда радиомодем простаивает – все потребители электроэнергии уводятся в сон. Более простые модули T-Lora32 не имеют контроллера питания, но подключаемых к процессору модулей, на этих платах меньше, сам процессор ESP32 при этом погружается в сон во время простоя. Для всех радиомодемов время сна и время рассылки о своих координатах можно настраивать в приложении.

Для максимального упрощения схемотехнической части и расширения возможного круга интересантов темы, автор умышленно опускает вопрос энергоэффективности и предлагает ограничиться на первом этапе конструирования питанием от USB разъёма модулей ESP32. Вторым этапом может быть переход на новые платы ESP32, в которых уже встроен контроллер Li-Ion батареи и цепочки заряда/разряда. Питание можно делать от аккумуляторов, от солнечных элементов или стационарное.

При дальнейшем самостоятельном развитии сети, нужно будет вопрос энергопотребления прорабатывать отдельно. Туда можно отдельно включить вопрос энергопитания необслуживаемого ретрансляционного узла, постоянного узла, например, на автомобиле или велосипеде, другие интересные варианты… 

В настоящем состоянии развития темы в Российской группе энтузиастов эти темы пока не поднимались особо ввиду малочисленности группы. Автор предлагает этот вопрос решать совместно. 

В следующей статье, мы рассмотрим поэтапно как «залить» в модем прошивку и войти в сеть.

ВАЖНОЕ ПРИМЕЧАНИЕ:

  1. Все схемы и описания представлены «как есть», большая часть схем проверена в работе. Если вы нашли ошибку, обязательно сообщите об этом автору статьи.

  2. Автор статьи предполагает, что берясь за паяльное дело, вы чётко себе представляете что делаете и как нужно делать. Если у вас после сборки что-то не работает, вы консультируетесь со своими более компетентными друзьями, или в сообществе.

  3. Во время творческих изысканий, вы соблюдаете все правила техники безопасности при работе с электроустановками, с паяльно-монтажным оборудованием и слесарным инструментом.

Часть 1. < Часть 2. <<<<< Часть 3. >>>>> Часть 4. Сборка и прошивка радиомодема (Запланировано).

ссылка на оригинал статьи https://habr.com/ru/post/568534/

Как ФБК* сами слили все данные оппозиции в открытый доступ

* — Фонд борьбы с коррупцией включён в реестр НКО, выполняющих функции иностранного агента, по решению Министерства юстиции РФ от 09.10.2019; организация признана экстремистской, её деятельность запрещена на территории России по решению Мосгорсуда от 09.06.2021.

Привет! Здесь я хочу указать на возможную причину, почему были слиты данные зарегистрировавшихся в УГ и предупредить, что ФБК* на несколько недель в июне была открыта, как эта калитка в меме. Сразу после того, как эта дыра была обнаружена, я написал ФБК*, и доступ до инфраструктуры они починили. Пишу об этом сейчас — уже после того, как набор почт от УГ был выставлен на продажу, а затем слит — по двум причинам: считаю недостаточным простое умалчивание происходившего и происходящего, (и понимаю, что писать об этом нужно было раньше), но сам ФБК* самостоятельно не сильно хочет говорить о том, что происходило у них с безопасностью в середине-конце июня.

Сразу дам дисклеймер — я мало разбираюсь в информационной безопасности, а все, что здесь откопал — продукт внимательности, небольшого опыта пользования k8s, метода «почему бы и нет» и чистой удачи. 

Как было найдено

На почту мне пришло сообщение с доменом «rus.vote» с темой «Умное голосование», что изначально показалось подозрительным: какой-то непонятный, короткий домен, не напомнивший что-то, что использовал бы ФБК*. Первой же идеей в этот момент было сначала найти домен в Google, и она увенчалась успехом, ведь на второй странице поисковика красовалась проиндексированная KubeWebView — вебпанель для доступа до инфраструктуры Kubernetes.

Прошу заметить одну интересную деталь про этот результат — он начинается с www — эта ошибка в конфигурации домена в сервисе дашборда, а значит таких доменов, как www.rus.vote, должно быть больше. Вот еще примеры доменов, что удалось найти, которые указывали на сервис вебпанели и спокойно искались в Google/Duck по запросу «Kubernetes Web View», сейчас они все кидают 404:

  • www.k8s.fbk.info

  • new.fbk.info

  • navalny.blog

  • presobol2021.k8s.fbk.info

Здесь показан более поздний процесс поиска в DuckDuckGo
Здесь показан более поздний процесс поиска в DuckDuckGo

Что было найдено

Что открывается человеку, который зашел в вебпанель Kubernetes? — Достаточно много информации о состоянии системы, железе, участвующем в кластере, логам запущенных сервисов, секретов (если те не были скрыты), значений в environment’е,… Первое, что я увидел были staging кластер, на котором было запущено много разных сервисов и удобная кнопка экспорта в формат tsv или yml в зависимости от данных:

Все поды, запущенные на кластере ФБК*
Все поды, запущенные на кластере ФБК*

Из всех подов, что я обнаружил, самыми интересными оказались:

  • Сервис ganimed — в логах было много почт, которым отправлялись письма с шаблоном «emails/email_confirm.html», «emails/email_singer_observer_confirm.txt»

  • Сервис headquarters — в логах опять почты и упоминание shtab@navalny.com

  • Другие поды: в основном всегда пара или тройка сервисов из фронта и бэка на django

  • Secrets и ConfigMaps

Логи ganimed

Это оказалось одной из самых интересных находок-комбинаций факторов: на бэке не был отключен дебаг, KubeWebView не смог скрыть почты, разработчики ФБК* решили логгировать все почты, на которые они высылали письма, в том числе и от УГ.

Для небольшого теста (reality check, а вдруг нашел кластер для разработки, и все не так плохо) я послал запрос на регистрацию на УГ с помощью почты «test@test.com»

В логе я сразу обнаружил:

ganimed-django-rq-685597bfd4-k2jsh main 2021-06-24T17:43:43.822640701Z 20:43:43 high: landing.tasks.email.send_confirmation_email_async(confirm_url='https://votesmart.appspot.com/email-confirm/91c30631f88e4b6b8d65/', html_template='emails/email_confirm.html', subject='ÐожалÑйÑÑа, подÑвеÑдиÑе поÑÑÑ', to='test@test.com', txt_template='emails/email_confirm.txt') (8c2e27a7-2bde-4b0f-b759-7d1952a69b7b)

Видеть это было больно, а таких логов там было на 40 дней. Вверху окна с логами в дашборде можно было указать фильтр и кол-во линий для вывода: таким образом можно было стащить хорошее количество почт, и данных когда и что именно на эту почту было выслано.

Секреты в ConfigMaps

Следующее, что я решил откопать — были секреты. Их положение было сразу известно — это ресурс Secrets. К счастью для ФБК*, все секреты в ресурсе Secrets были скрыты — на это указывал issue в репо KubeWebView и наши находки:

apiVersion: v1 data:   CELERY_BROKER_URL: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   DJANGO_DB_HOST: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   DJANGO_DB_NAME: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   DJANGO_DB_PASS: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   DJANGO_DB_USER: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   FB_PASSWORD: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'   FB_USERNAME: '**SECRET-CONTENT-HIDDEN-BY-KUBE-WEB-VIEW**'

Но.. у разработчиков есть всегда другой источник переменных данных — environment, или в интерпретации от Kubernetes — ConfigMaps. В итоге разработчики ФБК* успешно использовали их для хранения секретов… удобно видимо. Иронично, что в конфигмапах elections-api я обнаружил это:

apiVersion: v1 data:   ANTICAPTCHA_CLIENT_KEY: 8c12***4a   CANARY_HOST: https://canary.navalny.com   CANARY_SERVICE_KEY: 1e***79   CIK_API_HOST: https://cik-api.navalny.com   DB_HOST: 10.***   DB_NAME: ele***i   DB_PASS: O***8   DB_PORT: '5432'   DB_USER: django   ELASTIC_HOST: ela***db   ELASTIC_PORT: '9200'   FROM_EMAIL: info@rus.vote   # ирония:   MAILGUN_API_KEY: 3***1d

Как и другие данные — доступы до внутренних сервисов; доступы до БД; ключи от сервисов Amazon, Google, ботов Telegram; пароли от Facebook и Instagram — ключ от mailgun оказался рабочим и часто используемым.

Выводы и пожелания

Эта калитка (а точнее несколько) в врата оппозиции висела на Google и других поисковиках больше, чем 10 дней на момент починки дыры безопасности:

23 июн 2021 11:05:54 GMT как пример - на одной из таких страниц была указана дата 13 июня
23 июн 2021 11:05:54 GMT как пример — на одной из таких страниц была указана дата 13 июня

В связи с этим хотелось бы получить ответ на несколько простых вопросов:

  • Кто, когда и сколько раз ходил на этот ресурс извне ФБК*

  • Какие данные могли быть слиты кроме того, что я представил в статье

  • И самое важное: почему вы молчите?

Сейчас было слито порядка 20 тысяч (в источниках фигурирует цифра 200 тысяч) почт, сколько данных еще в запасе у людей с корыстными мотивами — неизвестно.

P.S.: как уже было сказало, я написал ФБК* сразу как обнаружили эту дыру (Thursday, June 24th, 2021), они даже отписались о том, что приняли меры и сменили ключи в конфигмапах. Эта статья с ними не согласована.

P.P.S.: с звездочкой при названии организации я не согласен.

ссылка на оригинал статьи https://habr.com/ru/post/568842/

Автоматизация UI-тестирования в приложении Недвижимости на Android. Доклад Яндекса

Чем больше процессов тестирования автоматизированы, тем эффективнее релизный пайплайн и тем быстрее пользователи получают новые возможности в сервисе. Руководитель Android-разработки Яндекс.Недвижимости Александр Рогов вспомнил, как эволюционировало UI-тестирование в его команде, как разработчики пришли к идее автоматизации, почему использовали фреймворк Espresso, с какими проблемами столкнулись и что в итоге получили.

— Начать хотелось бы с небольшого исторического экскурса. Когда я пришел в команду, она была маленькая, из двух-трех человек. Был один менеджер, один тестировщик. Релизы катились редко, примерно раз в месяц. Релиз обычно был прикреплен к какой-то фиче. Пока фичу не сделаем, релиз не случался. Соответственно, каждый релиз у нас было регрессионное тестирование. Такой неспешный режим работы нас всех устраивал, все было хорошо.

Но продукт начал развиваться, команда начала увеличиваться, менеджеров становилось все больше. И у менеджеров появился конфликт интересов, чью фичу катить, к чьей фиче привязывать релиз и так далее. Мы решили, что надо принимать меры, а именно — ускорять наш процесс, исправить наше узкое место в виде тестирования.

Как я уже сказал, команда тестирования была маленькой, регулярные регрессы, и все это очень сильно нам мешало делать частые релизы. Что можно было поделать?

В принципе, можно было отказаться от регрессионного тестирования и довериться разработчику. С точки зрения разработки это самый оптимистичный сценарий, ничего никому делать не надо, все круто. Но с точки зрения продукта не хотелось идти таким путем. Можно было увеличить команду тестирования, но здесь бизнес был против. Это логично, потому что вариант не особо перспективный. Кодовая база все равно растет. Соответственно, команда тестирования тоже стала бы бесконечно расти.

Другой вариант — выборочное тестирование, когда мы на релизе проверяем только ту часть приложения, в которой были изменения. Это вариант получше, но не хотелось оставлять без внимания остальные участки нашего приложения. Хотелось быть уверенным, что мы там ничего не поломали.

И здесь как раз появляется идея автоматизации тестирования. На самом деле, в процессе автоматизации тестирования мы планомерно перебрали все эти варианты. Переход с регрессионного тестирования проходил примерно так, что количество покрытых тестов увеличилось, выборочное тестирование уменьшалось, и даже чуть-чуть увеличилась команда тестирования.

Автоматизация UI-тестирования

Мы решили заняться написанием инструментальных тестов. Это тесты, которые прогоняются на эмуляторе или устройстве. В их основе лежит класс Instrumentation, который предоставляют средства мониторинга взаимодействия приложения и системы.

И в отличие от обычных UI-тестов, как я уже сказал, они прогоняются на реальном устройстве. То есть поднимается Application, запускаются тесты.

Для написания таких тестов мы решили использовать фреймворк Espresso, его разрабатывает Google.

Он позиционируется как очень простой и удобный инструмент для написания стабильных тестов. Рассмотрим некоторые основные компоненты Espresso. Здесь есть так называемые ViewMatchers — средства, которые позволяют нам искать элементы на экране.

ViewActions позволяют нам взаимодействовать с найденными элементами, а ViewAssertions — это некоторые проверки, которые мы можем выполнять с найденными элементами.

В качестве примера будем рассматривать простенькое приложение, в котором есть два экрана. Вводим пароль на одном, нажимаем кнопку «Проверить». Идем делать сетевой запрос. На втором экране отображаем результат нашей операции.

Пример такого теста будет выглядеть примерно так.

Рассмотрим основные части этого теста. Есть некоторые Rules, которые позволяют нам модифицировать процесс исполнения теста. Например, ActivityTestRule позволяет нам в начале каждого теста запускать Activity и выделять соответствующие ресурсы.

А в теле теста выполняются такие простейшие манипуляции. Мы находим элемент, выполняем, например, ввод текста.

Находим следующий элемент с кнопкой, выполняем нажатие.

Находим следующий элемент с результатом, проверяем его. Примерно так может выглядеть базовый тест Espresso.

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

Можно проваливаться по пакетам, по тестам.

Можно посмотреть ошибки.

Для ошибок выводится самый простой crash logs, ничего особо интересного.

Проанализировав все эти средства Espresso, мы выделили для себя недостатки. Например, изолированность. По умолчанию все тесты Espresso прогоняются в рамках одного инстанса Instrumentation и, соответственно, одного инстанса Application. Также нет никакой изолированности от внешней среды, такой как интернет. И от других сторонних приложений. Мы подробнее поговорим об этом дальше.

Хрупкость тестов. Вы наверняка слышали, что любые UI-тесты достаточно хрупкие, подвержены факторам, которые приводят к их так называемым флакам. Также мы выделили себе такой пункт, как медленное исполнение UI-тестов по сравнению с юнит-тестами. Здесь нам предстояло подумать, как мы сможем прогонять их достаточно часто, чтобы отлавливать актуальные проблемы и оперативно на них реагировать.

Также нам не очень понравилось, как пишутся такие тесты. Нам показалось, что они достаточно многословны. И нам не понравился отчет. Обо всем этом подробнее мы и поговорим. Посмотрим, что мы делали, чтобы решить эти проблемы.

Изолированность между тестами

Как я уже сказал, по умолчанию все тесты запускаются в одном инстансе Instrumentation, но существует средство, которое позволяет эту проблему решить: Android Test Orchestrator.

Это инструмент, который позволяет запускать каждый тест изолированно от остальных, в своем инстансе Instrumentation. Для каждого теста будет запускаться свой Application. Не будет никакого разделяемого состояния между тестами.

Даже если нам необходимо почистить базу данных, мы можем использовать специальные флаги, как здесь на слайде, clearPackageData. Это позволит нам максимально изолировать тесты друг от друга.

Концептуально это выглядит так: вместе с APK тестов и приложения устанавливается еще Orchestrator, и он управляет процессом исполнения тестов: поодиночке запускает каждый тест в своем инстансе Instrumentation.

Из плюсов, как я уже сказал, — максимальная изоляция состояния. Также получаются изолированные крэши. Поскольку каждый тест исполняется в своем Instrumentation, то если он падает по какой-то причине, то остальные тесты продолжают исполняться. В каком-то смысле повышается стабильность наших тестов. Из минусов: значительно замедляется исполнение тестов, так как на каждый тест мы запускаем свой инстанс Application.

Изолированность от внешней среды

Все современные приложения ходят в сеть, поэтому мы подвержены такому явлению, как отсутствие интернета. Что делать, если интернет пропал и тесты начинают падать? Нестабильные тесты — не то, к чему мы стремились. Мы хотели добиться максимально стабильного исполнения тестов, чтобы не тратить время на ненужные нам разборки.

Здесь мы решили использовать MockWebServer. Мы в своем проекте используем библиотеку OkHttpClient для сетевого взаимодействия. В ней есть модуль MockWebServer. Идея была запускать некий локальный WebServer и направлять все сетевые запросы нашего API на localhost.

Для реализации нам потребовалось переопределить Application для тестов.

Мы унаследовались от нашего реального Application.

Определили некий Dispatcher, куда мы будем мокать наши запросы. Запустили WebServer.

Далее нам необходимо, чтобы в тестах запускался именно наш тестовый Application, а не реальный.

Для этого нужно переопределить AndroidJUnitRunner, сделав кастомный, у которого есть специальный метод newApplication, позволяющий подменить реализацию на нашу тестовую.

Следующей задачей для нас стало перенаправить все наши сетевые запросы на localhost. Для этого нам помог Dagger 2, который мы используем в проекте.

Здесь все по аналогии. Есть некоторый Application-компонент, для теста мы создаем TestApplication-компонент, который наследуется от Application-компонента, но использует другие модули сетевого взаимодействия.

Вот пример такого модуля.

Оба модуля используют базовые сетевые модули, но предоставляют разную реализацию endpoint и OkHttpClient. Вот наш сетевой модуль, который как раз использует эти компоненты.

Когда мы запускаем что-то в тестах, то ходим на localhost.

Когда мы запускаем prod в сборку, то мы идем на продовый endpoint.

Что получилось в тесте? Добавляется вот такой блок для конфигурации WebServer. Здесь мы используем простенький DSL, в котором мы обращаемся к Instrumentation, получаем Application, кастуем его к нашему тестовому, и оттуда уже можем обращаться к его полям.

Помните, мы определили там Dispatcher? Какие плюсы? Такой подход позволяет нам изолироваться от внешней среды и тем самым повышается стабильность. Наши тесты становятся независимыми от интернета и перестают неупорядоченно падать.

Из минусов: необходимо готовить Mock’и ответов. Порой они бывают очень громоздкими, это повышает трудоемкость.

Пару слов об изоляции от внешних приложений. Здесь у Espresso есть отдельный модуль под названием Espresso-Intents. Он позволяет нам записывать ожидаемые Intent, которые запускает наше приложение, и мокать их ответ. Но на этом мы не будем подробно останавливаться.

Улучшаем восприятие теста

Помните, я рассказал, что нам не понравилось, как пишутся Espresso-тесты и нам хотелось добиться чего-то более лаконичного? Изначально планировалось, что команда тестирования будет смотреть код наших тестов и таким образом валидировать их.

Пример. Если посмотреть на наш тест, то видно, что для совершения простых действий — введи текст, нажми на кнопку и так далее — нам приходится совершать много манипуляций.

Здесь нам на помощь пришли так называемые тестовые роботы. Идея этих роботов: мы пытаемся отделить то, что мы делаем, от того, как мы это делаем. Появляются высокоабстрактные методы взаимодействия, которые скрывают от нас детали реализации.

Пример такого тестового робота мы можем посмотреть здесь. Тестовый робот — это дополнительная абстракция, представляющая собой часть пользовательского интерфейса, для которой характерен набор неких базовых действий.

Например, в нашем случае на первом экране ввода пароля есть действие «ввести пароль» и действие «нажать на кнопку». Мы посмотрели и поняли: было бы удобно переиспользовать алгоритмы поиска элементов на экране, и тоже выделили их в отдельную абстракцию, которую мы назвали Lookup.

Таким образом, получается базовый тест, который был разбит на робота и Lookup и преобразился примерно так.

Что мы видим теперь? Появились некоторые контексты, мы видим два экрана. Для каждого экрана мы создали своего робота. В каждом роботе есть функциональность, характерная для этого экрана. В тесте мы теперь можем это четко наблюдать. Есть некоторое разделение по контексту, тесты стало проще воспринимать.

Как я уже сказал, появилась декомпозиция — по функциональности, по Matchers. Из минусов: появляются Boilerplates по написанию роботов. Поговорим о нем более подробно чуть позднее.

Стабильность Espresso

Поговорим про стабильность Espresso и поймем, за счет чего она достигается. Google позиционирует свой фреймворк как инструмент для написания стабильных тестов.

В основе этгого лежит следующий подход. Каждый раз, когда мы вызываем onView и пытаемся выполнить какие-то действия или проверки, они не будут выполнены до тех пор, пока очередь сообщений основного потока не будет пуста, либо не будет выполняться никаких AsyncTask, либо все так называемые IdlingResource будут находиться в состоянии idle.

Первые два пункта, очередь сообщений и AsyncTask, — это компоненты, которые известны системе Android, и она может их сама контролировать. Но существует множество других ресурсов, о которых Android не знает и не понимает, как их контролировать. Поэтому здесь вводится дополнительная абстракция IdlingResource. Этот инструмент предоставляет разработчику возможность определять такие асинхронные операции и сообщает фреймворку Espresso, что пока исполнять нельзя тест.

В качестве примера такого ресурса рассмотрим OkHttp3IdlingResource. Так как мы применяем библиотеку OkHttp, то можем без проблем использовать и его тоже. Подключить к нашему тесту можно с помощью Rules, о которых я уже говорил.

Здесь используется тип ExternalResource. Его особенность в том, что он выполняет действия до исполнения теста и после.

А создать такой ресурс можно опять-таки на основе доступа к нашему тестовому контексту, из которого мы можем получить OkHttpClient. Это реализовывается средствами Dagger.

Пример использования. Нам необходимо добавить такой Rule в тест. Для этого используется RuleChain, то есть цепочка Rules.

В цепочку можно добавлять сколько угодно правил.

Из плюсов IdlingResource: у пользователя появляется возможность размечать асинхронные ресурсы и тем самым повышать стабильность своего приложения. Из минусов: не всегда просто эти ресурсы реализовать. Природа наших приложений может быть в значительной степени асинхронной, не все ресурсы могут быть легко доступны из тестового кода, и здесь могут возникать проблемы.

Что же делать, если использование IdlingResource затруднительно? Мы хотим добиться написания стабильных тестов, но сейчас, например, не можем себе позволить реализовать IdlingResource во всех местах приложения.

Мы, например, использовали вот такой известный костыль. Грубо говоря, это цикл, в котором мы проверяем, не выполнилось ли наше условие, не оказались ли мы в ожидаемом состоянии. Если по истечении заданного интервала мы не оказались в ожидаемом состоянии, то тест падает. За счет этого простого инструмента, который не рекомендуем к использованию, а рекомендуем все-таки использовать IdlingResource, нам удалось добиться значительной стабильности исполнения наших тестов.

Как использовать это в тесте? Предположим, мы нажали на кнопку «проверить пароль», переходим на вторую Activity, и на ней мы, прежде чем выполнять проверку, можем дождаться — действительно ли элемент появился на экране? Если да — выполнить проверку. Интеграция такой конструкции в тесте выглядит достаточно лаконично. Чуть-чуть избыточно, но что делать.

Из плюсов: простой способ повышения стабильности. Из минусов: в тестах появляется дополнительный код, и теоретически, это может негативно повлиять на время исполнения тестов, привести к дополнительным простоям.

Улучшаем отчет

Еще одним пунктом, о котором я говорил, был отчет. Нам не понравился базовый отчет, нам хотелось большего: проще узнавать, в чем проблема, быстрее реагировать на возникающие сложности.

Здесь мы решили попробовать использовать фреймворк построения отчетов Allure. Легковесный, предоставляет дополнительные средства построения отчета. Интеграция Allure происходит очень просто. Достаточно унаследоваться от их AllureAndroidJUnitRunner, и это уже позволит вам строить отчет. Также в Allure предоставляется базовый набор Rules. Например, есть ScreenshotRule, WindowHierarchyRule, LogcatRule. То есть, если у вас происходит тест, к нему автоматически будут добавлены скриншоты, логи из Logcat, иерархия представлений. Уже можно будет проанализировать результаты, информации чуть больше, чем в случае с Espresso.

Генерация отчета происходит либо из командной строки, либо с помощью Allure Gradle plugin.

Отчет выглядит примерно так. Опять-таки, мы видим, сколько тестов выполнилось, сколько нет и сколько они выполнялись по времени.

Можно проваливаться в тесты.

Увидеть, как раз на этом скриншоте, что к сфейленному тесту добавилась дополнительная информация. Еще одна интересная возможность, которую предоставляет Allure: накопление информации и ведение статистики. То есть когда вы агрегируете Allure-отчеты в одном месте, можно вести настоящий трекинг того, как проходило ваше тестирование, как вы фиксили проблемы, как они появлялись, исчезали и так далее.

Но еще одна важная особенность Allure-отчетов — средства документирования, которые он предоставляет. Это специальные средства, которые позволяют размечать ваш тест так, чтобы его шаги или особенности его исполнения попадали в этот отчет либо с помощью аннотаций, либо с помощью классов, если аннотации нам не подошли.

Мы были очень заинтересованы в том, чтобы получился более документированный отчет, чтобы команда тестирования смотрела не в код наших тестов, а в отчет и понимала, что там происходило.

Для этого мы решили создать прослойку между основными компонентами Espresso, которые мы назвали именованные компоненты.

Это просто обертка, которая добавляет имя. Таким образом появились обертки для Matchers.

И для Assertions, и для Actions.

И для Interaction. Входной точкой для наших тестов стал уже не Espresso#onView, а NamedViewInteraction#onView.

Идея была в том, что для всех действий добавляется человекопонятное имя, которое будет отражено в отчете с помощью команды step, которую здесь можно видеть.

То есть каждый раз, когда мы выполняем проверку, в отчете будет зафиксировано, что именно мы проверяем.

Также мы модифицировали всех наших роботов, добавив в их входную точку команду step, которая говорит, что начинается активность. И модифицировали все наши Lookup — добавили к ним человекопонятные имена.

Это привело к тому, что сгенерировался вот такой отчет, из которого уже можно понять, что и в каком контексте происходит, что и куда мы вводим.

Тестирование может прочитать этот отчет и понять, какой пользовательский сценарий мы этим покрыли.

Также здесь можно видеть, на каком шаге произошла ошибка. Нам это очень понравилось.

Из плюсов: появилась функциональность по конфигурированию отчета и некая автодокументируемость. Из минусов: необходимо решить инфраструктурные задачи: например, как мы строим этот отчет, как храним и передаем файлы Allure. Также замедляется время исполнения тестов, поскольку появляется больше работы с файлами, мы начинаем хранить скриншоты и так далее.

Качество тестов

На этом этапе у нас уже был какой-никакой подход к написанию тестов. Они были достаточно стабильными. У нас уже был отчет, и мы стали задумываться, насколько качественно мы вообще проверяем UI?

Ведь если бы проверял тестировщик, он смотрел бы не только на то, что написано в поле, что это хороший пароль. Он проверял бы, как элемент расположен на экране, смотрел бы на цвет текста, на шрифт и так далее. Мы подумали над этим, и вот пример такой проблемы. Кто-то поменял верстку. Или мы обновили какую-то библиотеку, и верстка поехала, constraint сломался, или еще что-то.

Текущий тест на эту проблему никак не реагирует, но тестирование в ручном режиме смогло бы ее обнаружить. Мы пришли к тому, что решили сравнивать скриншоты.

Для этого мы написали простой Interaction и абстракции в стиле Espresso.

Выглядит это примерно так. В роботе появляется функциональность по сравнению скриншотов. Что произошло в отчете?

В отчет в случае ошибки мы добавляем то, что ожидали увидеть, то, что получили, и diff.

Теперь мы проверяем не то, что конкретная строка совпадает, а общее расположение элементов, их композицию на экране.

Из интересного можно отметить, как в принципе стоит сравнивать скриншоты, ведь мы делаем скриншоты-эталоны на одном эмуляторе, а сравниваем неизвестно где, на CI. Следует уделить влияние конфигурации ваших эмуляторов, именно тех, на которых вы делаете скриншоты, чтобы они совпадали с теми, на которых вы эти тесты прогоняете.

На что следует обратить внимание? Конечно, на форм-фактор, то есть на размер вашего экрана и режим отрисовки. В нашем случае нам необходимо было выключить GPU и скрыть кнопки. Если этого не сделать, у вас могут появляться различные артефакты из-за разницы реализации anti-aliasing в той или иной среде.

Скриншоты позволили нам проводить комплексную проверку UI. Написание тестов в целом ускорилось, потому что нам больше не надо было делать много разных проверок, достаточно было делать одну. Но опять появился ворох новых инфраструктурных задач, таких как хранение скриншотов, создание эталонов и прочее. Также это привело к тому, что тесты значительно замедлились: стало еще больше работы с файлами и появилось сравнение скриншотов.

Улучшаем тестовых роботов

Я говорил, что у нас были претензии к роботам, некоторый Boilerplate, и мы пришли к осознанию того, что это тоже хотелось бы поправить.

Посмотрим на проблему. Предположим, появляется новая функциональность. Например, мы захотели проверять, что элементы — кнопка или поле ввода — видны. Тогда в соответствии с подходом робота нам надо эту функциональность вывести в робот.

Потом на экране неожиданно появилась еще одна кнопка, и для нее мы тоже должны продублировать функциональность по нажатию и проверке видимости.

Или вдруг появился еще один робот, и возникают еще какие-то кнопки, поля ввода. Здесь мы тоже дублируем функциональность, которая по сути имеет одну и ту же реализацию. Изменяется лишь Matcher, который мы используем.

Здесь, вдохновившись подходом из библиотеки Kakao, мы пришли к так называемому компонентному подходу.

Идея компонентного подхода: мы выделяем функциональность не в робота, а в компонент. Роботы заменяются так называемыми Screens. Каждый Screen представляет какую-то часть UI по аналогии с роботом, но хранит набор компонент, которые есть в этой части UI.

Базовый Screen предоставляет базовую функциональность.

Базовые компоненты тоже представляют какую-то функциональность, а конкретный компонент, например EditText, предоставляет функциональность по вводу текста.

А в тесте получилось следующее.

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

Нас этот подход устроил. Прежде всего потому, что мы хотели ускорить написание тестов, снизить количество Boilerplate-кода. А для команды тестирования у нас уже были отчеты, которые позволили им больше не смотреть в тело теста без лишней необходимости. Минус я уже отметил: понизился уровень абстракции.

Время исполнения тестов

Наверное, вы заметили, что многое из того, что мы делали, негативно влияло на скорость выполнения. Что же делать?

Количество тестов растет, мы используем Orchestrator, waitUntil, Allure и так далее, замедление усиливается. Рассмотрим несколько вариантов. Можно делать частичное исполнение тестов. Например, мы не всегда прогоняем все тесты на каждый пул-реквест, на каждый коммит, а начинаем прогонять их порциями.

Либо мы реализовываем параллельное исполнение тестов с достижением необходимого, желаемого времени исполнения. Мы решили покопать в сторону этого варианта, посмотреть, что мы можем сделать с точки зрения параллельного исполнения.

Существует средство шардирования исполнения тестов через AndroidJUnitRunner. Однако оно доступно только из командной строки. Нам этот вариант тогда показался не очень удобным. Мы еще немного покопали в сторону сторонних фреймворков — например, Spoon. Но втягивание сторонних фреймворков нам казалось избыточным.

Есть Gradle-команда — выполняешь и получаешь список подключенных устройств. Разделяешь тесты по этим устройствам, исполняешь их на этих устройствах. Собираешь результат. Хотелось добиться чего-то такого, казалось бы, простого. Зачем здесь отдельный фреймворк?

Решили попробовать сделать нечто подобное. Для этого мы написали свой Gradle-таск, в основе которого так называемый Worker API Gradle. Его идея в том, что существуют специальные абстракции: WorkerExecutor, который позволяет параллельно исполнять некоторые подтаски в рамках одной корневой таски, и действие WorkAction. Конфигурировать их можно с помощью WorkParameters.

Также мы проанализировали базовую команду для запуска Android-тестов — connectedAndroidTest, и выясняли, какие в принципе существуют абстракции, чтобы сделать нечто похожее. Обнаружили, что существует некий AndroidTestOrchestratorRemoteAndroidTestRunner, позволяющий из кода запускать тесты. У него есть дополнительный ITestRunListener и набор средств конфигурации этого Runner. Однако часть API, которые мы тогда нашли, начиная с Gradle 4.0 стали Deprecated, поэтому нам пришлось скопировать некоторые компоненты в проект.

Текущая конфигурация исполнения наших тестов выглядит примерно так. Мы запускаем два агента. На каждом запускаем по восемь эмуляторов — здесь их для краткости три.

Как можно заметить, на 16 эмуляторах тесты исполняются примерно за 30 минут, а последовательное их исполнение занимает порядка 5 часов. Но это не совсем честное время. Столько мы потратим только на исполненея тестов, без накладных расходов с точки зрения инфраструктуры.

Итог

Чего мы добились, проделав все это?

Если посмотреть на этот график, то за год с момента интеграции UI-тестов количество наших релизов значительно выросло. Количество HotFix снижается. То есть тесты помогают нам писать более стабильный код, вносить масштабные исправления в проект без особой оглядки.

Сейчас у нас, по утверждению команды QA, автоматизирован 71% регрессионного тестирования, и сформирован план по дальнейшей автоматизации. На релизе мы проводим выборочное тестирование, которое занимает порядка двух-трех часов. Релизы случаются примерно раз в одну-две недели, как можно заметить по этому графику за последние три месяца.

Что с проблемами, которые были обозначены в самом начале?

Для изолированности наших тестов мы используем такие средства, как Android Test Orchestrator, MockWebServer, Espresso Intens. Dagger 2 помогает подменять зависимости в тестовой среде. Для стабильности у нас есть IdlingResource, есть костыль waitUntil. Так как мы используем кастомный Gradle-таск, есть возможность перезапускать тесты, которые по непредсказуемым причинам падают. Что касается времени исполнения тестов, нам удалось реализовать параллельное исполнение средствами кастомной Gradle-таски.

У нас сейчас написано примерно полторы тысячи тестов. Они исполняются примерно за один час с учетом всех накладных расходов. Гоняем мы их на каждый коммит, на каждый пул-реквест.

В написании тестов используются подходы с тестовым роботом. Выделили Matcher и Lookup, используем компонентный подход, сравнение скриншотов для упрощения написания. Отчеты строятся в Allure, который предоставляет нам некоторую автодокументируемость. Это позволяет команде тестирования анализировать тесты, которые мы реализовали, и фиксировать, какую часть регресса мы покрыли.

Что же дальше? У нас есть планы по расширению использования IdlingResource. Сейчас мы их, к сожалению, используем только для OkHttpClient. Также есть планы по улучшению инфраструктуры параллельного исполнения тестов. Сейчас возникают очень большие накладные расходы: как я сказал, тесты исполняются за 30 минут, а все остальное время занимают процессы передачи управления между подзадачами. И, разумеется, можно предпринимать еще какие-то шаги по улучшению нашего отчета.

Специально для вас я подготовил репозиторий с исходными кодами всего этого параллелизма, всех подходов, о которых я рассказал. Подробнее можно посмотреть там. Спасибо за внимание.

Полезные ссылки:

developer.android.com/training/testing/espresso
jakewharton.com/testing-robots
docs.qameta.io/allure
github.com/KakaoCup/Kakao

ссылка на оригинал статьи https://habr.com/ru/company/yandex/blog/568800/

Вышел долгожданный релиз GitLab 14.0

Картинка для привлечения внимания

Когда мы думаем обо всём, что было выпущено за год с момента выхода GitLab 13.0, мы не можем не гордиться нашим сообществом и нашей командой. В этом месяце мы празднуем выход GitLab 14.0, и в связи с этим устроим небольшую ретроспективу. Вместе мы добились такого прогресса за последний год, что нам хочется рассказать обо всём, что потребовалось, чтобы пройти путь до GitLab 14.

Мы используем семантическое версионирование, поэтому релизы вида 14.0 отражают всё новое, что появилось в этом месяце. GitLab 14 же — это кульминация всего прошедшего года. Более того, GitLab 14 отражает будущее GitLab и будущее DevOps в целом.

С выходом GitLab 14 команды любого масштаба смогут перейти от поддержания DIY-инструментов для DevOps к внедрению современного DevOps. GitLab 14 — это полноценная DevOps-платформа со встроенной в её ДНК безопасностью, прозрачностью и аналитикой (которую обеспечивает единое место для хранения данных), а также с цельным рабочим процессом и масштабируемой системой, благодаря чему и конечные пользователи, и организации получают все преимущества скорости и эффективности.

Мы написали пост, в котором вы можете больше узнать о GitLab 14 и нашем видении современного DevOps, и о том, как DevOps позволяет любой команде создавать и поставлять программное обеспечение быстро, прозрачно и надёжно.

Как и всегда, мы рады рассказать обо всех новинках этого месяца в релизе 14.0. Читайте далее нашу постоянную обзорную подборку ключевых новых фич и улучшений релиза. Кроме того, в 14.0 есть несколько кардинальных изменений. Чтобы узнать, что будет в следующем месяце, зайдите на страницу предстоящих релизов, там вы найдёте видео по будущему релизу 14.1

Присоединяйтесь к нам на GitLab Commit Virtual, чтобы узнать, как команды, использующие DevOps, повышают эффективность совместной работы.

GitLab MVP badge

MVP этого месяца — Mathieu Parent

Mathieu внёс значительный вклад в нашу стадию Package благодаря своей работе над реестрами пакетов Debian и Helm. Фичи этого направления пока что целиком и полностью принадлежат его авторству.

Работа по внедрению пакетов Debian продолжается с сентября 2020 года. На данный момент было принято уже около 38 мерж-реквестов, и сейчас мы приближаемся к концу итеративного плана, который составил и поддерживал Mathieu. В результате его усилий мы находимся всего в нескольких мерж-реквестах от завершения работы над этой фичей и её выхода.

Mathieu также спланировал разработку менеджера пакетов Helm Charts и работал над ним в течение последних трёх месяцев. В ходе этой работы Mathieu придерживался ценностей GitLab — итеративности и сотрудничества — работая в тесном контакте со всей командой Package (и не только) над этими и многими другими фичами.

Спасибо за всю эту потрясающую работу, Mathieu!

Основные фичи релиза GitLab 14.0

Доски эпиков

(SaaS: PREMIUM, ULTIMATE; self-managed: PREMIUM, ULTIMATE) Стадия цикла DevOps: Plan

Доски эпиков (в русской локализации GitLab «цели») помогут наладить работу команд и организаций за счёт непрерывного информирования о состоянии эпиков. В предыдущих версиях GitLab для отслеживания общего состояния эпиков требовалось просматривать и сортировать их в списке. Для поддержания эпиков в актуальном состоянии большинство изменений приходилось вносить через страницу деталей эпика. Доски эпиков позволяют визуализировать и просматривать все ваши эпики в одном месте, используя настраиваемый интерфейс с перетаскиванием, который легко сможет освоить любой член команды.

Доски эпиков также будут значительным подспорьем для управления и визуализации идеальных рабочих процессов эпиков, таких как авторство состояний рабочего процесса (Draft, Writing, Done), состояния рабочего процесса DevOps (например, Planned, In Development и In Production) или любые другие взаимоисключающие состояния, которые вы можете моделировать с помощью меток с ограниченной областью действия. Визуализация рабочих процессов с помощью доски эпиков позволит вам повысить предсказуемость и эффективность.

Epic Boards

Документация по доскам эпиков и оригинальный эпик.

Встроенный в GitLab реестр модулей Terraform

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Configure

Модули Terraform играют центральную роль в создании стандартных компонентов инфраструктуры в организации. Вплоть до версии GitLab 13.12 пользователям GitLab приходилось использовать сторонний реестр модулей Terraform, локальные модули или модули, размещаемые в Git. Эти варианты неплохо работают, но они не помогают в распространении модулей, и в них отсутствует надлежащая поддержка версий, что вносит некоторые риски для пользователей этих модулей. GitLab 14.0 добавляет к нашему направлению инфраструктуры как кода реестр модулей Terraform. Теперь вы можете использовать встроенный в GitLab реестр модулей Terraform с поддержкой семантического версионирования для обновления и обслуживания модулей. Более того, вы также можете публиковать модули с помощью GitLab CI/CD.

Поскольку мы используем лучшие практики в работе с Terraform, мы рекомендуем разрабатывать каждый модуль Terraform в отдельном проекте GitLab. Однако для упрощения перехода к реестру пользователи могут размещать и публиковать несколько модулей из одного репозитория GitLab. Вы можете узнать больше о том, как публиковать и использовать модули с реестром модулей Terraform в нашей документации по реестру.

Terraform module registry built into GitLab

Документация по реестру модулей Terraform и оригинальный тикет.

Обновлённое верхнее навигационное меню

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

В GitLab 14.0 мы обновили и усовершенствовали верхнее меню навигации, которое поможет вам добраться до нужного места быстрее и с меньшим количеством кликов. Это новое объединённое меню совмещает в себе возможности предыдущих меню «Проекты» (Projects), «Группы» (Groups) и «Ещё» (More). Оно обеспечивает доступ к проектам, группам и фичам уровня инстанса всего лишь в один клик. Кроме того, новые отзывчивые элементы улучшают навигацию на небольших экранах.

Streamlined top navigation menu

Тикет для фидбека по обновлённому меню и оригинальный эпик.

Обновлённая боковая навигационная панель

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

GitLab — большое приложение, которое регулярно становится ещё больше. По мере того, как мы представляем новые фичи и категории, навигация по нагруженной контентом левой боковой панели становится менее интуитивной.

В GitLab 14.0 мы переработали дизайн и структуру левой навигационной панели для повышения удобства использования, доступности и похожего опыта использования в разных местах. Мы переместили некоторые ссылки на фичи, разделили фичи меню Операции (Operations) на три отдельных меню, улучшили визуальный контраст и оптимизировали расстояние между пунктами меню, чтобы все они удобно располагались на небольшом экране. Эти изменения нужны для того, чтобы меню лучше соответствовало вашему представлению о жизненном цикле DevOps, а также предоставляло более предсказуемую и привычную навигацию по проектам и группам.

Sidebar navigation redesign

Документация и оригинальный эпик.

Ревью мерж-реквестов в VS Code

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

Если вы разработчик, скорее всего, большую часть своего рабочего времени вы проводите в локальной среде разработки. Когда у вас запрашивают ревью мерж-реквеста (в русской локализации GitLab «запрос на слияние»), вам приходится покидать свой редактор и выполнять ревью в GitLab. При проведении ревью в GitLab вам также может понадобиться использовать локальный редактор, чтобы получить больше информации о предлагаемых изменениях.

Версия 3.21.0 расширения GitLab Workflow для Visual Studio Code (VS Code) теперь поддерживает полный процесс ревью мерж-реквестов, включая потоки. Выберите значок GitLab в VS Code, чтобы открыть боковую панель и просмотреть мерж-реквесты для ревью в Merge requests I’m reviewing. Выберите обзор мерж-реквеста, чтобы просмотреть все подробности и текущие обсуждения в мерж-реквесте.

Боковая панель также содержит список всех изменённых файлов в мерж-реквесте. При выборе файла открывается дифф для просмотра изменений в VS Code. Во время просмотра диффа вы можете прочитать комментарии, оставленные к файлам, а также оставить свои комментарии, выбрав номер нужной строки. Все комментарии и отклики, которые вы оставляете в VS Code, будут доступны и в веб-интерфейсе GitLab. Вам будет легче выполнять ревью в VS Code, а другим пользователям — участвовать в этих ревью в GitLab.

Мы действительно счастливы представить полный процесс ревью мерж-реквестов в нашем расширении для VS Code. Откройте тикет и дайте нам знать, что вы думаете по этому поводу.

Документация по расширению GitLab Workflow и оригинальный эпик.

Редактируйте вики-страницы с WYSIWYG редактором Markdown

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

Редактирование содержимого вики может быть намного проще! Многие вики-страницы в GitLab используют формат Markdown, и для некоторых пользователей это является препятствием для эффективной совместной работы. В этом релизе у вас появился доступ к современным расширенным возможностям редактирования Markdown в вашей вики, так что вы можете уверенно редактировать вики-страницы.

Мгновенный фидбэк и инструменты визуального редактирования помогают сделать редактирование вики более интуитивным, устранить барьеры и работать совместно. После завершения работы GitLab сохраняет изменения в формате Markdown, поэтому пользователи, которые хотят редактировать Markdown напрямую, могут продолжать это делать. Вы даже можете вводить Markdown в новый редактор, и он будет автоматически форматировать текст по мере ввода.

GitLab 14.0 представляет Редактор контента для вики с поддержкой большинства основных типов контента Markdown, таких как заголовки, жирный текст и курсив, списки, блоки кода и ссылки. Полная поддержка всего GitLab Flavored Markdown specification появится в ближайших релизах. Мы также планируем в будущем сделать этот редактор доступным в других областях GitLab. Мы будем рады услышать мнения об этом MVC в специальном тикете для фидбэка.

Edit wiki pages with the WYSIWYG Markdown editor

Документация по редактору контента для вики и оригинальный эпик.

Идентичные уязвимости DAST собираются в одну уязвимость

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Secure

В GitLab 13.12 и более ранних версиях все уязвимости DAST, найденные при сканировании, указывались отдельно для каждого URL-адреса, на котором была обнаружена уязвимость. Это могло создавать большое количество однотипных уязвимостей, хотя исправление сводилось к одному файлу или изменению конфигурации. Например, серверный header, отправляемый с каждым HTTP-ответом, вызывал проблему, о которой сообщалось для каждой страницы сайта, а не как об одной проблеме с несколькими вхождениями.

Чтобы уменьшить нагрузку при управлении уязвимостями, GitLab теперь объединяет идентичные уязвимости, найденные на нескольких страницах, в одно сообщение об уязвимости в отчёте DAST. Сведения об уязвимости включают список всех URL, на которых была обнаружена уязвимость, вместо того чтобы создавать для каждой страницы отдельную уязвимость в списке уязвимостей и на панели безопасности.

Это нововведение не будет объединять задним числом уязвимости, найденные в предыдущих сканированиях. Объединение будет работать только с проверками, выполненными в GitLab 14.0 и более поздних версиях.

Aggregate identical DAST vulnerabilities into a single vulnerability

Документация по отчётам DAST и оригинальный тикет.

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

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Configure

В этом релизе мы отказываемся от подхода к управлению кластерами на основе шаблонов CI/CD. Управление кластерами в GitLab — это возможность управлять работой кластеров Kubernetes для повышения доступности приложений, работающих на кластере. Старый метод скрывает слишком много логики, ограничивает настройку и расширение ваших приложений. С новым подходом вы сможете легко создать проект управления кластером из шаблона проекта и получить полный контроль над своими приложениями. Проект, созданный с использованием нового шаблона, содержит код, необходимый для выполнения заданий по управлению кластером, включая встроенную поддержку нескольких приложений. Вы можете легко распространить действие проекта на другие приложения и в полной мере управлять ими.

Кроме того, новые приложения будут устанавливаться с помощью Helm v3. Если вы ранее устанавливали управляемые GitLab приложения с помощью Helm v2, ознакомьтесь с руководством по миграции Helm и инструкцией по миграции управляемых GitLab приложений. Результаты выполнения заданий CI/CD также помогут вам при выполнении этих миграций.

В GitLab 14.0 проект управления кластером поддерживает только интеграцию кластеров на основе сертификатов. Мы планируем добавить поддержку GitLab Kubernetes Agent в следующем релизе.

Cluster management project template

Документация по шаблону проекта для управления кластером и оригинальный тикет.

Предзаполненный шаблон конвейера в редакторе CI/CD-конвейеров

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Verify

Редактор конвейера в GitLab — это ваш универсальный инструмент при взаимодействии с конвейерами (в русской локализации GitLab «сборочные линии») CI/CD. Раньше при написании первого конвейера в редакторе вам предлагалась пустая конфигурация. Это было вполне удобно для опытных разработчиков конвейеров, но для тех, кто только начинает с ними работать, это могло быть немного проблематично.

Начиная с этого релиза, если в проекте не настроен конвейер, редактор загружает шаблон с примером 3-х этапного конвейера. Вы можете сохранить и сразу же запустить этот конвейер, чтобы увидеть его в действии в своём проекте. Кроме того, в шаблоне есть комментарии, которые помогут вам понять синтаксис, а также советы и подсказки, которые помогут начать настраивать шаблон в соответствии с вашими потребностями. Теперь получить первый «зелёный» конвейер стало намного проще!

Prepopulate the CI/CD pipeline editor with an initial template

Документация по редактору конвейера и оригинальный тикет.

Интеграция сканирования контейнеров с Trivy

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Protect

Сканирование контейнеров в GitLab теперь по умолчанию использует движок Trivy. Это изменение предоставит клиентам более своевременные обновления информации об уязвимостях, более точные результаты и поддержку большего числа операционных систем. Пользователи, запускающие сканирование контейнеров с настройками по умолчанию, переключатся на новый движок в GitLab 14.0 автоматически и без каких-либо затруднений. Пользователям, которые настраивают переменные в задании сканирования контейнеров, следует ознакомиться с нашим руководством по переходу и внести необходимые изменения.

Container Scanning Integration with Trivy

Документация по сканированию контейнеров и оригинальный эпик.

Статистика времени внесения изменений через мерж-реквесты на уровне группы

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Release

В рамках нашей работы по добавлению встроенной поддержки метрик DORA4 в GitLab, график времени внесения изменений через мерж-реквесты теперь доступен на уровне группы. Этот релиз продолжает работу, завершённую в GitLab 13.11: теперь вы можете просмотреть график, который показывает, сколько времени требуется мерж-реквестам для развёртывания в продакшене не только в отдельных проектах, но и в целом по группе. Это позволит вам получить полное представление о производительности по проектам группы.

Lead time for merge requests at the group level

Документация по графикам внесения изменений и оригинальный тикет.

Другие улучшения в GitLab 14.0

Горизонтальная навигация для аналитики цикла разработки на уровне проекта

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Manage

Стадии в аналитике цикла разработки на уровне проекта теперь расположены горизонтально. Это помогает визуализировать процесс выполнения работы по стадиям цикла разработки. Кроме того, такой интерфейс совпадает с интерфейсом навигации по аналитике цикла разработки на уровне группы.

Horizontal navigation for project-level Value Stream Analytics

Документация по стадиям аналитики цикла разработки](https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html#default-stages) и оригинальный тикет.

Улучшенный интерфейс для добавления групп в таблицу DevOps Adoption

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Manage

Таблица DevOps Adoption даёт информацию о том, как GitLab используется в группах и подгруппах внутри вашей организации. Ранее вы могли добавлять в таблицу не более 200 групп. Мы понимаем, что более крупные организации могут иметь тысячи групп в GitLab. Теперь вы можете использовать поиск в выпадающем списке для добавления любой подгруппы в таблицу.

Кроме того, подгруппы, удалённые из таблицы DevOps Adoption в одной группе, больше не удаляются автоматически из таблиц других групп. В результате миграции данных, которая была проведена для исправления этой проблемы, вам возможно придётся вручную добавить некоторые подгруппы в ваши таблицы при первом повторном посещении их.

Документация по внедрению DevOps и оригинальный тикет.

Использование ключей SSH с истекшим сроком действия по умолчанию отключено

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Manage

Ключи SSH с истекшим сроком действия, добавленные в GitLab, теперь отключены по умолчанию. Это помогает сделать ваш инстанс GitLab более безопасным. Ранее ключи SSH с истекшим сроком действия, добавленные в GitLab, были активны по умолчанию, и их можно было использовать, пока администратор их не отключит.

Это изменение влияет на ключи SSH с истекшим сроком действия, используемые на GitLab.com. Если срок действия ваших ключей истёк или скоро истечёт, вам нужно обновить ключ и все использующие его сервисы. Наша документация по ключам SSH содержит полезную информацию о том, как создать новый ключ SSH.

Администраторы инстансов с самостоятельным управлением по-прежнему могут разрешать использование ключей с истекшим сроком действия аналогично тому, как они могут разрешать использование истекших токенов персонального доступа.

Документация по настройкам истечения срока действия ключей SSH и оригинальный тикет.

Отслеживание использования фичи «владельцы кода»

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Manage

Владельцы кода являются важной частью процесса ревью кода в GitLab. Когда владельцев кода легко определить, пользователи, делающие вклад, могут видеть, кто должен проводить ревью изменений файла или репозитория. Фича «владельцы кода» также может быть использована для настройки процесса подтверждения мерж-реквеста. Теперь вы можете отслеживать, какие команды в вашей организации используют фичу «владельцы кода» в своём процессе разработки.

Если вы хотите внедрить фичу «владельцы кода» в своей организации, отсортируйте таблицу DevOps Adoption по колонке «владельцы кода». Вы увидите команды, которые ещё не используют эту фичу, и поймёте, кому из них нужно помочь начать работать с ней. Вы также можете найти команды, которые уже успешно настроили фичу «владельцы кода», и получить от них полезные советы и фидбек. Таблица DevOps Adoption доступна на уровне группы и на уровне инстанса.

Track usage of Code Owners

Документация по внедрению DevOps и оригинальный тикет.

Уведомления в Slack при редактировании вики включают ссылки на файлы диффа

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

Наш сервис уведомлений в Slack может сообщать вам, когда пользователь редактирует одну из страниц вики. Сообщение в Slack предоставит вам полезный контекст изменения, включая проект, имя страницы и сообщение коммита. Однако иногда сообщение коммита не даёт достаточно контекста, и вам нужно больше информации о том, какие изменения были внесены.

Теперь вы можете нажать кнопку Сравнить изменения (Compare changes) в сообщении в Slack, чтобы сразу перейти к диффу. Это позволит сэкономить время и снизить уровень непонимания при двусмысленных или неполных сообщениях коммита.

Документация по триггерам уведомлений в Slack и оригинальный тикет.

Обработчик заданий GitLab 14.0

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Verify

Мы также выпускаем новую версию обработчика заданий GitLab — 14.0! Обработчик заданий GitLab — это легковесный, высокомасштабируемый агент, который выполняет ваши задания сборки и отправляет результаты обратно в инстанс GitLab. Обработчик заданий GitLab работает вместе с GitLab CI/CD — сервисом непрерывной интеграции с открытым кодом, поставляемым с GitLab.

Что нового:

Исправления ошибок:

Список всех изменений обработчика заданий GitLab здесь.

Документация по обработчику заданий GitLab.

Предопределённые переменные CI/CD для действий окружения

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Verify

Если вы хотите использовать одни и те же скрипты и настройки в разных заданиях развёртывания при помощи ключевого слова environment:, вам может быть сложно исключить определённые шаблоны поведения на основе типа действия, которое выполняет задание развёртывания. Например, действие окружения stop может быть заданием, которое останавливает review_app, и вы не хотите, чтобы запускались ваши скрипты развёртывания.

Теперь значение environment: action: доступно как предопределённая переменная CI/CD CI_ENVIRONMENT_ACTION, что максимально упрощает настройку скриптов для работы во всех заданиях развёртывания.

Документация по предопределённым переменным и оригинальный тикет.

Установка пакетов PyPI из группы или подгруппы

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Package

Вы можете использовать реестр пакетов вашего проекта, чтобы публиковать и устанавливать пакеты PyPI. При установке пакета PyPI вы должны указать, в каком проекте находится пакет. Это отлично работает для небольшого числа проектов, но если у вас есть несколько проектов в группе, вам, возможно, придётся добавлять десятки и даже сотни разных источников.

В крупных организациях с большим числом команд разработчики часто публикуют пакеты в реестры пакетов их проекта вместе с исходным кодом и конвейерами. Однако они также должны иметь возможность легко устанавливать зависимости из других проектов внутри организации. Теперь вы можете устанавливать пакеты из своей группы, так что вам не придётся запоминать, в каком проекте находится каждый пакет. Просто задайте путь к пакету, используя простой API: GET groups/:id/packages/pypi/files/:sha256/:file_identifier.

Вы также можете записывать результат выполнения в файл или вернуть дескриптор пакета как HTML-файл. Посмотрите документацию, чтобы получить больше информации, и дайте нам знать, что у вас получается. Мы надеемся, что это сделает работу вашей команды и организации более эффективной.

Документация по установке пакетов PyPI на уровне группы и оригинальный тикет.

Обобщённые детали в отчёте по безопасности

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Secure

Автоматизированное сканирование безопасности является важной частью любого безопасного процесса разработки. Существует большое число инструментов и технологий, покрывающих SDLC, начиная от сканирования исходного года, и заканчивая сканированием приложений и инфраструктуры после развёртывания. Конечная цель всех этих инструментов — обнаружить известные и потенциальные уязвимости, но информация от разных сканеров может значительно отличаться. Попытки стандартизировать данные результатов сканирования существуют, но они обычно фокусируются только на одной технологии сканирования или даже определённом наборе инструментов. Это представляет большую сложность для команд безопасности, которым нужно собирать широкий разброс результатов сканирований. Без надёжного способа нормализовать разрозненные данные очень сложно просматривать уникальные детали результатов сканирования для каждого сканера. И если выходные данные инструментов не собираются в одном месте, они обычно просматриваются в исходном инструменте. В результате реальная картина риска уязвимостей становится фрагментированной и остаётся вне цепи инструментов DevOps.

Новая структура с обобщёнными деталями в наших схемах отчётов по безопасности может сократить этот разрыв. Вы уже можете интегрировать широкий круг сканеров безопасности в GitLab с минимальными усилиями. Теперь вы можете продвинуться ещё дальше за счёт богатого набора опций форматирования для поиска деталей. Наша новая структура позволяет легко отображать существующие выходные данные большинства инструментов в наши форматы отчётов JSON, при этом автоматически добавляя последовательную логику презентации. Гибкость без потери возможности обеспечить большое число данных об уязвимостях — главная цель новой структуры. Детали предоставляются в открытой структуре с использованием предопределённых типов данных. Предопределённые типы обеспечивают и валидацию данных, и стандартизированное представление пользовательского интерфейса в GitLab. Например, мы предоставляем такие типы данных: целое число, ссылка, таблица и даже маркдаун GitLab (GFM). Это предоставляет точный контроль над тем, как отображаются детали, и при этом сохраняет согласованность общего опыта работы с GitLab.

Security report generalized details structure

Документация по уязвимостям и оригиральный тикет.

Отдельная страница для списков пользователей, использующих переключаемые фичи

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Release

Ранее, чтобы получить доступ к спискам пользователей переключаемых фич (feature flags), вам приходилось переходить на отдельную вкладку под страницей переключаемых фич. Такой интерфейс не отражал сути отношений между переключаемыми фичами и списками пользователей, так как списки пользователей являются дочерней фичей переключаемых фич. В этом релизе мы перенесли списки пользователей на отдельную страницу в разделе переключаемых фич, что улучшает рабочий процесс и более точно показывает отношения между ними.

Feature Flags User List is now on its own page

Документация по спискам пользователей переключаемых фич и оригинальный тикет.

Динамическое обновление таймера соглашения об уровне сервиса для инцидентов

(SaaS: PREMIUM, ULTIMATE; self-managed: PREMIUM, ULTIMATE) Стадия цикла DevOps: Monitor

Таймер соглашения об уровне сервиса для инцидентов, представленный в GitLab 13.5, показывает время, оставшееся до нарушения соглашения для инцидентов. Однако ранее пользователям нужно было обновлять страницу, чтобы обновить значение таймера. Начиная с GitLab 14.0 таймер обновляется динамически каждые 15 минут без необходимости обновлять страницу.

Документация по таймеру соглашения об уровне сервиса для инцидентов и оригинальный тикет.

Управление нагрузкой базы данных доступно в Free

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Доступность

Управление нагрузкой базы данных позволяет распределять запросы на чтение между несколькими серверами. Для инстансов GitLab с тысячами пользователей распределение запросов может снизить нагрузку на основную базу данных и повысить скорость ответа, что приведёт к более быстрой загрузке страниц внутри GitLab.

В этом релизе мы переместили распределение нагрузки из Premium в Free, что позволит большему числу пользователей воспользоваться этой фичей.

Документация по управлению нагрузкой базы данных и оригинальный тикет.

Поддержка Geo для высокой доступности PostgreSQL в общем доступе

(self-managed: PREMIUM, ULTIMATE) Доступность

Patroni — это решение для обеспечения высокой доступности PostgreSQL, которое также позволяет настраивать высокодоступный резервный кластер PostgreSQL на вторичной ноде Geo. Эта конфигурация пригодится, когда вторичная нода используется как часть стратегии аварийного восстановления, поскольку позволяет системным администраторам зеркалировать количество нод базы данных на первичной и вторичной нодах. Это означает, что после сбоя не потребуется дополнительных нод базы данных для восстановления высокой доступности.

Geo теперь предоставляет общедоступную поддержку для высокодоступных конфигураций PostgreSQL через Patroni.

Мы улучшили документацию, обновили версию Patroni до 2.0.2, добавили поддержку распределения нагрузки базы данных на резервных кластерах и убедились, что команды приостановки и возобновления заданий по репликации работают с резервным кластером Patroni.

Документация по поддержке Patroni и оригинальный эпик.

Обновление Ruby on Rails до версии 6.1

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Доступность

В этом релизе мы обновили Ruby on Rails до версии 6.1, чтобы вы могли воспользоваться всеми преимуществами последних улучшений этого фреймворка для разработки приложений. Посмотрите примечания к релизу Ruby on Rails 6.1, чтобы узнать больше подробностей.

Документация по Gemfile, оригинальный тикет и оригинальный эпик.

Шкала производительности показывает процент используемой памяти

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Доступность

Шкала производительности позволяет системным администраторам и разработчикам ПО оценить производительность страницы GitLab.

Разработчикам ПО важно иметь наглядное представление используемой памяти, чтобы они могли улучшить производительность и впечатления от использования GitLab. В этом релизе мы добавили поле памяти, которое отображает количество используемой памяти и выделенные объекты для текущего запроса. При выборе этого поля отображается дополнительная информация. Эта информация поможет разработчикам быстрее замечать проблемы с использованием памяти и разрабатывать более эффективные и производительные фичи.

Документация по шкале производительности и оригинальный тикет.

Редизайн панели сайтов Geo

(self-managed: PREMIUM, ULTIMATE) Доступность

Geo реплицирует и верифицирует множество разных типов данных. Системным администраторам нужно следить за состоянием сайтов Geo, чтобы знать, есть ли на них проблемы, требующие внимания, например, несинхронизованные проекты или несовпадения контрольных сумм. В нашем исследовании пользовательского опыта мы выяснили, что администраторам, использующим страницу администратора Geo, часто было сложно находить нужную информацию, и отображаемая информация могла быть непонятной. Наш редизайн панели сайтов Geo исправляет эти проблемы. Мы добавили больше полезных индикаторов, таких как сводка по синхронизации и верификации типов данных и полоска статуса верификации для отдельных типов данных. Мы также улучшили структуру страницы, снизив число нажатий, необходимое для получения нужной информации.

Redesign for Geo sites dashboard

Документация по настройке Geo и оригинальный эпик.

Идентификация выделенных пользователей на уровне группы

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Manage

В этом релизе мы добавили возможность идентифицировать выделенных (provisioned) пользователей и разработчиков. Напротив выделенных пользователей будет отображаться новая метка Enterprise. Это поможет пользователям отличать аккаунты, которые группа создаёт автоматически через SCIM, от аккаунтов, созданных пользователями вручную.

Документация по настройке SCIM и оригинальный тикет.

Отчёт о внедрении DevOps на уровне экземпляра включён по умолчанию

(self-managed: ULTIMATE) Стадия цикла DevOps: Manage

Отчёт о внедрении DevOps на уровне экземпляра теперь по умолчанию включён. Отчёт DevOps Adoption показывает, какие команды в вашей организации используют в GitLab:

  • тикеты
  • мерж-реквесты
  • подтверждения
  • обработчики заданий
  • конвейеры
  • развёртывания
  • сканирования

Сравните внедрение GitLab во всей организации, добавив группы в таблицу внедрения. Вот лишь несколько способов использования отчёта DevOps Adoption:

  • Проверьте, получаете ли вы ту отдачу от вложений, которую ожидали от GitLab.
  • Определите конкретные группы, которые медленнее внедряют GitLab, чтобы помочь им в их пути к DevOps.
  • Определите группы, которые внедрили определённые фичи, например конвейеры, и дайте советы другим группам, заинтересованным в начале работы с этими фичами.

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

Отчёт о внедрении DevOps также доступен на уровне группы. Пользователи SaaS могут получить полезные идеи о внедрении для всей организации, просмотрев отчёт о внедрении DevOps в своей группе верхнего уровня.

Instance-level DevOps Adoption report enabled by default

Документация по DevOps Adoption и оригинальный тикет.

Установка местоимений в профилях пользователей GitLab

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Manage

В профили пользователей GitLab были добавлены местоимения. Они будут отображаться рядом с именами пользователей на вкладке Профиль (Profile). Вы можете:

  • решить, нужно ли добавлять местоимения в профиль;
  • самоидентифицироваться и ввести любые местоимения, которые вы предпочитаете, без выбора из заранее определённого списка.

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

Set pronouns on GitLab user profiles

Документация по добавлению личных местоимений и оригинальный тикет.

Редактирование имени проекта и пути по умолчанию при форке

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Create

Форк проекта позволяет получить точную копию исходного репозитория, в котором вы можете экспериментировать, применять изменения и вносить вклад в родительский проект. У ваших форков должны быть осмысленные имена, объясняющие их цели, и если ваш проект расходится и дальше, вам может потребоваться несколько форков одного проекта.

С этого релиза GitLab поддерживает редактирование имени проекта и семантического URL проекта непосредственно при создании форка. Теперь вы можете создать несколько форков с разными именами одного и того же проекта в одной группе!

Edit default path and project name when forking

Документация по созданию форков и оригинальный тикет.

Теперь можно использовать символ ~ для маскирования переменных CI/CD

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Verify

Безопасное управление секретными ключами, хранящимися в переменных CI/CD, крайне важно. Вы можете скрыть значения переменных в журналах заданий, замаскировав переменные, но GitLab поддерживает в этой роли только определённые символы. Теперь мы поддерживаем маскирующие переменные с символом ~ в значении, что расширяет фичу для поддержки большего количества ключей, генерируемых другими платформами поставщиков секретных ключей. Спасибо dallmair из нашего сообщества за этот вклад!

Документация по маскированию переменной CI/CD и оригинальный тикет.

Определяйте, какие задания запускали нижестоящие конвейеры

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Verify

Раньше, глядя на представление конвейера, было трудно определить, какое задание запустило нижестоящий конвейер. Начиная с версии 14.0, каждый нижестоящий конвейер показывает имя задания, которое его запустило. Это упрощает отслеживание потока выполнения в сложных конвейерах, запускающих нисходящие конвейеры.

Identify which jobs triggered downstream pipelines

Документация по вложенным конвейерам и оригинальный тикет.

Удаление связанных файлов пакета через пользовательский интерфейс

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Package

Реестр пакетов GitLab используется для публикации, установки и совместного использования зависимостей. Когда вы публикуете зависимость, она генерирует несколько файлов, включая архив пакета. До GitLab 14.0 для удаления таких файлов приходилось использовать API. В GitLab 14.0 теперь вы можете использовать пользовательский интерфейс, чтобы удалить как файлы, связанные с данным пакетом, так и сам пакет.

Поскольку содержать реестр в порядке может быть непросто, наша цель — упростить и повысить эффективность этого процесса, добавив дополнительные параметры для удаления неиспользуемых файлов.

Документация по удалению файлов, связанных с пакетом и оригинальный тикет.

Закрепление конкретных версий анализатора SAST

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Secure

С развитием инструментов сканирования GitLab Secure нам потребовалось повысить степень детализации нашего процесса подготовки релиза. Ранее GitLab использовал общие мажорные версии для всех наших анализаторов и инструментов. Для этого нужно было, чтобы все инструменты были одной и той же мажорной версии, что не давало использовать семантическую нумерацию версий. Начиная с версии 14.0 мы убрали глобальную переменную SAST_ANALYZER_IMAGE_TAG в нашем шаблоне SAST.gitlab-ci.yml в пользу переменной задания анализатора, устанавливающей тег major.minor в поставляемом шаблоне SAST. Каждое задание анализатора теперь имеет свою переменную SAST_ANALYZER_IMAGE_TAG, которой будет управлять GitLab, и для неё будет установлен тег major для соответствующего анализатора. Чтобы закрепить определённую версию, просто измените значение переменной на конкретный тег версии.

Если вы переопределяете или поддерживаете пользовательские версии SAST.gitlab-ci.yml, вам надо будет обновить свои шаблоны CI, чтобы перестать ссылаться на глобальныйSAST_ANALYZER_IMAGE_TAG и перейти к использованию соответствующего тега задания анализатора с нужной областью видимости. Мы настоятельно рекомендуем наследовать и переопределять управляемые GitLab шаблоны CI, чтобы ваши шаблоны CI не ломались в будущем. Это изменение позволит вам более детально контролировать будущие обновления анализатора с помощью закреплённой версии major.minor.

Документация по закреплению версии анализатора и оригинальный эпик.

Обновления анализаторов SAST

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Secure

SAST (Статическое тестирование безопасности приложений) в GitLab включает в себя множество анализаторов безопасности, которые команда статического анализа GitLab активно поддерживает и обновляет. Ниже представлены обновления анализаторов, выпущенные в релизе 14.0. Эти обновления включают расширенное покрытие, исправления ошибок и другие улучшения.

  • Semgrep обновлён до версии 2.8.0: мерж-реквест, список изменений
    • Исправили неправильные номера строк для многострочного универсального режима
    • SAST_EXCLUDED_PATHS передаются в semgrep для исключения при запуске semgrep
    • Оптимизировали производительность
    • К первичному идентификатору правила в отчёте добавили URL, чтобы связать его с базовым правилом
  • GoSec обновлён до версии 3.1.0: мерж-реквест, список изменений
    • Убрали поддержку SAST_GOSEC_CONFIG, уведомление об устаревании
    • Добавили переменную COMPILE для поддержки пропуска получения зависимостей при желании
    • Добавили переменную GOSEC_GO_PKG_PATH чтобы дать возможность указать, где go собирает приложение
    • Обновили получение зависимостей, чтобы по умолчанию только загружать пакеты, а не собирать или устанавливать
  • Flawfinder обновили до версии 2.0.17: мерж-реквест, список изменений
  • SpotBugs обновили до версии 2.28.3 мерж-реквест, список изменений
    • Обновили зависимости
  • PMD-Apex обновили до версии 2.12.3: мерж-реквест, список изменений
    • Повысили точность правил, исправили баги
  • ESLint обновили до версии 7.27.0: мерж-реквест, список изменений
    • Обратите внимание, этот анализатор планируется заменить на Semgrep в одном из следующих релизов.

Если вы используете поставляемый GitLab шаблон SAST (SAST.gitlab-ci.yml), вам не нужно ничего делать, чтобы получить эти обновления. Однако, если вы переопределяете его или используете свой собственный шаблон CI, вам потребуется обновить конфигурации CI. Если вы хотите использовать определённую версию любого анализатора, теперь вы можете закрепить минорную версию анализатора. Закрепление одной из предыдущих версий отменит автоматические обновления анализатора и потребует от вас вручную менять версию анализатора в шаблоне CI.

Документация по настройке анализаторов SAST и оригинальный тикет.

Изменение типа тикета

(SaaS: FREE, PREMIUM, ULTIMATE; self-managed: FREE, PREMIUM, ULTIMATE) Стадия цикла DevOps: Monitor

Иногда может понадобиться изменить тип тикета. Например, вы можете захотеть поднять его уровень до инцидента, чтобы убедиться, что ваша команда корректно обработает проблему. Чтобы изменить тип тикета, начните редактировать его и выберите тип из меню Issue type.

Change an issue's type

Документация по изменению типа тикета и оригинальный тикет.

Интеграция сканирования контейнеров с Grype

(SaaS: ULTIMATE; self-managed: ULTIMATE) Стадия цикла DevOps: Protect

Сканирование контейнеров GitLab теперь может использовать движок сканирования Grype вместо Trivy, применяемого по умолчанию. Это даёт пользователям больше гибкости в выборе движка для сканирования контейнеров. Мы сравнили эти два сканера с открытым исходным кодом. Однако, поскольку каждый сканер уникален, вы можете сравнить сами, чтобы решить, какой из них лучше для вас. Пользователи могут попробовать сканер Grype, установив переменную CI CS_ANALYZER_IMAGE: registry.gitlab.com/security-products/container-scanning/grype:4.

Container Scanning Integration with Grype

Документация по выбору движка сканирования и оригинальный тикет.

Geo требует подтверждения перед повторной синхронизацией всех проектов

(self-managed: PREMIUM, ULTIMATE) Доступность

В пользовательском интерфейсе Geo Admin есть кнопка Повторно синхронизировать все проекты (Resync All). Для клиентов с большим количеством проектов, пытающихся повторно синхронизировать только проблемные репозитории, непреднамеренное включение этой опции может вызвать значительные задержки в устранении неполадок. Теперь мы отображаем модальное окно подтверждения всякий раз, когда выбрано Resync All. Это небольшое, но эффективное улучшение UX снижает вероятность того, что администраторы случайно запустят повторную синхронизацию всех своих проектов.

Geo requires confirmation before resyncing all projects

Документация по администрированию Geo и оригинальный тикет.

Улучшения GitLab chart

(self-managed: FREE, PREMIUM, ULTIMATE) Доступность

Документация по GitLab chart.

Место хранения проекта доступно в API REST и GraphQL

(self-managed: FREE, PREMIUM, ULTIMATE) Доступность

После появления хэшированного хранилища стало труднее понять, где реально хранится проект. Системные администраторы могли искать путь в пользовательском интерфейсе администратора проекта, но для многих проектов это было непрактично. В этом релизе мы добавили конечные точки API, которые предоставляют информацию о хранении проекта. В REST API этой новой конечной точкой является GET /projects/:id/storage. Для GraphQL поле diskPath теперь доступно в объекте Repository.

Документация по получению пути хранения проекта и оригинальный эпик.

Исправленные баги

Вот некоторые баги, которые мы исправили в релизе 14.0, и о которых стоит упомянуть:

Посмотрите все исправления багов в GitLab 14.0

Улучшения удобства использования

В каждом релизе мы работаем над повышением общей эффективности и полезности нашего продукта.

У нас также есть Галерея UI Polish для отслеживания важных обновлений наших интерфейсов. Эти обновления, хоть часто и небольшие, заметно улучшают удобство использования.

В GitLab 14.0 мы поработали над тикетами, проектами, майлстоунами и многим другим! Мы особо выделяем следующие изменения в GitLab 14.0:

Посмотрите все улучшения удобства использования в GitLab 14.0.


Полный текст релиза и инструкции по обновлению/установке вы можете найти в оригинальном англоязычном посте: 14.0 released with a celebration of GitLab 14.

Над переводом с английского работали cattidourden, maryartkey, ainoneko и rishavant.

ссылка на оригинал статьи https://habr.com/ru/post/568846/

Безопасность в мобильных приложениях

Информационная безопасность это всегда гонка вооружений. Из чего следует одна простая мысль, что полная безопасность невозможна, особенно в случае с клиентскими приложениями, когда у злоумышленника есть физический доступ к устройству. Но тут как при убегании от медведя: необязательно бежать быстрее медведя, достаточно бежать быстрее соседа.

Главная идея заключается в том, чтобы сломать вас было дороже получения возможной выгоды. Нужно донести до потенциального хакера одну простую мысль, «ломать нас невыгодно, иди поищи счастья в другом месте». Поэтому одной из основных критических ошибок являются крики о том что ваша защита совершенна. На подобные заявления сразу сбегается куча высоко профессиональных хакеров, которые будут ломать вашу защиту просто для доказательства своей крутизны невзирая на любую возможную выгоду.

Одним из основных столпов хорошей защиты, является журналирование действий и мониторинг всех нестандартных событий. Тяжело выстраивать защиту, если вы даже не знаете что вас ломают и каков вектор угрозы. Тут многое специфично для ваших процессов, но в качестве примеров могу привести использование большого количества разных аккаунтов с одного устройства; попытки обратиться к API к которому у аккаунта не должно быть доступа; многочасовые сессии в случаях, когда среднее время измеряется в минутах; нестандартные сбои и так далее.

Базовые методики защиты

Они не защитят от продвинутых ребят, но прикручиваются быстро и выбрасывают всех script-kiddie которые просто скачали утилиты из интернета и не особо понимают что делают.

Root

В природе есть много разных методик обнаружения рута. Одним из самых простых является проверка подписи прошивки или попытка достучаться до суперпользователя:

private fun checkForBuildTags(): Boolean {     val tags = Build.TAGS     return tags != null && tags.contains("test-keys") }  private fun checkForSuperUserAvailability(): Boolean {     return SUPER_USER_PATHS.any { File(it).exists() } } 

Также очень популярным методом получения рута является Magisk. Обнаружение само по себе является той еще игрой в кошки мышки: находят один способ, потом разработчики его патчат, находят другой, его патчат и так далее. Самой свежей методикой обнаружения является использование изолированного процесса.

Emulator

Для обнаружения запуска на эмуляторе можно проверять разные поля из класса Build. Большинство возвращаемых данных постоянны и одинаковы для подавляющего большинства эмуляторов:

private fun checkSystemIsEmulator(): Boolean {     return (Build.BRAND.startsWith(EMULATOR_BRAND) && Build.DEVICE.startsWith(EMULATOR_DEVICE))             || EMULATOR_FINGERPRINTS.any { Build.FINGERPRINT.contains(it) }             || EMULATOR_HARDWARES.any { Build.HARDWARE.contains(it) } } 

Также практически не меняется эмулируемая среда: сеть, данные с датчиков и так далее.

Xposed

Один из самых популярных инструментов для изучения приложений. Принцип работы достаточно простой: хукается основной процесс Zygote, что позволяет перехватить вызов любой функции и прочитать/подменить ответ. Есть много методик обнаружения такой атаки, например проверка stackTrace:

private fun checkForXposedStackTrace(): Boolean {     val stackTrace = RuntimeException().stackTrace     for (trace in stackTrace) {         val className = trace.className         if (className?.contains("de.robv.android.xposed.XposedBridge") == true) {             return true         }     }     return false } 

Проверка имени установщика приложения

Имя можно получить через

context.packageManager.getInstallerPackageName(securityConfig.applicationId) 

Если вернуло null, то в 99% случаев это означает что приложение установлено вручную и скорее всего взломано. Имена основных сторов:

private val appStoresPackages = hashMapOf(         "com.android.vending" to "Play Store",         "com.sec.android.app.samsungapps" to "Samsung Galaxy Apps",         "com.lge.lgworld" to "LG Smart World",         "com.huawei.appmarket" to "Huawei App Gallery",         "com.amazon.venezia" to "Amazon App Store",         "cm.aptoide.pt" to "Aptoide",         "net.appcake" to "AC Market",         "com.slideme.sam.manager" to "Slide Me",         "com.uptodown" to "Uptodown" ) 

Продвинутые методики защиты

Эти методики не спасут от профессионального специалиста по реверс-инжинирингу. От такого вообще ничего не защитит, поэтому лучше не держать на клиентских приложениях ничего сверх того что необходимо для работоспособности этого приложения. Зато они доставят достаточно много проблем, чтобы злоумышленники еще раз задумались, а надо ли это им.

Проверки на клонирование/пересборку приложения:

Можно проверить путь установки приложения, в большинстве случаев при клонировании приложение устанавливается по нестандартному пути:

context.filesDir.path 

и/или проверить подпись

return context.packageManager.getPackageInfo(     context.packageName,     PackageManager.GET_SIGNATURES ).signatures.firstOrNull() 

Safety net

Проверка Android-устройства возвращает следующий ответ:

{   "timestampMs": 9860437986543,   "nonce": "R2Rra24fVm5xa2Mg",   "apkPackageName": "com.package.name.of.requesting.app",   "apkCertificateDigestSha256": ["base64 encoded, SHA-256 hash of the                                   certificate used to sign requesting app"],   "ctsProfileMatch": true,   "basicIntegrity": true,   "evaluationType": "BASIC", } 

basicIntegrity — базовые проверки надежности устройства;

ctsProfileMatch — Более строгая проверка, прохождение которой означает что профиль устройства соответствует сертифицированному Google

SSL pinning

Эта проверка означает что мы не доверяем базовым сертификатам устройства, а доверяем только тому сертификату который нам известен. В случае okHttp3(стандарт сетевой библиотеки в большинстве приложений) проверка включается так:

val pinnerBuilder: CertificatePinner.Builder = Builder()     for (domain in domains) {       for (certificate in certificates) {          pinnerBuilder.add(domain, "sha256/$certificate")      } } builder.certificatePinner(pinnerBuilder.build()) 

Обфускация

Стандартным подходом в индустрии является Proguard. Для дополнительной защиты можно использовать собственный словарь с символами иностранного языка(китайский и арабский особенно хороши). Также существует проблема, при которой строковые литералы не обфусцируются. Решается платным обфускатором DexGuard, также на GitHub есть библиотеки не настолько качественные, зато бесплатные, например paranoid.

Шифрование

Шифрование всех важных данных — очень хорошее препятствие для обратного инжиниринга. Отличным вариантом алгоритма шифрации будет AES-256

object AES256 {      private const val ITERATION_COUNT = //степень двойки     private const val KEY_LENGTH = 256     private const val CIPHER_ALGORITHM = "AES"     private const val CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"          fun encrypt(key: String, salt: String, textToEncrypt: String, iv: ByteArray): String {         val ivSpec = IvParameterSpec(iv)         val secretKey = buildSecretKey(key, salt)         val cipher = Cipher.getInstance(CIPHER_TRANSFORMATION)         cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec)         val encrypted = cipher.doFinal(textToEncrypt.toByteArray())         return String(Base64.encode(encrypted, Base64.DEFAULT), Charsets.UTF_8)     }      fun decrypt(key: String, salt: String, encryptedText: String, iv: ByteArray): String {         val ivSpec = IvParameterSpec(iv)         val secretKey = buildSecretKey(key, salt)         val cipher = Cipher.getInstance(CIPHER_TRANSFORMATION)         cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec)         val encryptedArray = Base64.decode(encryptedText, Base64.DEFAULT)         val decryptedArray = cipher.doFinal(encryptedArray)         return String(decryptedArray, Charsets.UTF_8)     }      private fun buildSecretKey(key: String, salt: String): SecretKey {         val generator = PKCS5S2ParametersGenerator(SHA256Digest())         generator.init(key.toByteArray(), salt.toByteArray(), ITERATION_COUNT)         val keyArray = (generator.generateDerivedParameters(KEY_LENGTH) as KeyParameter).key         return SecretKeySpec(keyArray, CIPHER_ALGORITHM)     } } 

Единственное, что нужно продумать, это ротацию ключей. В идеале это будет отдельный ключ на каждую сессию, но это очень сложно и дорого поддерживать, поэтому подбирайте баланс в зависимости от доступных ресурсов и требуемого уровня безопасности.

JNI

Также очень интересным вариантом является перенос критической логики в нативный код. Отреверсить код на C намного тяжелее, чем это сделать с APK. Но так же как и с шифрованием это довольно дорого поддерживать, поэтому стоит продумать баланс в зависимости от доступных ресурсов и требуемого уровня безопасности.


Если вас заинтересовала тема безопасности в мобильных приложениях, то есть прекрасное руководство от OWASP с которого можно начать своё путешествие в кроличью нору.

ссылка на оригинал статьи https://habr.com/ru/company/citymobil/blog/567370/