Node-Local Virtual IP в OpenStack

Нашей команде по исследованию облачных технологий (Cloud Tech Research Team) из Лаборатории передовых программных технологий (Advanced Software Technology Lab) Huawei достаточно часто приходится оптимизировать работу тех или иных компонентов облачной инфраструктуры. При решении одной из таких задач по обновлению 5G Core приложений на очень больших кластерах нами была предложена и разработана технология Local IP в OpenStack Neutron.

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

Пример использования Local IP для локального кеширования.
Пример использования Local IP для локального кеширования.

Технология Local IP будет полезна:

  • (в общем случае) при реализации side-car прокси, балансировщиков нагрузки или service mesh;

  • (в large-scale и/или high-performance) при построении сервисов распределенного кеширования данных и CDN. Так же технология позволит упростить использование распределенных кэшей в облаках построенных на основе OpenStack. Например, запустив виртуальные машины с Docker Registry (в режиме passthrough) на каждой физическом сервере, можно добиться значительного сокращения времени скачивания образов и времени старта контейнеров, запускаемых в виртуальных машинах;

  • (в large-scale) при реализации паттерна load-balance-at-source.

Доступно два режима работы Local IP:

  • translate (по умолчанию) – поведение Local IP будет аналогично DNAT;

  • passthrough – пакеты будут перенаправляться без изменения IP заголовков. В этом случае ожидается, что гостевая OS виртуальных машин отвечает за конфигурирование Local IP адреса на интерфейсе. Данный режим будет полезен для реализации Fault-tolerance или похожих сценариев.

Как это работает?

Neutron – это компонент управляющий сетью в OpenStack (будем рассматривать стандартную инсталляцию с ML2 плагином и OpenvSwitch). Для тех читателей, которые не знаком с OpenStack Networking рекомендую обратить внимание на эту статью в которой достаточно подробно описаны все аспекты.

Neutron при помощи агентов на каждом физическом сервере конфигурирует OpenvSwitch (OVS), который в свою очередь создает несколько бриджей:

  • бридж «br-int» (так называемый «integration bridge») служит для работы с локальными портами/виртуальными машинами;

  • бридж «br-ex» (или «provider bridge») используется для взаимодействия с внешними сетями;

  • бридж «br-tun» (или «tunnel bridge») предназначен для взаимодействия между хостами под управлением OpenStack.

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

Пример хождения пактов внутри OVS с включенным Local IP (зеленая кривая) и без (серая пунктирная кривая).
Пример хождения пактов внутри OVS с включенным Local IP (зеленая кривая) и без (серая пунктирная кривая).

Вся логика работы Local IP реализована внутри «br-int», поэтому трансляция адресов происходит локально, не выходя за границы физического сервера. Это позволяет использовать один и тот же адрес для Local IP на разных физических серверах.

Реализация Local IP внутри «br-int».
Реализация Local IP внутри «br-int».

На рисунке, в упрощенном виде, изображен OpenFlow pipeline для «br-int» с правилами и набором действий для функционирования Local IP. Правила расположены в порядке приоритета выполнения от высшего к низшему. Более подробнее о том какие таблицы в себе содержит «br-int» и какие правила в этих таблицах содержатся можно узнать при помощи следующей команды «ovs-ofctl dump-flows br-int», выполнив её на физическом сервере под управлением OpenStack с OVS. Тем читателям, кто хочет разобраться как конфигурируется OpenvSwitch рекомендую к ознакомлению эту статью.

Логика работы Local IP, на первый взгляд, очень простая: используя DNAT нужно обеспечить трансляцию (подмену) dst MAC и IP адресов с Local IP на Fixed IP.  Это описано правилами Static Local IP Translation в таблице 31 «Local IP». NAT реализован двумя способами и может быть настроен используя опцию static_nat:

  1. (static_nat = False, значение по умолчанию) через contrack с использованием ct nat action;

  2. (static_nat = True) с использованием static NAT правил, добавляемых с помощью LEARN action в обратном flow используя следующие данные из заголовка пакета: MAC адреса отправления/назначения, IP адреса отправления/назначения, протокол и порты отправления/назначения. Поддерживается VLAN изоляция, возможность использовать Local IP вместе с OpenvSwitch Firewall и позволяет использовать SmartNIC для OpenvSwitch offloading и функционала DPDK. Сразу отмечу, что при этом Local IP использует большее количество flows в таблицах, что может влиять на производительность.

Помимо этого, необходимо учесть следующие граничные сценарии:

  • Локальный хост с Local IP должен иметь возможность обращаться к внешнему хосту с таким же IP адресом;

  • Локальный хост может сформировать ARP запрос, чтобы узнать MAC адрес хоста с Local IP;

  • На одном физическом сервере для разных сетей может быть установлен один и тот же Local IP на разные локальные хосты;

  • Внешний хост может прислать «Gratuitous ARP» или «ARP Announcement» пакет с тем же IP адресом, что уже используется для Local IP.

Для того чтобы локальный хост с Local IP мог обращаться к внешнему хосту с таким же IP адресом, нужно для таких пакетов игнорировать все правила трансляции «Static Local IP Translation» и не создавать запись в DNAT. Это реализовано при помощи правила «Self NAT Avoiding» в таблице 31 «Local IP».

Из-за того, что локальные порты «br-int» не тегированные и не содержат информации о сети, то с помощью правила, описанного в таблице 30 «Local Egress», в reg6 каждого пакета устанавливается идентификатор сети VLAN и далее используется для идентификации сети.

Чтобы локальному хосту можно было определить MAC адрес хоста с Local IP, необходимо реализовать локальный ARP Responder, который будет перехватывать все ARP запросы со стороны локальных портов и генерировать ответы с MAC адресом локального хоста на такие запросы. Это реализовано правилом «ARP Responder» в таблице 31 «Local IP».

Для того чтобы блокировать рассылаемые внешними хостами gARP анонсы, нужно реализовать так называемый gARP Blocker, который будет блокировать только ARP пакеты, содержащие в себе Local IP чтобы не допускать обновлений ARP адресов в кэшах локальных хостов.

Ну и конечно же, нужно учесть, что Neutron в «br-int» создает правила для предотвращения ARP/MAC Spoofing (таблицы 24 и 25). Причем эта функциональность опциональна и может быть отключена на этапе установки OpenStack. Для того, чтобы Local IP был совместим ней, перенаправление в Local Egress было добавлено в том числе и в таблицу 25.

Как использовать?

Давайте рассмотрим пример, где мы перенаправим трафик с помощью Local IP в локальный прокси. Представим, что на физическом сервере есть две виртуальные машины: хост «A» (MAC: aa:aa:aa:aa:aa:aa, IP: 10.0.0.101), на котором размещен клиент и хост «B» (MAC: bb:bb:bb:bb:bb:bb, IP: 10.0.0.102), на котором размещен прокси, а так же существует внешний хост «E» (MAC: ee:ee:ee:ee:ee:ee, IP: 10.0.0.10) на котором размещен сервис к которому будет обращаться клиент. Без Local IP клиент на хосте «A» обращается к сервису, находящемуся на хосте «E».

Пример перенаправления трафика в локальный proxy с включенным Local IP (сплошная линия) и без (пунктирная линия).
Пример перенаправления трафика в локальный proxy с включенным Local IP (сплошная линия) и без (пунктирная линия).

Назначив Local IP с адресом 10.0.0.10 на 10.0.0.102 (хост «B») мы направим трафик нашего клиента через прокси сервер, не изменяя конфигурации нашего клиента. Это можно сделать, создав объект Local IP и ассоциацию, выполнив следующие команды:

$ openstack local ip create --network public --name local_proxy --local-ip-address 10.0.0.10 +------------------+--------------------------------------+ | Field            | Value                                | +------------------+--------------------------------------+ | created_at       | 2022-02-07T11:39:55Z                 | | description      |                                      | | id               | e1918998-84c1-40d3-abd3-950e5bcb4cad | | ip_mode          | translate                            | | local_ip_address | 10.0.0.10                            | | local_port_id    | 49207b7d-52d5-4b18-b0bc-3c38bb2d08bb | | name             | local_proxy                          | | network_id       | 8bf58077-2a80-4f23-84b4-80ea1f40835e | | project_id       | 183b5dc87b774aac937f431f4e161e4e     | | revision_number  | 0                                    | | updated_at       | 2022-02-07T11:39:55Z                 | +------------------+--------------------------------------+    $ openstack local ip association create e1918998-84c1-40d3-abd3-950e5bcb4cad f8c935ce-24fc-4d55-b537-7f7bec6c2c79 +------------------+--------------------------------------+ | Field            | Value                                | +------------------+--------------------------------------+ | fixed_ip         | 10.0.0.102                           | | fixed_port_id    | f8c935ce-24fc-4d55-b537-7f7bec6c2c79 | | host             | uscpepper00644                       | | local_ip_address | 10.0.0.10                            | +------------------+--------------------------------------+

Благодаря NAT, для каждого исходящего пакета с хоста «A» на MAC bb:bb:bb:bb:bb:bb и IP адрес: 10.0.0.10, адрес назначения будет транслироваться в 10.0.0.102 и пакеты будут перенаправлены на локальный порт хоста «B». В пакетах, посланных в ответ с хоста «B» так же благодаря NAT будет транслироваться адрес отправления с 10.0.0.102 на 10.0.0.10 и таким образом пакеты будут доставлены на хост «A».

Если же в локальном ARP кэше хоста «A» не оказалось MAC адреса для 10.0.0.10, то хостом «A» будет отправлен широковещательный ARP запрос. В ответ на этот запрос хост «А» получит MAC адрес: «bb:bb:bb:bb:bb:bb», который соответствует хосту «B». В случае, если бы у нас все работало в обычном режиме, в ответе содержался бы MAC ee:ee:ee:ee:ee:ee хоста «E».

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

Степень готовности технологии Local IP

Данная технология будет доступна начиная с релиза Yoga, который запланирован на 30 марта 2022 года. На настоящий момент реализовано:

  • Neutron API – готово;

  • OpenStack CLI – готово;

  • Поддержка VLAN (ML2 драйвер) – готово;

  • Поддержка VxLAN и GRE (Native драйвер) – готово;

  • Поддержка в DevStack – готово;

  • Поддержка режима «passthrough» – не планируется в релизе Yoga (может быть реализован через allowed address pair);

  • Поддержка IPv6 – в ближайшее время не планируется;

  • Поддержка в HeatStack – в ближайшее время не планируется.

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

  1. Внутренняя документация.

  2. Спецификация.


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

История создания первого по настоящему open-source Brain-computer interface устройства (DIY)

Abbreviation

  • BCI Brain-computer interface

  • EEG Electroencephalogram

  • SBC Single-board computer

  • ADC Analog-digital converter

Меня зовут Ильдар, я радиолюбитель. Наша идея создания недорогого интерфейса Мозг-Компьютер появилась два года назад на одной из научных конференций, во время одной из футуристических бесед, еще до событий пандемии. Идея была наивной и простой — мы хотели управлять роботами силой мысли методом воображения движения. (https://en.wikipedia.org/wiki/Motor_imagery)

вот как то так

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

Очень кратко, что такое BCI. BCI измеряет сигналы ЭЭГ с поверхности головы, это сигналы в микровольтах, разделенные на несколько частотных диапазонов (Альфа — 8–13 Гц, Бета — 14–40 Гц, Тета — 4–8 Гц, Дельта — 0,5–3 Гц). Эти частотные диапазоны могут предоставить некоторую информацию о субъекте. Звучит просто, но есть пара нюансов, кроме грамотно спроектированной платы на качество сигнала существенно влияют следующие факторы:

  • любые физические нагрузки (артефакты);

  • электромагнитная интерференция;

  • качество соединений электродов, да и вообще все, действительно все.

Сигналы ЭЭГ измеряются через электроды [1, 2021], мы выбрали сухие электроды, потому что они проще в использовании (в идеале гель не нужен, но на самом деле с гелем лучше). Но даже после всего этого полученные сигналы ЭЭГ все равно не будут пригодны для получения какой-либо полезной информации. Следующим шагом является обработка сигналов, которая представляет собой попытку найти полезные корреляции в сигналах ЭЭГ и удалить другие шумы. И это огромная тема! и на самом деле, если и есть магия (или где она нужна), то она здесь. Методов очень много, и они очень разнообразны, на эту тему мы написали следующие обзорные статьи ([2, 2021], [3, 2020]). И я до сих пор работаю в этом направлении.

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

Сначала сомнения, а возможно ли? без опыта в нейронауках разработать BCI. Чтобы понять это, я много читал. Для начала, что проще: — medium, форумы, по ключевым словам — все возможные вариации с BCI. Далее я изучил все, что смог найти в известных мне библиотеках — research.google, researchgate, Elsevier, Taylor and Francis, Springer и т. д. Я понимаю, что у многих нет допуска к статьям, не находящимся в открытом доступе, это болезненная тема для многих исследователей, особенно обострившаяся после весьма печальных событий в штате Массачусетс в 2013 году.

Только у нас то, что есть, ученые публикуют не в open-access доступе не потому, что хотят скрыть свои исследования от посторонних глаз или заработать денег, а потому, что просто не нашлось спонсора для публикации. Можно возразить, что есть препринты (Arxiv например), согласен, только для научной карьеры — важен рейтинг публикации. Об этом можно говорить долго, но говорить надо и делать. Если статьи нет в открытом доступе, то пишите авторам, задавайте вопросы, никогда не стесняйтесь, это нормальный процесс, в большинстве своем авторы рады, что есть интерес к их работе. Мой процесс чтения занял 1 месяц, по несколько часов в день — но оно того стоит, т.к. позволяет понять, что есть на рынке, что нужно рынку, каковы перспективы, направления исследований и т. д. Лучше потратить время, чем заново изобретать колесо. В общем, исследование рынка вселило в меня уверенность, что да, надо это делать, особенно в формате с открытым исходным кодом.

Как мы разрабатывали — интерфейс мозг-компьютер

Сердцем BCI является ADC, а самым слабым местом устройства является часть между электродом и ADC— этот аналоговый сигнал в мкВ — который только рад собрать все возможные шумы, которые только он может найти. После оцифровки сигнала уже идут стандартные операции — это полосовой фильтр (я использовал 1–30 Гц), вам поможет любой язык — я реализовал на Python. Подходящих ADC на рынке не так много, особенно для нейрофизиологических задач — Texas Instruments и Analog devices. Мы выбрали ADS 1299 от Texas Instruments.

Попытка 1 (1 марта 2020 г.)

С первой попытки я собрал схему на макетной плате, все элементы подобраны с минимальным шумом (power supply). Как и ожидалось, все это выглядело ужасно. Ну, тем не менее, я смог связаться с АДС, изучил регистры, но количество шумов не давало мне понять, ЭЭГ это сигнал или нет.

Попытка 2 (8 октября 2020 г.)

Уже лучше, я сделал печатную плату, и успешно, плата заработала. Удалось прочитать сигнал ЭЭГ, обнаружить основные артефакты. Но размер платы был слишком велик, в этой версии использовались Wi-Fi, Bluetooth, радио, последовательный порт и SD-карта для передачи данных. Для меня главное, чтобы устройство работало, а конструкция была правильной [4, 2020].

Попытка 3 (1 января 2021 г.)

Тот же дизайн с уменьшенной формой. Устройство заработало — но так как у нас был сендвич, то я не мог надежно соединить платы друг с другом, казалось бы, простая деталь, но я потратил много времени на поиск нужных пинов, так как SPI-соединение между МК и ADC постоянно терялся.

Попытка 4 (7 апреля 2021 г.)

С учетом всех ошибок прошлого года было создано итоговое устройство — ironbci.

Использовался следующий микроконтроллер — STM32F406VE. Вычислительными возможностями в данном проекте МК особо не занимается и выбирался в зависимости от периферии (SPI). [5, 2021].

Детали проекта ironbci

GitHub (электрическая схема, Gerber-файлы, BOM-файлы, hex файл и т. д.)

Youtube. Демонстрация артефактов (жевание и моргание) на STM32F407 и ADS1299

Youtube. Iron BCI hardware — процесс разборки

Одной из основных идей было использование платы с дополнительными датчиками, среди стартапов так называемая «киллер фича» — но для меня задача убрать все артефакты из сигналов ЭЭГ. Задача состоит в регистрации сигналов ЭЭГ в повседневной жизни и использовании набора датчиков для контроля и нейтрализации артефактов в сигналах ЭЭГ. [6, 2021]. Идея еще не реализована, нужно больше данных.

Но идея очень хорошая, и надеюсь продолжить работу над ней.

Все казалось идеальным. Но случился chip-shortage. В результате себестоимость нашего прибора взлетела со 100 до 600 долларов (и это только за 8 электродов) — просто безумная цена.

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

Сделай сам, полная инструкция как создать это устройство на фабрике pcbway

https://youtu.be/VQqJwoX9bg0

Но мне не очень хотелось бросать это занятие после стольких исследований. И поэтому решил, что проще всего взять только плату АЦП от устройства ironbci и использовать ее как шилд для одноплатного компьютера.

Попытка 5 (16 октября 2021 г.)

Теперь мы подошли к PIEEG, который преобразовывает Raspberry Pi в BCI [7, 2022]. Raspberry был выбран только потому, что это самый популярный одноплатный компьютер на рынке. Обмен данными между Raspberry и платой реализован на C (важна скорость передачи)

https://github.com/Ildaron/EEGwithRaspberryPI

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

Основное применение, которое мы видим в этом, это управление робототехническими устройствами, возможности приложения зависят от фантазии и возможностей пользователя. (8, 2022)

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

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

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

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

В общем, я очень кратко описал процесс разработки, по вашим комментариям, по мере необходимости, напишу подробнее. Ваши идеи приветствуются, пишите).

Данный проект никем не финансировался, делался в свободное от работы время и все исходники находятся в открытом доступе, так что судите строго (не опечатка).

Сегодня мы находимся в процессе подачи заявки на crowdsupply для PIEEG.

https://www.crowdsupply.com/hackerbci/pieeg

Мы делаем это, чтобы создать сообщество, собрать набор данных, я надеюсь, вместе мы сможем добиться значительного прогресса в этом направлении. Обо всем писать сложно — на каждом этапе я ошибался, весь процесс разработки — это каждодневный поиск багов, как программных, так и аппаратных, каждый день решал задачи, но это правда, это нормально. Ну и немного идеологии — для меня, опенсорс это не только альтруизм (хотя и этого аргумента уже достаточно, технологии, тем более биотехнологии, должны быть направлены не на обогащение. Можно возразить, пожалуйста, но у меня есть много примеров разных гениальных людей, для которых это воспринималось, как должное), а главное способ создать что-то действительно хорошее, обратная связь творит чудеса, критика очень полезна. Я честно пришел в мир ЭЭГ, чтобы управлять механическими конечностями неинвазивным методом, доступным и простым способом. Пока не получилось, но это шаг на пути к этому.

Slack — pieeg.slack.com
email — ildar.o2010@yandex.ru
Github — https://github.com/Ildaron/EEGwithRaspberryPI
Linkedin https://www.linkedin.com/in/ildar-rakhmatulin-262a66112/

Reference

1. Rakhmatulin, I.; Gan, Y. (2021). Review Dry and Non-Contact EEG Electrodes for 2010–2021 Years. Preprints, 2021030555 (doi: 10.20944/preprints202103.0555.v1). https://www.preprints.org/manuscript/202103.0555/v1
2. Rakhmatulin, I. (2021). Progress in neural networks for EEG signal recognition in 2021. arXiv:2103.15755, https://arxiv.org/abs/2103.15755
3. Rakhmatulin, I. (2020). Review of EEG feature selection by neural networks, DOI: 10.5281/zenodo.3987894
4. Rakhmatulin, I. (2020). The electronic board to replace the reference voltage on the earlobe for EEG measurement, Measurement, 173, 108673 https://www.sciencedirect.com/science/article/abs/pii/S0263224120311854?via%3Dihub
5. Rakhmatulin, I., Parfenov, A., Traylor, Z. et al. (2021). Low-cost brain computer interface for everyday use. Exp Brain Res 239, 3573–3583 https://doi.org/10.1007/s00221-021-06231-4
6. Rakhmatulin, I. (2022). ironbci. Open source. Brain-computer interface with the embedded board to monitor the physiological subject’s condition and environmental parameters. arXiv:2111.03656
7. Rakhmatulin, I., Volkl, S. (2022). PIEEG: Turn a Raspberry Pi into a Brain-Computer-Interface to measure biosignals, arXiv:2201.02228
8. Rakhmatulin, I., Volkl, S. (2022). Brain-Computer-Interface controlled robot via RaspberryPi and PiEEG, arXiv:2202.01936.


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

Автоматизированный бот на Selenium

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

Помимо автоматизированного веб-тестирования, веб-скрейпинг с  Selenium на Python – крайне популярный вариант, который вы можете реализовать с меньшим количеством кода и ошибок на Python. Как QA-инженер, я по-прежнему использую другие языки программирования, такие как Java и JavaScript в связке с Selenium, но Python – мой основной инструмент для простых/комплексных задач веб-автоматизации.

Как я уже упоминал, Python – третий по популярности язык после HTML/CSS и JavaScript. Бот на Selenium с Python может широко использоваться для автоматизации различных сценариев и задач.

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

Инструменты для создания бота

Одной из основных целей создания бота является использование возможностей, предлагаемых Selenium для автоматизации взаимодействия с web-элементами в DOM. Существует набор инструментов Selenium для автоматизации веб-браузеров, которые можно использовать для целого ряда задач автоматизации, такие как веб-скрейпинг, автоматизированное веб-тестирование, кросс-браузерное тестирование и т.д.

Итак, давайте посмотрим на основные инструменты, необходимые для создания бота с Selenium.

Selenium

Библиотека Python – обертка над Selenium WebDriver, обеспечивает соединение и простой API для написания функциональных тестов для автоматизации веб-задач, таких как нажатие на кнопки, навигация по страницам и заполнение форм.

Скрипт теста не взаимодействует напрямую с браузером. Selenium WebDriver — это ядро фреймворка Selenium. Как говорится в этом руководстве, Selenium WebDriver играет важную роль в соединении с браузером с помощью соответствующего драйвера браузера. Однако, вы можете еще глубже погрузиться в Selenium, если хотите узнать больше о его компонентах.

Если тесты должны выполняться в локальной Selenium Grid, на целевой машине должен быть установлен соответствующий драйвер браузера: 

Firefox

GeckoDriver for Firefox (https://github.com/mozilla/geckodriver/releases)

Chrome

ChromeDriver for Chrome (https://sites.google.com/a/chromium.org/chromedriver/downloads)

Microsoft Edge

Microsoft Edge Driver (https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)

Safari

WebDriver for Safari (https://webkit.org/blog/6900/webdriver-support-in-safari-10/)

Загружать и устанавливать драйверы браузера необходимо только если вы хотите выполнять тесты в локальном Selenium Grid. В случае с удаленным Selenium WebDriver тесты выполняются в облачном Selenium Grid (например, LambdaTest).

Фреймворки для автоматизации на Python

Python – самый популярный выбор для автоматизированного тестирования с Selenium, ведь сам по себе язык не такой многословный, поддерживает динамическую типизацию, дает беспроблемную отчетность и многое другое. Широкий спектр фреймворков Selenium поддерживает параллельное тестирование, что ускоряет время выхода на рынок.

В этом руководстве я затронул основы Selenium Python, так позвольте мне углубиться в популярные фреймворки Selenium для автоматизации тестирования:

PyUnit (Unittest)

Unittest (или PyUnit) – это фреймворк для тестирования на Python по умолчанию, который поставляется «из коробки». Этот фреймворк вдохновлен другим популярный фреймворком JUnit.

Unittest обеспечивает простое и гибкое выполнение тест-кейсов с быстрой генерацией отчетов о тестировании. Unittest использует camelCase вместо соглашения об именовании snake_case в Python.

Руководство по Selenium PyUnit может стать хорошей отправной точкой для тех, кто хочет использовать фреймворк для автоматизированного тестирования.

PyTest

PyTest – это открытый фреймворк для тестирования, который поддерживает модульное тестирование, функциональное и тестирование API. Он доступен для Python версии 3.5 и выше. 

Объектная модель страницы (POM) в Selenium Python играет важную роль в улучшении поддержки и переиспользовании кода. Я отдаю предпочтение PyTest, а не PyUnit из-за богатого набора плагинов – настоящего блага для QA-инженеров.

Вот несколько популярных плагинов PyTest для QA-инженеров:

  • pytest-randomly

  • pytest-cov

  • pytest-django

  • pytest-bdd

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

Robot

Robot – это открытый фреймворк для автоматизации, который позволяет писать тест-кейсы на Gherkin. Лучше всего работает в методологии Behaviour Driven Development (BDD) в связке с Selenium и Gherkin. Robot также используется для приемочного TDD и автоматизации роботизированных процессов (RPA). 

Ядро Robot написано на Python, но он также может работать с Jython и IronPython. Изначально он не поддерживает параллельное тестирование, но предоставляет множество простых в использовании расширений и библиотек.

Для демонстрации реализации бота Selenium с Python я собираюсь использовать фреймворк PyTest.

Behave

Behave – фреймворк для тестирования, работающий в связке с Behavior-Driven Development (BDD). У него обширная документация и он хорошо поддерживается сообществом. Еще он обеспечивает интеграцию с Django и Flask – двумя самыми популярными веб-фреймворками на Python. 

Behave также пригодится для blackbox – тестирования. Связка BDD, Behave и Selenium имеет свой собственный набор преимуществ и недостатков, но это все еще отличный фреймворк для автоматизации тестирования на Python.

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

Планировщики задач для Python

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

Планировщик задач можно использовать для запуска пакетного файла (или .bat), который запускает соответствующий скрипт на Python. 

Вот некоторые распространенные программы, обеспечивающие планирование задач на Python:

Cron

Cron – планировщик задач, который основывается на времени в Unix-подобных операционных системах, таких как Linux и macOS. Он позволяет планировать такие задачи, как создание резервных копий, логирование и запуск скриптов.

Планировщик задач Windows

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

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

Для текущей задачи я собираюсь использовать планировщик задач Windows вместе с библиотекой Win32com – тонкой оберткой на Python, которая помогает автоматизировать приложения Windows. 

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

Создание бота на Selenium с Python

Выполните указанные ниже шаги, чтобы создать среду разработки для нашей реализации:

Создание виртуальной среды и установка зависимостей

Виртуальная среда (или virtualenv) — инструмент для создания изолированных сред Python. Для этой цели в Python есть модуль venv, который поддерживает создание облегченных «виртуальных сред» с изолированными каталогами.

Вы можете ознакомиться с этим руководством для быстрого погружения в автоматизированное тестирование с помощью Selenium и Python.

python3 -m venv env
  1. Выполните одну из команд ниже, чтобы активировать эту виртуальную среду.

Windows

.\env\Scripts\activate

Linux

source env/bin/activate
  1. Выполните следующую команду, чтобы установить Selenium для Python:

pip install selenium
  1. Выполните следующую команду, чтобы установить фреймворк PyTest:

pip install pytest
  1. Установите пакет pywin32 для работы с планировщиком задач Windows:

 pip install pywin32

Структура папок для тестовых скриптов

Проект состоит из двух файлов:

  • main.py – Содержит основной скрипт, который позволяет входить в платформу LambdaTest и получать подробную информацию о соответствующих тестах.

  • scheduler.py – Содержит реализацию для планирования запуска тестов.

Реализация бота

Для демонстрации создания бота Selenium с Python мы автоматизируем тестовый сценарий входа на платформу LambdaTest. Тестируемый URL-адрес — https://accounts.lambdatest.com/login

Поскольку тест демонстрируется в LambdaTest Grid, я использую удаленный WebDriver в Selenium вместо локального. Для начала мы импортируем необходимые пакеты.

from selenium import webdriver

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

username = "<YOUR USERNAME>" access_key = "<YOUR ACCESS KEY>"

Создадим класс TestClass со следующим функционалом:

  • Setup_method – функция настройки удаленного драйвера и его свойств.

# Generate capabilities from here: https://www.lambdatest.com/capabilities-generator/ # setUp runs before each test case and def setup_method(self): desired_caps = {        "build": "your build name",        "name": "your test name",        "platform": "Windows 10",        "browserName": "Chrome",        "version": "92.0",        "selenium_version": "3.13.0",        "geoLocation": "IN",        "chrome.driver": "91.0", } """ Setup remote driver        -------        username and access_key can be found on the lambdatest platform   """ self.driver = webdriver.Remote(        command_executor="https://{}:{}@hub.lambdatest.com/wd/hub".format(        username, access_key        ),        desired_capabilities=desired_caps )
  • Teardown_method – функция для разрыва соединения после каждого тест-кейса.

def teardown_method(self):        self.driver.quit()
  • Test_login – Реализация этой функции используется для входа в дашборд LambdaTest. Здесь я использую SendKeys в Selenium для заполнения формы входа, чтобы войти на сайт LambdaTest. Вот синтаксис метода SendKeys в Selenium Python:

element.send_keys("text to enter")

Для определения местоположения соответствующих веб-элементов я использую локатор XPath в Selenium. Однако вы можете использовать другие популярные локаторы Selenium, такие как ID, Name, linktext и т.д. для определения местоположения веб-элементов.

Ниже показан синтаксис метода find_element_by_xpath() в Selenium Python. В качестве альтернативы вы также можете использовать метод driver.find_element(By.XPATH) для определения местоположения элемента с помощью локатора XPath.

element = driver.find_element_by_xpath("xpath_here")   driver.find_element(By.XPATH, "xpath")

Вот как выглядит весь метод входа в систему (test_login):

def test_login(self):        """        this function logins you in lambdatest dashboard        """        LOGIN_URL = "https://accounts.lambdatest.com/login"        DASHBOARD_URL = "https://accounts.lambdatest.com/dashboard"        self.driver.get(LOGIN_URL)        login_email = self.driver.find_element_by_xpath(            "//input[@id='email']"        )        login_password = self.driver.find_element_by_xpath(            "//input[@id='password']"        )        login_button = self.driver.find_element_by_xpath(            "//button[@id='login-button']"        )          login_email.send_keys(email)        login_password.send_keys(password)        login_button.click()          # if we are on right page        if self.driver.current_url == DASHBOARD_URL :            assert True            # time to get recent tests            self.get_recent_tests()        else:            print(" something went wrong !!")            assert False
  • Get_recent_tests – Как только я вошел в дашборд LambdaTest, извлекаю из него все последние тесты.

Как видно выше, .cut-text — общий класс для всех тегов, которые нам нужно прочитать. Далее я сделаю веб-скрейпинг для получения необходимой информации.

titles = self.driver.find_elements_by_class_name("cut-text")

Здесь я получаю текст из соответствующих тегов:

def get_recent_tests(self):        titles = self.driver.find_elements_by_class_name("cut-text")        titles_list = []        for i in titles:            titles_list.append(i.text)        message = ' '.join(titles_list[0::2])        print(message)        send_email(message)

Как видно из реализации, мы используем Selenium 3 Grid для тестирования. С выпуском стабильной версии Selenium 4 многие QA-инженеры переносят тесты в Selenium 4 Grid. Прежде чем сделать это, я рекомендую сравнить Selenium 3 и Selenium 4, чтобы можно было беспрепятственно переносить тесты.

Отправка электронных писем через Selenium для Python

В Python есть встроенная библиотека smtplib для отправки электронных писем с защищенным подключением с использованием SMTP_SSL() и .starttls(). Библиотека smtplib использует протокол RFC 821 для SMTP.

Для отправки электронного письма через smtplib я создал функцию, которая принимает сообщение в виде строки и отправляет электронное письмо.

def send_email(message):    context = ssl.create_default_context()    try:        server = smtplib.SMTP(smtp_server,port)        server.ehlo() # Can be omitted        server.starttls(context=context) # Secure the connection        server.ehlo() # Can be omitted        server.login(sender_email, sender_password)        server.sendmail(sender_email, receiver_email, message)        server.close()    except:        print(" failed to send email ")

Так выглядит итоговая реализация main.py.

from selenium import webdriver import smtplib, ssl   port = 587 smtp_server = "smtp.gmail.com" sender_password = "<YOUR_PASSWORD>" sender_email = "<YOUR_EMAIL>" receiver_email = "<EMAIL_WHERE_YOU_WANT_TO_SEND>"   def send_email(message):    context = ssl.create_default_context()    try:        server = smtplib.SMTP(smtp_server,port)        server.ehlo() # Can be omitted        server.starttls(context=context) # Secure the connection        server.ehlo() # Can be omitted        server.login(sender_email, sender_password)        server.sendmail(sender_email, receiver_email, message)        server.close()    except:        print(" failed to send email ")   username = "<YOUR_LAMBDATEST_USERNAME>" access_key = "<YOUR__LAMBDATEST_ACCESS_KEY>"   class TestClass():    def setup_method(self):        desired_caps = {            "build": "your build name",            "name": "your test name",            "platform": "Windows 10",            "browserName": "Chrome",            "version": "92.0",            "selenium_version": "3.13.0",            "geoLocation": "IN",            "chrome.driver": "91.0",        }        """        Setup remote driver                -------                username and access_key can be found on lt platform          """        self.driver = webdriver.Remote(            command_executor="https://{}:{}@hub.lambdatest.com/wd/hub".format(                username, access_key            ),            desired_capabilities=desired_caps,        )      # tearDown runs after each test case    def teardown_method(self):        self.driver.quit()      def test_login(self):        """        this function logins you in lambdatest dashboard        """        LOGIN_URL = "https://accounts.lambdatest.com/login"        DASHBOARD_URL = "https://accounts.lambdatest.com/dashboard"        self.driver.get(LOGIN_URL)        login_email = self.driver.find_element_by_xpath(            "//input[@id='email']"        )        login_password = self.driver.find_element_by_xpath(            "//input[@id='password']"        )        login_button = self.driver.find_element_by_xpath(            "//button[@id='login-button']"        )          login_email.send_keys(email)        login_password.send_keys(password)        login_button.click()          # if we are on the right page        if self.driver.current_url == DASHBOARD_URL :            assert True            # time to get recent tests            self.get_recent_tests()        else:            print("something went wrong !!")            assert False      def get_recent_tests(self):               titles = self.driver.find_elements_by_class_name("cut-text")        titles_list = []        for i in titles:            titles_list.append(i.text)        message = ' '.join(titles_list[0::2])        send_email(message)

Планирование теста Selenium на Python

Планировщик позволяет запланировать выполнение тестовых скриптов в заданный момент времени или при заданных условиях. Для этой задачи я использую планировщик задач Windows, который представляет из себя приложение с графическим интерфейсом. Я использую библиотеку Win32com для программного планирования триггеров.

Win32com — библиотека API, тонкая оболочка Python, которая позволяет автоматизировать приложения Windows, как экземпляры планировщика задач Windows.

Планировщик задач Windows использует объекты COM (Component Object Model), что позволяет управлять приложениями Windows из другой программы или скрипта. COM-объекты определяются в реестре Windows. Поскольку COM-объекты сами по себе являются «объектами», их можно использовать для тестового скрипта и с ними можно взаимодействовать программно.

Краткий код на Python для запуска тестового скрипта в планировщике задач Windows:

  • Определение клиента win32com из библиотеки pywin32:

scheduler = win32com.client.Dispatch('Schedule.Service') scheduler.Connect() root_folder = scheduler.GetFolder('\\') task_def = scheduler.NewTask(0)
  • Настройка важных аргументов

start_time: Установите время запуска скрипта.

start_time = datetime.datetime.now() + datetime.timedelta(minutes=1)

Repetition.Duration: продолжительность времени (в днях), в течение которого необходимо повторять выполнение программы. В данном случае я хочу запустить этот скрипт на 10 дней.

#Repeat for 10 days num_of_days = 10 trigger.Repetition.Duration = "P"+str(num_of_days)+"D"

Repetition.Interval: Переменная указывает, с каким интервалом должна выполняться программа. Здесь я настроил запуск скрипта через каждые 6 часов.

#For every 6 hour trigger.Repetition.Interval = "PT6H"

action.Path: Путь к интерпретатору Python или бинарному файлу pytest.

action.Path = r'C:\Users\vinayak\selenium_test\env\Scripts\pytest.exe'

action.Arguments: Путь к скрипту, который должен выполняться.

action.Arguments = r'C:\Users\vinayak\selenium_test\main.py'

Для кода планировщика давайте создадим файл scheduler.py.

import datetime import win32com.client   scheduler = win32com.client.Dispatch('Schedule.Service') scheduler.Connect() root_folder = scheduler.GetFolder('\\') task_def = scheduler.NewTask(0)   # Start time of script start_time = datetime.datetime.now() + datetime.timedelta(minutes=1)   # for running it one time TASK_TRIGGER_DAILY = 1 trigger = task_def.Triggers.Create(TASK_TRIGGER_DAILY)   #Repeat for 10 day num_of_days = 10 trigger.Repetition.Duration = "P"+str(num_of_days)+"D"   #For every 6 hour trigger.Repetition.Interval = "PT6H"  trigger.StartBoundary = start_time.isoformat()   # Create action TASK_ACTION_EXEC = 0 action = task_def.Actions.Create(TASK_ACTION_EXEC) action.ID = 'TRIGGER BATCH' action.Path = r'C:\Users\vinayak\selenium_test\env\Scripts\pytest.exe' action.Arguments = r'C:\Users\vinayak\selenium_test\main.py'   # Set parameters task_def.RegistrationInfo.Description = 'Test Task' task_def.Settings.Enabled = True task_def.Settings.StopIfGoingOnBatteries = False   # Register task # If task already running, it will be updated TASK_CREATE_OR_UPDATE = 6 TASK_LOGON_NONE = 0 root_folder.RegisterTaskDefinition(    'Test Task',  # Task name    task_def,    TASK_CREATE_OR_UPDATE,    '',  # No user    '',  # No password    TASK_LOGON_NONE

Обертка

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

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


Приглашаем всех желающих на открытый урок «Написание автотестов для UI-части интернет-магазина и формирование отчётности».


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

Как настроить резервированную схему сети с двумя файерволами FortiGate

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

Подробно описанные шаги — под катом.

Какие задачи решает схема


Такое резервирование позволяет решить все перечисленные задачи одновременно:

  • Использовать разнообразные платформы — выделенные серверы, облачную платформу, облако VMware — для размещения проекта.
  • Объединить вычислительные ресурсы в единую изолированную сеть, защищенную от внешних угроз — например, DDoS-атак.
  • Разделить проект на несколько окружений (например, Production, Staging, Testing, Development), изолированных друг от друга на уровне сети провайдера.
  • Контролировать доступ как между проектами/окружениям, так и внешними сетями.
  • Сделать проект максимально доступным из интернета, даже в случае выхода из строя или планового обслуживания оборудования в одном из ДЦ.

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

В рассматриваемом примере мы используем:

  • IaaS-продукты Selectel: выделенные серверы, облачную платформу, облако на базе VMware
  • Услугу L3 VPN, которая строится на базе отдельной локальной сети Selectel, не пересекающейся с интернет-каналами.
  • Разные VRF (Virtual Routing and Forwarding instance), или виртуальные маршрутизаторы, в локальной сети Selectel.
  • Два файервола FortiGate, выполняющие роль пограничных роутеров и размещенные в разных городах.
  • Внешнюю anycast-сеть, которая может быть доступна одновременно из разных местоположений (выдается дата-центром).
  • Линковочные /29 подсети.

Итоговая схема сети выглядит так:

У нас есть роутинг-инстанс — vrf_1 (красные линии). Он объединяет вычислительные ресурсы, расположенные в Санкт-Петербурге и Москве: выделенные серверы, виртуальные машины, развернутые в облачной платформе Selectel и в облаке на базе VMware.

Для доступа к проектам из интернета выделена anycast-сеть 31.184.217.248/29.

Также выделены две внешние /29 сети для организации связи между FortiGate клиента и сетевым оборудованием провайдера. Адреса из данных сетей будут использоваться для настройки протоколов маршрутизации (Border Gateway Protocol, BGP), через которые клиент будет анонсировать свою anycast-сеть на оборудование в дата-центр. Также они могут использоваться для доступа в интернет.

Мы не используем /31 стыковочные сети, так как наш шлюз резервируется на базе технологии VRRP (подключено по умолчанию для FortiGate).

Чтобы реализовать расписанную схему, необходимо:

  • Заказать необходимое количество выделенных серверов, файерволов, виртуальных машин.
  • Понять, сколько изолированных виртуальных роутеров потребуется и какие серверы должны быть ими связаны.
  • Определиться, сколько белых IP-адресов необходимо для доступа к клиентским сервисам из интернета.
  • Заказать и настроить VRF.
  • Настроить маршрутизации на клиентских серверах.
  • Создать виртуальные машины с файерволами FortiGate.
  • Настроить FG через CLI.
  • Настроить BGP на FortiGate в локальной сети.
  • Настроить BGP во внешней сети.
  • Определить Master/Slave-роли для FortiGate.
  • Настроить NAT на FortiGate.
  • Протестировать схемы.

Заказ и настройка VRF


Мы опустим описание первых трех шагов, потому что они не связаны с настройками сети. О том, как арендовать серверы в Selectel, и что такое виртуальный роутер, можно почитать в базе знаний компании или обратиться за консультацией по почте sales@selectel.ru.

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

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

Мой текст тикета выглядел примерно так:

Здравствуйте!

Просьба собрать L3 VPN.

Локация: облачная платформа ru-7
Проект ID: d0f49f94c5a44b1dbe82ac41d20d635a
Подсеть: 10.10.1.0/24, в качестве шлюза будет выступать адрес 10.10.1.254, для резервирования с вашей стороны можете забрать адреса 10.10.1.252-10.10.1.253
Далее адреса для шлюза и резервирования для каждой подсети будут аналогичными.

Локация: облачная платформа ru-9
Проект ID: d0f49f94c5a44b1dbe82ac41d20d635a
Подсеть: 10.10.2.0/24

Локация: MSK-2
VLAN:2450
Подсеть: 10.10.3.0/24

Локация: SPB-5
VLAN:1303
Подсеть: 10.10.4.0/24

Локация: VMware SPB
Виртуальный дата-центр: s-3327-SPB1-S1-vDC59
Подсеть: 10.10.5.0/24

Локация: VMware MSK
Виртуальный дата-центр: s-3327-MSK1-S1-vDC30
Подсеть: 10.10.6.0/24

Какие изменения в инфраструктуре произойдут после этих действий?

В облачной платформе будет добавлена подсеть с доступом в локальную сеть L3 VPN. Для удобства ее можно переименовать. Чтобы изменить CIDR, потребуется оформить запрос через тикет-систему. Если вы планируете пользоваться сетью в дальнейшем, удалять ее нельзя, иначе придется заново открывать запрос на ее добавление в локальную сеть L3 VPN. Обращаем внимание, что существующую в облачной платформе подсеть добавить в L3 VPN невозможно по техническим причинам;

В облаке на базе VMware ситуация аналогичная: после заказа подсеть появится в vCloud Director.

Для выделенных серверов фиксированной конфигурации дополнительно просить о подключении локального порта не нужно. Серверы Selectel заранее подключены в обе плоскости сети — локальную и интернет.

Если у вас сервер произвольной конфигурации или вы разместили свое оборудование в Selectel (colocation), потребуется запросить подключение вашего оборудования к локальной сети Selectel через тикет

Дополнительно для построения BGP-сессий во внешней сети потребуется выделить по стандартной /29 внешней подсети для каждого файервола. В нашей схеме в
качестве примера будут использоваться сети 77.223.107.152/29 (Мск) и и 94.26.237.112/29 (СПб).

Настройка маршрутизации на клиентских серверах


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

Здесь будут полезны статьи по настройке маршрутов в L3 VPN-сети и настройке облака на базе VMware с нуля.

Создание виртуальных машин с файерволами FortiGate


В качестве файерволов мы выбрали Fortinet FortiGate (FG). Оба мы развернули из официального образа на виртуальной машине в облачной платформе. Отличий в конфигурировании виртуального и «железного» FG нет. Приступаем к развертыванию образа и настройке FG.

На что обратить внимание, если вы разворачиваете FortiOS на виртуальной машине в облачной платформе Selectel: для добавления портов в конфигурацию FG необходимо в панели управления облачной платформой на вкладке «Порты» добавить порт, затем программно перезапустить виртуальную машину с ОС FortiOS. Поэтому советуем заранее просчитать максимальное необходимое количество портов, которое потребуется для полноценной работы инфраструктуры с использованием FG.

В нашем примере потребуется добавить еще два порта (первый порт появляется, когда мы указываем его в поле «Сеть» при создании виртуальной машины).

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

Первичная настройка FG через CLI


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

Итоговая конфигурация портов в CLI для FortiGate MSK будет выглядеть так:

 config system interface     edit "port1"         set vdom "root"         set ip 10.10.1.200 255.255.255.0         set allowaccess ping ssh         set type physical         set snmp-index 1     next     edit "port2"         set vdom "root"         set ip 77.223.107.154 255.255.255.248         set allowaccess ping ssh http         set type physical         set snmp-index 5     next     edit "port3"         set vdom "root"         set ip 31.184.217.250 255.255.255.248         set allowaccess ping         set type physical         set snmp-index 6     next ... end 

Port 1 — располагается в локальной сети, которая прокинута в L3 VPN;
Port 2 — внешняя адресация;
Port 3 — anycast-подсеть (для анонсирования подсети в интернет, так как активных сервисов на серверах у нас пока нет).


Настройка BGP на FortiGate в локальной сети


Для поднятия BGP-сессий с L3 VPN-роутерами Selectel необходимо сделать заявку через тикет в панели управления. В нем нужно указать IP-адрес, который используется на FortiGate (в примере это 10.10.1.200 и 10.10.2.200 на FortiGate MSK).

В ответе будет следующая информация:

— IP-адреса роутеров Selectel (в примере 10.10.1.252 и 10.10.1.253);
— Selectel ASN (в примере 64530);
— Ваша ASN (в примере 65500).

Пример запроса на подключение BGP во внешней сети:

Локация: MSK-1 VLAN: 2380 IP-адрес для BGP-сессии: 212.41.3.146 Маршрутная политика: default route only Номер AS: 52016 ID услуги: b3d3fst1a-81tt-4d12-7c77-d028526d81b0 

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

Итоговый конфиг BGP для локальной сети:

config router bgp     set as 65500     set router-id 10.10.1.200     config neighbor         edit "10.10.1.252"             set interface "port1"             set remote-as 64530         next         edit "10.10.1.253"             set interface "port1"             set remote-as 64530         next     end

Можно также настроить BGP через neighbor-range. Это значит, что сессия поднимется с любым адресом из заданного диапазона:

config neighbor-group         edit "selectel"             set remote-as 64530         next     end     config neighbor-range         edit 2             set prefix 10.20.1.0 255.255.255.0             set neighbor-group "selectel"         next     end 

Несмотря на то, что router-id отличен от того, который сконфигурирован как адрес соседа на другом конце, сессия установится в Established. В качестве router-id может быть указан внешний адрес, тогда сессии поднимутся и во внешней, и в локальной сетях. Если router-id будет содержать в себе адрес из диапазона локальных адресов, то локальные сессии поднимутся, а внешние нет.

Настройка BGP во внешней сети


Чтобы сессии установились во внешней сети, потребовалось изменить адрес router-id на внешний. Сессии в локальной сети при этом переустановились.

FG анонсирует в интернет подсеть 31.184.217.248/29 (напомним, что это anycast-подсеть) и принимает маршрут по умолчанию (0.0.0.0/0) от пограничных роутеров Selectel.

В Selectel для успешного построения BGP-сессии с бордерными роутерами необходимо:

  • прописать опцию multihop (set ebgp-enforce-multihop enable),
  • выставить TTL не менее 10 (set ebgp-multihop-ttl),
  • прописать статический маршрут до адреса соседа (в нашем случае достаточно будет маршрута до /32 адреса).

С учетом всех вводных итоговый конфиг выглядит так:

 config router bgp     set as 65500     set router-id 77.223.107.154     config neighbor         edit "<selectel-brd-1>"             set ebgp-enforce-multihop enable set ebgp-multihop-ttl 10             set interface "port2"             set prefix-list-in "default_from_selectel_inet"             set prefix-list-out "anycast_subnet_out"             set remote-as 50340         next         edit "<selectel-brd-2>"             set ebgp-enforce-multihop enable             set ebgp-multihop-ttl 10             set interface "port2"             set prefix-list-in "default_from_selectel_inet"             set prefix-list-out "anycast_subnet_out"             set remote-as 50340         next     end    config router prefix-list     edit "anycast_subnet_out"         config rule             edit 1                 set prefix 31.184.217.248 255.255.255.248                 unset ge                 unset le             next             edit 2                 set action deny                 set prefix any                 unset ge                 unset le             next         end     next     edit "default_from_selectel_inet"         config rule             edit 1                 set prefix 0.0.0.0 0.0.0.0                 unset ge                 unset le             next         end     next end  config router static     edit 4         set dst <selectel-brd-1> 255.255.255.255         set gateway 77.223.107.153         set device "port2"     next     edit 1         set dst <selectel-brd-2> 255.255.255.255         set gateway 77.223.107.153         set device "port2"     next end 

В результате мы получили следующую таблицу маршрутизации на FG:

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

Так как мы добавили еще port 3 с адресом из anycast-подсети, сделаем так, чтобы данная подсеть начала анонсироваться через BGP и стала доступна из интернета. Для этого необходимо настроить редистрибуцию на FortiGate следующим образом:

config redistribute "connected"         set status enable     end

Аналогично настраиваем сессию со вторым бордерным роутером.

Таким же образом настраиваем FG в СПб.

Определение Master/Slave ролей для FortiGate


Рассматриваемая нами топология предполагает, что FortiGate работают по схеме Master/Slave. В нашем случае мастером будет FortiGate в Москве, а бэкапом — FG в Санкт-Петербурге. Это значит, что при отсутствии нештатных ситуаций в инфраструктуре, все активные сервисы будут располагаться и работать в московской части инфраструктуры.

Как обеспечить распределение ролей для FortiGate, мы описали ниже.

Применим список правил (route-map, объект, в котором указываются атрибуты для управления приоритетами маршрутов) на FG, располагающемся в Санкт-Петербурге, чтобы сделать его бэкапом во внешней и локальной сети. Для этого будем использовать:

  1. AS Path Prepend (во внешней сети)
  2. MED (в локальной сети).

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

Technical Tip: BGP AS-Path Prepending Configuration Example

Настройки route-map на FG в СПб (бэкап):

config router route-map     edit "Secondary_exit"         config rule             edit 1                 set set-aspath "65500 65500 65500"                 unset set-ip-nexthop                 unset set-ip6-nexthop                 unset set-ip6-nexthop-local                 unset set-originator-id             next         end     next     edit "Secondary_exit_local"         config rule             edit 1                 unset set-ip-nexthop                 unset set-ip6-nexthop                 unset set-ip6-nexthop-local                 set set-metric 500                 unset set-originator-id             next         end     next end 

В это время активный маршрут до anycast-подсети 31.184.217.248/29 ведет на московский FG.

Настройка NAT на FortiGate


Далее для упрощения конфигурирования правил NAT можно перейти в WEB панель FG.

Настраиваем SNAT (механизм подмены адреса источника пакета):

Метод: One-to-one (механизм подмены локального адреса на внешний).

Внешний адрес: адрес из anycast-подсети.

Настраиваем DNAT (механизм подмены адреса назначения пакета):

В данном примере 10.10.6.2 — это адрес виртуальной машины в VMware.

P.S: На FG DST NAT называется VIP (Virtual IPs).

Настройка Firewall Policy на FortiGate


Создаем необходимые файервольные правила для прохождения трафика из интернета в локальную сеть и обратно.

Те же настройки нужно будет добавить на FG в СПб.

Пример настроек из примера выше в CLI:

config firewall policy     edit 1         set name "LAN_to_WAN"         set uuid f122f4a0-d40d-51eb-13d6-2bcda4bbb967         set srcintf "port1"         set dstintf "port2"         set srcaddr "lan_vrf_1"         set dstaddr "all"         set action accept         set schedule "always"         set service "ALL_TCP" "PING" "SSH" "TRACEROUTE"         set ippool enable         set poolname "snat"         set nat enable     next     edit 2         set name "WAN_to_LAN"         set uuid 19ad41c8-d40e-51eb-5332-1b1f167774ff         set srcintf "port2"         set dstintf "port1"         set srcaddr "all"         set dstaddr "WAN_to_LAN_31.184.217.252"         set action accept         set schedule "always"         set service "ALL_TCP" "PING" "SSH" "TRACEROUTE"         set fixedport enable         set nat enable     next    end 

lan_vrf_1 — это подсеть 10.10.0.0/16.

edit "lan_vrf_1"         set uuid c90d6cf2-d40d-51eb-9a1d-554fdb82ae1d         set subnet 10.10.0.0 255.255.0.0     next end 

WAN_to_LAN_31.184.217.252 — это правило DST NAT.

config firewall vip     edit "WAN_to_LAN_31.184.217.252"         set uuid b767c3a0-3b2b-51ec-b73d-62bc3b513471         set extip 31.184.217.252         set mappedip "10.10.6.2"         set extintf "any"         set portforward enable         set protocol icmp     next end

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

Тестирование схемы (часть 1)

На схеме FortiGate в Санкт-Петербурге является бэкапом (мы настроили такое поведение в разделе «Определение Master/Slave ролей для FortiGate»), и все активные маршруты ведут на FortiGate в Москве.

Рассмотрим схему в действии с разных сторон.

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

Возьмем, например, железный сервер в СПб (10.10.4.2) и виртуальную машину в Москве в облаке VMware (10.10.6.2).

10.10.4.2

10.10.6.2

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

10.10.4.2:

10.10.6.2:

Трафик в интернет идет через файервол. Внешних адресов на этих серверах нет.

10.10.4.2:

10.10.6.2:

Проверяем отсутствие возможности у серверов выйти в интернет при отключении файервола в Москве (мастер-файервол). На машинах запущена команда «ping 8.8.8.8».

Отключаем файервол в панели управления:

Результаты запуска утилиты ping:

с машины 10.10.4.2:

с машины 10.10.6.2:

Трассировка до отключения (слева) и после (справа) московского FortiGate:

с машины 10.10.4.2:

с машины 10.10.6.2:

Видим, что трафик после отключения московского мастер-файервола пошел через резервный FG, расположенный в СПб.

Тестируем возвращение мастер-файервола.

Результаты пинга 8.8.8.8:

с машины 10.10.4.2:

с машины 10.10.6.2:

По трассировкам будет видна обратная ситуация: сначала трафик шел через СПб, потом ушел в МСК.

Фиксируем приличные потери. Это происходит потому, что сессия в интернет-сети поднимается на долю секунды быстрее, чем в локальной сети. Поэтому дефолтный маршрут (0.0.0.0/0) начинает анонсироваться в локальную сеть только при следующем сообщении BGP update. По дефолту на FG таймер анонсирования подсетей равен 30 секундам. Чтобы уменьшить время даунтайма, выставим таймер в 2 секунды на московском FG для соседей в локальной сети.

Настройка таймера:

config neighbor           Description: BGP neighbor table.           edit <ip>               set advertisement-interval {integer} 

Итоговый конфиг для соседей в локальной сети:

config router bgp     set as 65500     set router-id *белый IP-адрес*     config neighbor         edit "10.10.1.252"             set advertisement-interval 2             set interface "port1"             set remote-as 64530         next         edit "10.10.1.253"             set advertisement-interval 2             set interface "port1"             set remote-as 64530         next     end 

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

Результаты пинга 8.8.8.8:

10.10.4.2:

10.10.6.2:

Вероятно, изменение таймеров — не самое лучшее решение проблемы, но оперативно найти и применить какой-либо другой workaround не удалось.

Тестирование схемы (часть 2)


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

Для простоты представим, что на виртуальной машине в Москве 10.10.6.2 крутится сервис, который транслируется через NAT на anycast-адрес 31.184.217.252.

На обоих файерволах настроено одно и то же правило DST NAT:

Из любой сети (домашняя/офисная/другая) ставим на ping адрес 31.184.217.252 и/или запускаем трассировку.

Выключаем мастер FG (московский) через панель управления, тем самым имитируем аварию/работы.

Спустя несколько миллисекунд во внешней сети маршрут перестраивается, и теперь anycast-подсеть доступна через петербургский FG.

Слева — до отключения FG в МСК, справа — после.

Результаты пинга:

Включаем московский FG в панели управления.

Получаем следующий результат утилиты ping:

Заключение


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

На данный момент описанная схема уже эксплуатируется в реальных проектах на сети Selectel.

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


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

Security Week 2209: криптография в смартфонах

На прошлой неделе исследователи из Тель-Авивского университета опубликовали научную работу, в которой сообщили об обнаружении серьезных недостатков в системе шифрования данных смартфонов Samsung. Уязвимости, на данный момент исправленные, были найдены в защищенном приложении Keymaster Trusted Application.

Компания Samsung на данный момент идентифицировала и закрыла две связанные между собой уязвимости. Первая — CVE-2021-25444 в том самом приложении Keymaster. С помощью повторного использования вектора инициализации у потенциального атакующего имелась возможность «сломать» механизм авторизации, расшифровав секретные ключи. Вторая уязвимость (CVE-2021-25490) позволяет провести аналогичную атаку на более современные смартфоны Samsung, в которых используется слегка модифицированный механизм доставки зашифрованных ключей. Была показана и практическая атака: кража приватных ключей для авторизации на веб-сайтах с использованием протокола FIDO2.

Помимо демонстрации уязвимостей, в работе подробно описывается механизм Trusted Execution Environment, точнее, реализация данного принципа компанией Samsung. TEE противопоставляется окружению REE, Rich Execution Environment, а если проще — операционной системе Android. Модель защиты наиболее критичных данных построена на том, что доверять Android нельзя: система может быть взломана злоумышленником, или сам владелец устройства способен получить на ней права суперпользователя. Окружение TEE должно быть достаточно защищено даже в этих условиях. Соответственно, разные варианты TEE отвечают за наиболее критичную функциональность: управление ключами шифрования данных, подтверждение платежей, авторизация в различных службах, включая идентификацию пользователей в корпоративных сервисах.

Основой TEE в устройствах на базе процессоров ARM (то есть на подавляющем большинстве смартфонов) является технология ARM Trustzone, на аппаратном уровне обеспечивающая разделение ресурсов для TEE и REE, или, в терминах ARM, для окружений Secure World и Normal World. Софт в «защищенной среде» у каждого производителя свой, по сути это отдельная операционная система. У Samsung используется как минимум три разных варианта операционных систем TrustZone (TZOS).

Для связи между Android и различными реализациями TZOS используется элемент Android Keystore, он делает доступным API для отправки запросов и получения данных из TEE. На стороне TEE Samsung используется доверенное приложение (Trusted Application) Keymaster. Предельно упрощенная система работы Keymaster заключается в получении от Android-приложений зашифрованных секретных ключей, которые могут быть расшифрованы только в TEE. Зашифрованные ключи именуются блобами и шифруются с помощью симметричного потокового алгоритма AES-GCM.

Потоковый шифр по умолчанию требует уникального вектора инициализации — случайного набора данных, используемого в процессе шифрования. Если вектор инициализации используется повторно, данные можно расшифровать. Именно это произошло в защищенном окружении телефонов Samsung. Исследователи обнаружили, что они могут напрямую из Android-приложения задавать вектор инициализации. Из четырех протестированных смартфонов лишь самый старый, Samsung Galaxy S8, оказался не подвержен атаке, так как игнорирует передаваемый из приложения вектор инициализации. Подвержены смартфоны S9, S10, S20 и S21, но со своими нюансами. Формат тех самых «блобов» (зашифрованных ключей) периодически меняется, и их самый свежий вариант не подвержен уязвимости. Но можно сделать «даунгрейд» до более раннего формата «блоба» и эксплуатировать уже его.

Была также показана практическая атака на механизм авторизации на веб-сайтах по протоколу FIDO2. Он зависит от «безопасного окружения» в смартфоне, а модель безопасности протокола исходит из того, что секретные ключи авторизации нельзя клонировать. Используя уязвимость, приватный ключ можно похитить и авторизоваться на другом устройстве без ведома владельца, как показано на скриншотах ниже.

По мнению авторов работы, проблема заключается в непрозрачности работы защищенного программного обеспечения, разрабатываемого такими вендорами, как Samsung или Qualcomm. В научной среде экспертов по криптографии нормой является независимый аудит открытых алгоритмов шифрования для поиска и устранения уязвимостей. В данном случае исследователям пришлось заниматься реверс-инжинирингом фирменного ПО. К счастью, проблема решилась обновлением ПО. Для таких устройств, как Samsung Galaxy S10, S20 и S21, была выключена поддержка legacy-блобов. В моделях S9, J7, A6 Plus и ряде других была заблокирована возможность передачи произвольного вектора инициализации.


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