Русский
Русский
English
Статистика
Реклама

Сеть

Что такое VPN, Proxy, Tor? Разбор

19.04.2021 20:16:49 | Автор: admin
Анонимность и конфиденциальность это прекрасные понятия. Но в последнее время создается ощущение, что в сети оба понятия стили недостижимыми. Поэтому даже я, совсем не параноик периодически задумываюсь об инструментах, таких какVPN, Proxy и Tor. Вы наверняка слышали эти слова, а может быть даже регулярно пользуйтесь пользуетесь этими технологиями для сохранения анонимности, обхода блокировок, просмотра американского Netflix или банально для доступа к корпоративной сети.


Но как именно работают эти технологии и чем они отличаются? И правда ли что бесплатный сыр только в мышеловке?Сегодня поговорим о том как защитить себя и свои данные в глобально сети.

Proxy




Среди троицы VPN, Proxy, Tor самая простая технология это именно Proxy. С неё и начнём.

Proxy переводится с английского, как представитель, уполномоченный, посредник. Иными словами, прокси-сервер это сервер-посредник.

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

  • Подменив свое местоположение при помощи Proxy, вы сможете обходить региональные блокировки. Например, именно прокси-серверы позволили Telegram так легко пережить несколько лет официальной блокировки.
  • Или вы сможете получить доступ к контенту, доступному только в определенных странах. Например, к американской библиотеке Netflix, которая существенно более обширная, чем наша отечественная.
  • Или сможете сэкономить на цене авиабилетов, воспользовавшись региональными ценовыми предложениями или скидками.
  • Но может быть и обратная ситуация. Если нужно, при помощи прокси, администраторы сетей могут ограничить доступ к отдельным ресурсам.
  • Есть и менее очевидные сценарии использования. Часто прокси-серверы кэшируют данные с популярных сайтов, поэтому загружая данные через прокси-сервер вы сможете ускорить доступ к этим ресурсам.
  • Или сможете сэкономить трафик. Потому что прокси-серверы могут сжимать весь запрашиваемый контент. Именно так работают различные турбо- и экономные режимы в браузерах.

В общем, вариантов применения прокси-серверов масса. И это позитивная сторона технологии, но есть у прокси-серверов и существенные недостатки.

Типы Proxy




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

Например, для FTP-соединения (File Transfer Protocol) нужен FTP-прокси. Для HTTP и HTTPS также два отдельных HTTP- и HTTPS-прокси сервера.

Это серьёзное ограничение, поэтому еще есть отдельный тип прокси-серверов SOCKS-прокси.

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

Безопасность Proxy


Но это половина беды. Все виды прокси объединяет главная, ключевая проблема проблемы с безопасностью.

Потому как прокси-сервера дополнительно никак не шифруют трафик. То есть HTTP трафик вообще не будет никак шифроваться. А HTTPS будет зашифрован также как и при обычном интернет соединении: при помощи SSL-шифрования.А это огромная проблема. И чтобы представить масштаб трагедии, давайте вспомним аналогию с чемоданом.

Пользоваться прокси-сервером это всё равно что передавать данные посреднику в чемодане без пароля. Делать такое можно только в случае если 100% доверяете посреднику. И конечно же стоит остерегаться бесплатных прокси-серверов с сомнительной репутацией.Ведь воспользоваться непроверенным бесплатным прокси, это все равно, что доверить доставить мешок бесплатному курьеру по объявлению на автобусной остановке.

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

VPN




Но есть технология, которая обладает большинством достоинств прокси и лишена большинства недостатков это VPN или Virtual Private Network виртуальная частная сеть.

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

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

С другой стороны, это позволяет вам сохранить анонимность, так как сайт, на который вы попали думает, что запрос пришел с IP-адреса VPN-сервера, а не вашего.Но прокси-серверы, делают по сути тоже самое, так в чем же тогда разница?

Ключевое отличие VPN от Proxy это сквозное шифрование. Весь трафик проходящий через VPN-сервер защищен на всём пути от точки входа до точки выхода.А всё потому, что при включенном VPN между вашим устройством и VPN-сервером создается зашифрованный канал связи, который защищает все данные от хакерских атак.

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

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

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

Бесплатные VPN-сервисы




Получается, что VPN во всем лучше прокси? Не всегда.

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

Например, VPN-сервис Betternet, который насчитывал 38 миллионов пользователей использовал целых 14 библиотек для слежки за пользователями.

А сервис Hola продавал IP-адреса бесплатных пользователей злоумышленникам. То есть преступники могли использовать ваш IP-адрес для своих делишек.

SHADOWSOCKS




С другой стороны, не все прокси-сервисы плохие. Например, существует особый тип прокси, который называется Shadowsocks. По сути, это SOCKS-прокси на стероидах.

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

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

Например, находитесь вы в Китае и хотите проверь почту на Gmail, или свят-свят посмотреть YouTube. Благодаря Shadowsocks, вы сможете сможете сделать и это, и одновременно посещать сайты, доступные только из Китая.

В свою очередь, VPN-сервисы зашифровывают весь трафик, поэтому открыть сайты, доступные только в Китае, вы уже не сможете.

Но это не значит, что Shadowsocks лучше VPN.В отличие от VPN-сервисов, Shadowsocks не создан для защиты конфиденциальности и анонимности пользователя. При использовании Shadowsocks? пакеты данных остаются без шифрования. Это сделано специально, чтобы ваши данные были больше похожи на обычный HTTPS-трафик и не вызывали подозрений.Поэтому Shadowsocks подходит только для обхода блокировок? но никак не для безопасности или подключения к корпоративной сети.В этом плане VPN вне конкуренции. С поправкой на то, что пользоваться нужно только проверенными сервисами с хорошей репутацией.

Tor




И, наконец, самый хардкорный способ анонимизации в сети Tor. Что это и правда ли, что Tor такой безопасный?

Tor расшифровывается как The Onion Router и он использует так называемую луковую маршрутизацию. Твои данные это сердцевина луковицы, а их защита слои вокруг. Что это значит?

Для анонимизации Tor, также как прокси и VPN, пропускает трафик через промежуточные серверы. Но Только в случае с Tor их не один, а три, и называется они узлами.



А вот теперь смотрите, ваш трафик проходит через три узла:

  1. входной или сторожевой,
  2. промежуточный,
  3. выходной.

Зачем это нужно?

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

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

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

А доступ к сети осуществляется через специальный браузер Tor Browser, основанный на Firefox. Его улучшили дополнениями, запрещающими сайтам следить за тобой. Например браузер умеет отличать все скрипты на сайтах, фактически запрещая собирать любые данные пользователя, или заставляет сайты принудительно использовать шифрование.Звучит очень безопасно, но на практике, это не так.

Во-первых, Tor очень не любят правоохранительные органы, а сам факт использования Tor легко отследить.Поэтому, просто используя Tor Browser, вы уже можете привлечь лишнее внимание. Иными словами лучше использовать Tor в связке с VPN.

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

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

Более того, из-за многослойного шифрования сеть Tor работает очень медленно, половина сайтов прост отказывается корректно работать через Tor Browser.

Итоги




Что в сухом остатке? Если вы беспокоитесь за свою безопасность в сети, то самым оптимальным способом защиты будет VPN. Но не забывайте, что использовать надо только надежные VPN-сервисы с хорошей репутацией. Часто информацию о надёжности того или иного сервиса можно найти в интернете, в специальных статьях. Также помните, что хороший VPN может стоить денег, вернее его создатели могут брать за его использования какую-либо сумму. Ведь бесплатный сыр бывает только в мышеловке.
Подробнее..

Что такое SASE и зачем это нужно?

30.03.2021 22:07:52 | Автор: admin


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

В целом, можно сказать, что SASE своего рода объединение возможностей SD-WAN и служб сетевой безопасности, включая брандмауэр следующего поколения (NGFW), безопасный веб-шлюз (SWG), сетевой доступ к сети с нулевым доверием (ZTNA) и посреднические службы облачной безопасности (CASB), в единую модель обслуживания. Это если кратко, подробности под катом.

Кому и зачем это нужно?


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

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

Сам термин SASE появился только в 2019 году его автором можно считать компанию Gartner, которая употребила термин в своем отчете Будущее сетевой безопасности в облаке. Эксперты агентства в этом ответе указали, что SASE одна из важнейших тенденций рынка. В частности, об этом говорится в разделе Требования клиентов к простоте, масштабируемости, гибкости, низкой задержке и постоянной конвергенции сетевой безопасности WAN и рынков сетевой безопасности.

В отчете дается следующее определение стратегии: SASE объединяет функции сетевой безопасности (такие как SWG, CASB, FWaaS и ZTNA) с возможностями WAN (т.е. SD-WAN) для обеспечения потребности организаций в динамическом безопасном доступе к ИТ-ресурсам. Эти возможности предоставляются в основном в виде -aaS и основаны на определении учетных записей, актуального контекста и политик безопасности и регуляторного соответствия. По сути, SASE это новый пакет технологий, включающий SD-WAN, SWG, CASB, ZTNA и FWaaS в качестве основных возможностей, обладающий способностью идентифицировать конфиденциальные данные или вредоносное ПО, а также способностью дешифровать контент на линейной скорости, с непрерывным мониторингом сессий на предмет адекватного уровня риска и доверия".

Особенности SASE


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

Компоненты стратегии SASE


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



Основные компоненты:
  • Защита SD-WAN. Включает основные возможности сети WAN, например, динамический выбор пути, самовосстанавливающиеся возможности WAN, поддержка требовательных высокопроизводительных приложений и единообразное взаимодействие с пользователями.
  • Доступ с нулевым доверием (Zero Trust). Главная задача этого компонента многофакторная аутентификация пользователей. Здесь, в числе прочих технологий, используется идентификация на основе ролей.
  • NGFW (физический) или FWaAs (облачный) брандмауэр. Обеспечивает безопасность для периферии и предложений, предоставляемых через облако. Это нужно для защиты периферийных устройств и пользователей не только в сети компании, но и за ее пределами. Благодаря этому компоненту обеспечивается внутренняя сегментация, которая позволяет предотвратить угрозы гостям и/или Интернету вещей, одновременно обеспечивая согласованные политики безопасности для пользователей, которые работают вне сети.
  • Безопасный веб-шлюз. Этот компонент требуется для защиты пользователей и устройств от внешних угроз. Благодаря ему обеспечивается соблюдение нормативных требований подключения сети Интернет. Кроме того, фильтруется потенциально вредоносный интернет-трафик.
  • CASB. Этот компонент представляет собой услугу, которая дает возможность компаниям контролировать собственные SaaS-приложения, включая безопасный доступ к приложениям. CASB и DLP дают комбинированную защиту критически важных данных. Компонент выполняет сразу несколько функций обеспечения безопасности для облачных сервисов, включая выявление теневой активности, защиту конфиденциальности данных и обеспечение соответствия с требованиям регламентов по защите данных.

Какие преимущества дает SASE компании?


В целом, их немало. Всего можно выделить четыре основных плюса.

  • Гибкая и последовательная безопасность. Стратегия предоставляет широкий спектр возможностей по обеспечению безопасности, от предотвращения угроз до политик NGFW, для любой периферии, обеспечивая доступ к сети с нулевым доверием. В итоге компания всегда знает, кто и с какой целью находится в сети компании. Кроме того, все ресурсы компании, как в сети, так и вне защищены, а у сотрудников есть доступ.
  • Снижение общей стоимости инфраструктуры. SASE единая стратегия, объединяющая сразу несколько решений. Благодаря этому не нужно использовать изолированные продукты и зоопарк самых разных решений. Соответственно, снижаются капитальные и эксплуатационные расходы.
  • Снижение сложности инфраструктуры. SASE упрощает архитектуру решений за счет консолидации ключевых сетевых функций и функций обеспечения безопасности из разрозненных систем и решений в единое целое. Все они управляются из единого центра.
  • Оптимизация производительности. Благодаря доступности облачных технологий, все сотрудники компании без проблем подключаются к внутренним или внешним ресурсам, не опасаясь разного рода киберугроз.

На что нужно обратить особенное внимание?



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

А что у Zyxel?




В частности принцип Zero Trust, о котором мы писали выше, позволяющий эффективно контролировать безопасность сети дажи при большом количестве удаленных устройств реализован в Централизованной системе управления сетью Zyxel Nebula. Система предлагает единое, удобное управление распределенной сетью предприятия, а также удаленными локациями и сотрудниками. Все сетевые компоненты находятся в одной экосистеме, управляемой из облака: безопасность, коммутация, беспроводка. В базовой бесплатной версии выполняется большая часть функционала, подходящая для большинства сетей. В частности в одной из гостиниц Голландии базовая версия работает на более чем 300 устройствах.

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

Вебинар 1 для европейской части России и Беларуси

Вебинар 2 для Украины

Вебинар 3 для Казахстана, Сибири и Дальнего Востока

Вебинар 4 Новая модель лицензирования и сопутствующий функционал Nebula

Добро пожаловать!
Подробнее..

Китай начал строить первый коммерческий дата-центр на дне моря

29.05.2021 02:13:41 | Автор: admin

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

А вот Китай, похоже, настроен очень серьезно. Представители администрации провинции Хайнань заявили о начале работ по созданию подводного центра обработки данных. Успешное тестирование в полевых условиях завершено. Теперь началось строительство полноценного ЦОД силами компании Highlander и нескольких других партнеров.

Что это за проект?


Согласно плану, на дне моря будет установлено около 100 специализированных герметичных резервуаров. Внутри них будет находиться серверное оборудование. О старте проекта было объявлено на крупном мероприятии с участием представителей правительства и таких компаний, как Highlander, Sinnet, Hainan Telecom и Lenovo.

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

Главным инициатором проекта является компания Highlander. Ее руководство считает подводные дата-центры весьма перспективным направлением работы в телекоммуникациях. Компания сообщала, что вдохновилась примером Microsoft, которая тестировала подводный ЦОД в течение двух лет, заявив о вполне удовлетворительных результатах. Но вот Microsoft пока что ничего не говорила о коммерциализации своего проекта, а китайская компания занимается этим прямо сейчас.


21 мая Highlander, предствители администрации и инвестиционная компания порта Хайнань заявили о пятилетнем плане строительства подводного центра. Резервуары располагаются на дне моря вокруг центрального коммуникационного модуля, который является как бы ядром всей системы. Главное достоинство такого дата-центра экономия электроэнергии благодаря отсутствию необходимости разворачивать сложную систему охлаждения.

Кстати, ЦОД размещается рядом с АЭС, так что проблемы в снабжении энергией нет станция будет поставлять столько электричества, сколько понадобится.

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

Все идет по плану?


Вроде бы да. Проект будет реализован в три этапа. В 2021 году установят всего 5 резервуаров, которые начнут работу сразу же после установки. Еще 45 таких же резервуаров компания подключит с 2022 по 2023 год. И если все пройдет хорошо, то в строй введут еще 50 единиц уже с 2024 по 2025 год. На этом этапе к проекту подключат заинтересованные компании, которые станут клиентами Highlander. Еще одно достоинство дата-центра такого типа возможность его масштабирования. По словам представителей компании, масштабирование может быть сколь угодно большим, развернуть полноценный дата-центр при условии готовности модулей можно очень быстро.

Обслуживать ЦОД будет торговый порт Хайнаня, которому постоянно требуются новые и новые вычислительные мощности. Почему именно порт? Дело в том, что правительство провинции планирует превратить весь остров Хайнань в крупнейшую экономическую зону Китая с большим количеством налоговых льгот, привлечением туристов и поддержкой технологического сектора.


У такого рода объектов, по мнению экспертов, есть и недостатки. Даже если они будут работать полностью в автономном режиме, не требуя регулярного обслуживания, а система охлаждения позволит снизить затраты энергии, то начальные инвестиции могут испортить привлекательность такого ЦОД. Денег на строительство подводного центра обработки данных понадобится много. Представитель аналитического агентства CCID Consulting заявил, что сомневается в прибыльности дата-центров, расположенных под водой, по его мнению, коммерческая ценность подобных систем стремится к нулю.

С другой стороны, климат Хайнаня тропический. Здесь достаточно высокая среднегодовая температура. В ходе преобразования зоны в экономически свободную здесь понадобятся значительные вычислительные мощности, что приведет к строительству ЦОД. На их охлаждение понадобится огромное количество энергии, так что, возможно, выгоднее все же пустить дата-центр на дно, если так можно выразиться.

Что дальше?


Компания Highlander заявила, что в случае успеха первого проекта она развернет целую серию проектов подводных ЦОД, включая торговый порт, о котором уже говорилось выше, один из районов Большого залива, дельту реки Янцзы и экономический район Бохай.


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

Главное это вода, которая в случае плавучих дата-центров частично или полностью бесплатна, причем забирать ее можно из любой точки.
Еще одно достоинство мобильность. Плавучий ЦОД от Nautilus можно развернуть практически в любой точке мира, где есть необходимая инфраструктура. Таких мест не так уж и мало.
Экономия. Для плавучего дата-центра не нужна земля, которая во многих регионах очень дорогая. Кроме того, благодаря особенностям системы охлаждения расходы на отвод тепла снижаются минимум на треть.

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

Подробнее..

Эмулятор ИБП с протоколами Megatec и Voltronic

11.05.2021 08:07:02 | Автор: admin

Ряд наших устройств имеет встроенный порт RS-232 для считывания данных с источников бесперебойного питания (ИБП) по двум наиболее распространённым протоколам обмена Megatec и Voltronic. Для облегчения тестирования устройств мы разработали небольшую программу-эмулятор. Именно о ней дальше и пойдёт речь.

Протоколы Megatec и Voltronic текстовые и довольно простые. Обмен данными ведётся на низкой скорости 2400 бит/сек, 8 бит данных, без контроля чётности по принципу запрос-ответ. Запросы представляют собой текстовые строки длиной от одного до трёх символов, оканчивающихся байтом перевода строки (код 0x0D). Ответы приходят также в текстовом виде с завершающим символом 0x0D. Значения в ответах разделяются пробелами. Числа могут передаваться либо с незначащими нулями в начале, либо с дополнительными пробелами.

В зависимости от конкретного ИБП таких команд может быть разное количество, но основную информацию можно получить при помощи четырёх из них. Рассмотрим их подробнее.

Q1 запрос текущего состояния
Ответ ИБП:
(MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T b7b6b5b4b3b2b1b0
( начальный символ.
MMM.M входное напряжение, В.
NNN.N напряжение, при котором последний раз был осуществлён переход на работу от батареи, В.
PPP.P выходное напряжение, В.
QQQ потребляемая мощность, %.
RR.R частота сети, Гц.
SS.S напряжение на батарее, В. Оно может передаваться в двух форматах: SS.S для линейно-интерактивных ИБП или S.SS для онлайн-ИБП (указывается напряжение на одном элементе).
TT.T температура ИБП, C.
b7...b0 статусные биты, которые могут принимать значение 0 или 1.
b7 1 : работа от АКБ, 0 : работа от сети.
b6 1 : низкий уровень заряда АКБ, 0 : АКБ в норме.
b5 1 : байпас включён, 0 : байпас выключен (только для онлайн-ИБП).
b4 1 : авария ИБП, 0 : ИБП в норме.
b3 1 : линейно-интерактивный ИБП, 0 : онлайн-ИБП.
b2 1 : запущен тест ИБП.
b1 1 : ИБП выключен, 0 : ИБП включён.
b0 1 : звуковой сигнал включён, 0 : выключен.

I запрос информации об ИБП
Ответ ИБП:
#CompanyName Model Version
# начальный символ.
CompanyName производитель ИБП.
Model название модели.
Version версия ИБП.

F запрос информации о номинальных параметрах ИБП
Ответ ИБП:
#MMM.M QQQ SS.SS RR.R
# начальный символ.
MMM.M номинальное выходное напряжение, В.
QQQ номинальный выходной ток, А.
SS.SS номинальное напряжение АКБ, В (может быть в форматах SS.SS или SSS.S).
RR.R номинальная частота выходного напряжения, Гц.

QBV запрос информации об АКБ
Ответ ИБП:
(RRR.R NN MM CCC TTT
( начальный символ.
RRR.R номинальное напряжение АКБ, В.
NN количество батарей в АКБ, шт.
MM количество параллельных групп батарей, шт.
CCC ёмкость АКБ, %.
TTT оставшееся время работы от АКБ, мин.

Помимо команд, которые считывают какие-либо параметры ИБП, есть ещё управляющие команды. Часто используются такие:
T запуск теста АКБ на 10 сек.
TL запуск теста АКБ до полного разряда.
T<n> запуск теста АКБ на заданное количество минут.
CT остановка теста АКБ.
Q включение/отключение звукового сигнала ИБП.

На первый взгляд вышеописанные команды очень простые, но дьявол, как обычно, кроется в мелочах. Например, некоторые ИБП вообще не выдают ответы на команды I и QBV. Примером может служить ряд моделей от Ippon.

Также замечено, что различные ИБП выполняют команду Q (управление звуковым сигналом) за совершенно разное время. То есть от момента выдачи команды Q и до момента смены бита b0 в ответе на команду Q1 может пройти до 30 сек!!! А так как включение и выключение осуществляется одной командой, то при автоматизированном управлении может начаться колебательный процесс. Например, контроллеру через Web-интерфейс задаётся выключенное состояние звукового сигнала. Он анализирует текущее состояние ИБП (по флагу b0), и если оно отличается от нужного, то подаёт команду Q. При следующем запросе Q1 контроллер опять проверяет флаг b0 и видит, что он не поменялся. В результате он опять подаёт команду Q. Но ИБП всё это время на самом деле что-то там у себя внутри обдумывал, поэтому не сразу среагировал на первую Q, а тут уже пришла и вторая. В результате звуковой сигнал может остаться включённым. И, более того, в некоторых ИБП при смене статуса звукового сигнала осуществляется короткий бип. А из-за такого колебательного процесса эти бипы могут издаваться много раз, пока наконец контроллер и ИБП не синхронизируются.

Мы решили эту проблему просто смену состояния звукового сигнала проводим только раз в минуту. За это время у ИБП внутри уже всё устаканится.

Ещё один интересный момент заключается в расчёте оставшейся ёмкости АКБ. Считается она по упрощённой формуле:

BatCap = \frac{U - U_{min}}{U_{max} - U_{min}}\times100\%

Здесь:
U текущее напряжение АКБ.
Umin минимально допустимое напряжение на АКБ (обычно около 10В).
Umax напряжение заряженной АКБ (обычно 13,8...14,2В).

Этого обычно достаточно для оценки оставшегося заряда.

Протокол Voltronic на множестве указанных выше команд отличается только одной из них вместо кода Q1 используется QS. При этом форматы ответов совпадают. В наших устройствах реализовано автоматическое определение протокола обмена как раз на основе данного отличия. Контроллер при включении пробует посылать по очереди команды Q1 и QS. На какую приходит ответ, тот протокол дальше и используется. Если в течение определённого тайм-аута на команду перестают приходить ответы (был подключён другой ИБП на горячую), то определение протокола автоматически запускается заново.

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

Она представляет из себя экран с настройками и выбором COM-порта, через который будет осуществляться обмен. Поддерживаются все указанные выше команды, в том числе и для запуска тестов:

Работа с программой нее вызовет затруднений. Менять любые параметры можно прямо в процессе работы, и тут же видеть результат:

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

Саму программу эмулятора можно скачать здесь.

Подробнее..

Полезные материалы для разработчика

19.03.2021 12:22:16 | Автор: admin

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

Выпускнику и преподавателю Computer Science Center, Равилю Галееву, пришла идея собрать такие инструменты и технологии в один курс и познакомить студентов с ними. За пример такого курса были взяты The Missing Semester of Your CS Education от MIT, Software Carpentry и cs50.

В этом посте мы собрали видеолекции курса Практический минимум и материалы к занятиям. Благодарим Равиля за подборку!

Содержание

Введение в Linux

Командная строка Linux

Система контроля версий git

Языки разметки и XML

Регулярные выражения

Взаимодействие с сетью

Протокол HTTP

Контейнеризация

Архитектура приложений

Тестирование приложений

Опасность в приложениях

Билд-системы

Кодировки, даты, локали

Дебаг

Набор в Computer Science Center 2021

Введение в Linux

  • Буквально пара слов о том, что такое ядро

  • Набор исторических фактов (от Unix к Linux)

  • Файловая система

  • Пользователи

  • Файлы

  • Процессы

  • Unix way

Слайды

Статьи

Wikipedia History of Unix

Книги

Видео

Курсы

Командная строка Linux

  • bash как REPL

  • Unix way

  • Шебанг

  • make

Слайды

Статьи

Книги

Ian Miell Learn Bash the Hard Way

Видео

Слайды/Презентации

Bash-скрипты из реального мира

Система контроля версий git

  • git

    • commit

    • branch

    • merge

  • git flow

  • github

Слайды

Статьи

Книги

  • Scott Chacon and Ben Straub Pro Git

Видео

Потренироваться

Языки разметки и XML

  • groff

  • LaTex

  • XML, JSON, YAML

  • Markdown, AsciiDoc

  • GraphViz, PlantUML

Слайды

Статьи

Книги

К. В. Воронцов LATEX в примерах

Видео

Слайды и другие материалы

Markdown cheatsheets

Разное

Регулярные выражения

  • Регулярки

  • grep

  • sed

  • awk

Слайды

Статьи

Видео

Слайды и другие материалы

Взаимодействие с сетью

  • Разбираемся как работает посылка пакетов

  • Рассматриваем простейшие утилиты работы с сетью

  • Знакомимся с DNS, CDN, VPN и другими словами на три буквы

  • Пишем сервер на сокетах

Слайды

Материалы

Протокол HTTP

  • HTTP

  • REST

Слайды

Статьи

Видео

Разное

Контейнеризация

  • chroot

  • Docker

  • Docker compose

Слайды

Статьи

Видео

Курсы

Разное

Архитектура приложений

  • ООП

  • Паттерны

  • Многослойная архитектура

Слайды

Статьи

Книги

Курсы

Видео

Тестирование приложений

  • Тестирование

  • Логгирование

Слайды 1

Слайды 2

Статьи

Видео

Опасность в приложениях

  • Хеширование, контрольные суммы

  • Авторизация vs Аутентификация; JWT

  • Обмен ключами Диффи-Хеллман

  • RSA

  • TLS

  • Двухфакторная аутентификация

Слайды

Статьи

Видео

Книги

Билд-системы

  • от make к TravisCI

  • dockerhub

Слайды

Статьи

Видео

Разное

Anatomy of a Continuous Integration and Delivery (CICD) Pipeline

Кодировки, даты, локали

Разбираемся, почему /dev/random печатает краказябры

Слайды

Статьи

Видео

Дебаг

  • Исключения

  • Дебаг

Слайды

Статьи

Книги

Видео

Курсы

Кирилл Кринкин Основы программирования для Linux

Разное


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

Набор в Computer Science Center 2021

Помимо лекций и материалов студентам CS центра на курсе доступны домашние задания. Если вы хотите проходить ещё больше курсов по разным направлениям, приходите поступать.

CS центр это вечерние курсы по математике и программированию. Занятия проходят в Санкт-Петербурге и в Новосибирске. Жители других городов могут поступить на обучение в удалённом формате.

Чтобы поступить:

заполните анкету на сайте до 10 апреля,

решите задания онлайн-теста до 11 апреля,

участвуйте в онлайн-экзамене в конце апреля-начале мая,

пройдите собеседование в мае-июне.

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

Задать вопросы про набор можно в телеграм канале или по почте info@compscicenter.ru.

Подробнее..

Перевод Сеть контейнеров это не сложно

26.05.2021 22:23:37 | Автор: admin

Работа с контейнерами многим кажется волшебством, пришло время разобраться как работает сеть контейнеров. Мы покажем на примерах, что это совсем не сложно. Помните, что контейнеры - всего лишь изолированные процессы Linux.

В этой статье мы ответим на следующие вопросы:

  • Как виртуализировать сетевые ресурсы, чтобы контейнеры думали, что у каждого из них есть выделенный сетевой стек?

  • Как превратить контейнеры в дружелюбных соседей, не дать им мешать друг другу и научить хорошо общаться?

  • Как настроить сетевой доступ из контейнера во внешний мир (например, в Интернет)?

  • Как получить доступ к контейнерам, работающим на сервере, из внешнего мира (публикация портов)?

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

  • Network namespaces

  • Virtual Ethernet devices (veth)

  • Virtual network switches (bridge)

  • IP маршрутизация и преобразование сетевых адресов (NAT)

Нам потребуется немного сетевой магии и никакого кода ...

С чего начать?

Все примеры в статье были сделаны на виртуальной машине CentOS 8. Но вы можете выбрать тот дистрибутив, который вам нравится.

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

$ vagrant init centos/8$ vagrant up$ vagrant ssh[vagrant@localhost ~]$ uname -aLinux localhost.localdomain 4.18.0-147.3.1.el8_1.x86_64

Мы не будем использовать какое-либо популярное решение для контейнеризации (например, docker или podman). Вместо этого мы сосредоточимся на основных концепциях и воспользуемся минимальным набором инструментов для достижения наших учебных целей.

Изоляция контейнеров с помощью Network namespaces

Что составляет сетевой стек Linux? Ну, очевидно, набор сетевых устройств. Что еще? Набор правил маршрутизации. И не забываем про настройку netfilter, создадим необходимые правила iptables.

Напишем небольшой скрипт inspect-net-stack.sh:

#!/usr/bin/env bashecho "> Network devices"ip linkecho -e "\n> Route table"ip routeecho -e "\n> Iptables rules"iptables --list-rules

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

$ sudo iptables -N ROOT_NS

Запускаем скрипт:

$ sudo ./inspect-net-stack.sh> Network devices1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000    link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff> Route tabledefault via 10.0.2.2 dev eth0 proto dhcp metric 10010.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100> Iptables rules-P INPUT ACCEPT-P FORWARD ACCEPT-P OUTPUT ACCEPT-N ROOT_NS

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

Мы уже упоминали об одном из Linux namespaces, используемых для изоляции контейнеров, которое называет сетевое пространство имён (Network namespace). Если заглянуть в man ip-netns, то мы прочтём, что Network namespace логически является копией сетевого стека со своими собственными маршрутами, правилами брандмауэра и сетевыми устройствами. Мы не будем затрагивать другие Linux namespaces в этой статье и ограничимся только областью видимости сетевого стека.

Для создания Network namespace нам достаточно утилиты ip, которая входим в популярный пакет iproute2. Создадим новое сетевое пространство имён:

$ sudo ip netns add netns0$ ip netnsnetns0

Новое сетевое пространство имён создано, но как начать его использовать? Воспользуемся командой Linux под названием nsenter. Она осуществляет вход в одно или несколько указанных пространств имен, а затем выполняет в нём указанную программу:

$ sudo nsenter --net=/var/run/netns/netns0 bash# The newly created bash process lives in netns0$ sudo ./inspect-net-stack.sh> Network devices1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00> Route table> Iptables rules-P INPUT ACCEPT-P FORWARD ACCEPT-P OUTPUT ACCEPT

Приведённый выше пример показывает, что процесс bash, работающий внутри пространства имён netns0, видит совершенно другой сетевой стек. Отсутствуют правила маршрутизации, и правила iptables, есть только один loopback interface. Все идет по плану...

Подключаем контейнер к хосту через virtual Ethernet devices (veth)

Выделенный сетевой стек будет бесполезен, если к нему отсутствует доступ. К счастью, Linux предоставляет подходящее средство для этого - virtual Ethernet devices (veth)! Согласно man veth, veth-device - это виртуальные устройства Ethernet. Они работают как туннели между сетевыми пространствами имён для создания моста к физическому сетевому устройству в другом пространстве имён, а также могут использоваться как автономные сетевые устройства.

Виртуальные Ethernet устройства всегда работают парами. Создадим их прямо сейчас:

$ sudo ip link add veth0 type veth peer name ceth0

С помощью этой единственной команды мы только что создали пару взаимосвязанных виртуальных Ethernet устройств. Имена veth0 и ceth0 были выбраны произвольно:

$ ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000    link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff5: ceth0@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000    link/ether 66:2d:24:e3:49:3f brd ff:ff:ff:ff:ff:ff6: veth0@ceth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000    link/ether 96:e8:de:1d:22:e0 brd ff:ff:ff:ff:ff:ff

И veth0, и ceth0 после создания находятся в сетевом стеке хоста (также называемом Root Network namespace). Чтобы связать корневое пространство имён с пространством имён netns0, нам нужно сохранить одно из устройств в корневом пространстве имён и переместить другое в netns0:

$ sudo ip link set ceth0 netns netns0# List all the devices to make sure one of them disappeared from the root stack$ ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:002: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000    link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff6: veth0@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000    link/ether 96:e8:de:1d:22:e0 brd ff:ff:ff:ff:ff:ff link-netns netns0

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

$ sudo ip link set veth0 up$ sudo ip addr add 172.18.0.11/16 dev veth0

Продолжим сnetns0:

$ sudo nsenter --net=/var/run/netns/netns0$ ip link set lo up  # whoops$ ip link set ceth0 up$ ip addr add 172.18.0.10/16 dev ceth0$ ip link1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:005: ceth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000    link/ether 66:2d:24:e3:49:3f brd ff:ff:ff:ff:ff:ff link-netnsid 0

Проверяем подключение:

# From netns0, ping root's veth0$ ping -c 2 172.18.0.11PING 172.18.0.11 (172.18.0.11) 56(84) bytes of data.64 bytes from 172.18.0.11: icmp_seq=1 ttl=64 time=0.038 ms64 bytes from 172.18.0.11: icmp_seq=2 ttl=64 time=0.040 ms--- 172.18.0.11 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 58msrtt min/avg/max/mdev = 0.038/0.039/0.040/0.001 ms# Leave netns0$ exit# From root namespace, ping ceth0$ ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.64 bytes from 172.18.0.10: icmp_seq=1 ttl=64 time=0.073 ms64 bytes from 172.18.0.10: icmp_seq=2 ttl=64 time=0.046 ms--- 172.18.0.10 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 3msrtt min/avg/max/mdev = 0.046/0.059/0.073/0.015 ms

Обратите внимание, если мы попытаемся проверить доступность любых других адресов из пространства имен netns0, у нас ничего не получится:

# Inside root namespace$ ip addr show dev eth02: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000    link/ether 52:54:00:e3:27:77 brd ff:ff:ff:ff:ff:ff    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute eth0       valid_lft 84057sec preferred_lft 84057sec    inet6 fe80::5054:ff:fee3:2777/64 scope link       valid_lft forever preferred_lft forever# Remember this 10.0.2.15$ sudo nsenter --net=/var/run/netns/netns0# Try host's eth0$ ping 10.0.2.15connect: Network is unreachable# Try something from the Internet$ ping 8.8.8.8connect: Network is unreachable

Для таких пакетов в таблице маршрутизации netns0 просто нет маршрута. В настоящий момент существует единственный маршрут до сети 172.18.0.0/16:

# From netns0 namespace:$ ip route172.18.0.0/16 dev ceth0 proto kernel scope link src 172.18.0.10

В Linux есть несколько способов заполнения таблицы маршрутизации. Один из них - извлечение маршрутов из подключенных напрямую сетевых интерфейсов. Помните, что таблица маршрутизации в netns0 была пустой сразу после создания пространства имен. Но затем мы добавили туда устройство ceth0 и присвоили ему IP-адрес 172.18.0.10/16. Поскольку мы использовали не простой IP-адрес, а комбинацию адреса и сетевой маски, сетевому стеку удалось извлечь из него информацию о маршрутизации. Каждый пакет, предназначенный для сети 172.18.0.0/16, будет отправлен через устройство ceth0. Но все остальные пакеты будут отброшены. Точно так же есть новый маршрут в корневом пространстве имен:

# From root namespace:$ ip route# ... omitted lines ...172.18.0.0/16 dev veth0 proto kernel scope link src 172.18.0.11

На этом этапе мы ответили на первый вопрос. Теперь мы знаем, как изолировать, виртуализировать и подключать сетевые стеки Linux.

Объединение контейнеров с помощью virtual network switch (bridge)

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

# From root namespace$ sudo ip netns add netns1$ sudo ip link add veth1 type veth peer name ceth1$ sudo ip link set ceth1 netns netns1$ sudo ip link set veth1 up$ sudo ip addr add 172.18.0.21/16 dev veth1$ sudo nsenter --net=/var/run/netns/netns1$ ip link set lo up$ ip link set ceth1 up$ ip addr add 172.18.0.20/16 dev ceth1

Проверим доступность:

# From netns1 we cannot reach the root namespace!$ ping -c 2 172.18.0.21PING 172.18.0.21 (172.18.0.21) 56(84) bytes of data.From 172.18.0.20 icmp_seq=1 Destination Host UnreachableFrom 172.18.0.20 icmp_seq=2 Destination Host Unreachable--- 172.18.0.21 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 55mspipe 2# But there is a route!$ ip route172.18.0.0/16 dev ceth1 proto kernel scope link src 172.18.0.20# Leaving netns1$ exit# From root namespace we cannot reach the netns1$ ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.From 172.18.0.11 icmp_seq=1 Destination Host UnreachableFrom 172.18.0.11 icmp_seq=2 Destination Host Unreachable--- 172.18.0.20 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 23mspipe 2# From netns0 we CAN reach veth1$ sudo nsenter --net=/var/run/netns/netns0$ ping -c 2 172.18.0.21PING 172.18.0.21 (172.18.0.21) 56(84) bytes of data.64 bytes from 172.18.0.21: icmp_seq=1 ttl=64 time=0.037 ms64 bytes from 172.18.0.21: icmp_seq=2 ttl=64 time=0.046 ms--- 172.18.0.21 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 33msrtt min/avg/max/mdev = 0.037/0.041/0.046/0.007 ms# But we still cannot reach netns1$ ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.From 172.18.0.10 icmp_seq=1 Destination Host UnreachableFrom 172.18.0.10 icmp_seq=2 Destination Host Unreachable--- 172.18.0.20 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 63mspipe 2

Что-то пошло не так... По какой-то причине мы не можем подключиться из netns1 к root namespace. А из root namespace мы не можем подключиться к netns1. Однако, поскольку оба контейнера находятся в одной IP-сети 172.18.0.0/16, есть доступ к veth1 хоста из контейнера netns0. Интересно...

Возможно, мы столкнулись с конфликтом маршрутов. Давайте проверим таблицу маршрутизации в root namespace:

$ ip route# ... omitted lines ...172.18.0.0/16 dev veth0 proto kernel scope link src 172.18.0.11172.18.0.0/16 dev veth1 proto kernel scope link src 172.18.0.21

После добавления второй пары veth в таблице маршрутизации root namespace появился новый маршрут 172.18.0.0/16 dev veth1 proto kernel scope link src 172.18.0.21, но маршрут до этой подсети уже существовал! Когда второй контейнер пытается проверить связь с устройством veth1, используется первый маршрут и мы видим ошибку подключения. Если бы мы удалили первый маршрут sudo ip route delete 172.18.0.0/16 dev veth0 proto kernel scope link src 172.18.0.11 и перепроверили подключение, то увидели бы обратную ситуацию, то есть подключение netns1 будет восстановлено, но netns0 останется в подвешенном состоянии.

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

Рассмотрим Linux Bridge - еще один виртуализированный сетевой объект! Linux Bridge ведёт себя как коммутатор. Он пересылает пакеты между подключенными к нему интерфейсами. А поскольку это коммутатор, то он работает на уровне L2 (то есть Ethernet).

Чтобы предыдущие этапы нашего эксперимента в дальнейшем не вносили путаницы, удалим существующие сетевые пространства имён:

$ sudo ip netns delete netns0$ sudo ip netns delete netns1# But if you still have some leftovers...$ sudo ip link delete veth0$ sudo ip link delete ceth0$ sudo ip link delete veth1$ sudo ip link delete ceth1

Заново создаём два контейнера. Обратите внимание, мы не назначаем IP-адреса новым устройствам veth0 и veth1:

$ sudo ip netns add netns0$ sudo ip link add veth0 type veth peer name ceth0$ sudo ip link set veth0 up$ sudo ip link set ceth0 netns netns0$ sudo nsenter --net=/var/run/netns/netns0$ ip link set lo up$ ip link set ceth0 up$ ip addr add 172.18.0.10/16 dev ceth0$ exit$ sudo ip netns add netns1$ sudo ip link add veth1 type veth peer name ceth1$ sudo ip link set veth1 up$ sudo ip link set ceth1 netns netns1$ sudo nsenter --net=/var/run/netns/netns1$ ip link set lo up$ ip link set ceth1 up$ ip addr add 172.18.0.20/16 dev ceth1$ exit

Убедимся, что на хосте нет новых маршрутов:

$ ip routedefault via 10.0.2.2 dev eth0 proto dhcp metric 10010.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100

И, наконец, создадим bridge интерфейс:

$ sudo ip link add br0 type bridge$ sudo ip link set br0 up

Теперь подключим к нему veth0 и veth1:

$ sudo ip link set veth0 master br0$ sudo ip link set veth1 master br0

... и проверим возможность подключения между контейнерами:

$ sudo nsenter --net=/var/run/netns/netns0$ ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.64 bytes from 172.18.0.20: icmp_seq=1 ttl=64 time=0.259 ms64 bytes from 172.18.0.20: icmp_seq=2 ttl=64 time=0.051 ms--- 172.18.0.20 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 2msrtt min/avg/max/mdev = 0.051/0.155/0.259/0.104 ms
$ sudo nsenter --net=/var/run/netns/netns1$ ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.64 bytes from 172.18.0.10: icmp_seq=1 ttl=64 time=0.037 ms64 bytes from 172.18.0.10: icmp_seq=2 ttl=64 time=0.089 ms--- 172.18.0.10 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 36msrtt min/avg/max/mdev = 0.037/0.063/0.089/0.026 ms

Прекрасно! Все отлично работает. При этом мы даже не настраивали интерфейсы veth0 и veth1. Мы назначили только два IP-адреса интерфейсам ceth0 и ceth1. Но поскольку они оба находятся в одном сегменте Ethernet (подключены к виртуальному коммутатору), существует возможность подключения на уровне L2:

$ sudo nsenter --net=/var/run/netns/netns0$ ip neigh172.18.0.20 dev ceth0 lladdr 6e:9c:ae:02:60:de STALE$ exit$ sudo nsenter --net=/var/run/netns/netns1$ ip neigh172.18.0.10 dev ceth1 lladdr 66:f3:8c:75:09:29 STALE$ exit

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

Настраиваем сетевой доступ из контейнера во внешний мир (IP routing and masquerading)

Сейчас контейнеры могут подключаться друг к другу. Но будут ли удачны подключения к хосту, то есть к корневому пространству имён?

$ sudo nsenter --net=/var/run/netns/netns0$ ping 10.0.2.15  # eth0 addressconnect: Network is unreachable

Интерфейс eth0 не доступен. Всё очевидно, в netns0 отсутствует маршрут для этого подключения:

$ ip route172.18.0.0/16 dev ceth0 proto kernel scope link src 172.18.0.10

Корневое пространство имён также не может взаимодействовать с контейнерами:

# Use exit to leave netns0 first:$ ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.From 213.51.1.123 icmp_seq=1 Destination Net UnreachableFrom 213.51.1.123 icmp_seq=2 Destination Net Unreachable--- 172.18.0.10 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 3ms$ ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.From 213.51.1.123 icmp_seq=1 Destination Net UnreachableFrom 213.51.1.123 icmp_seq=2 Destination Net Unreachable--- 172.18.0.20 ping statistics ---2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 3ms

Чтобы установить связь между корневым пространством имён и пространством имён контейнера, нам нужно назначить IP-адрес сетевому интерфейсу моста:

$ sudo ip addr add 172.18.0.1/16 dev br0

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

$ ip route# ... omitted lines ...172.18.0.0/16 dev br0 proto kernel scope link src 172.18.0.1$ ping -c 2 172.18.0.10PING 172.18.0.10 (172.18.0.10) 56(84) bytes of data.64 bytes from 172.18.0.10: icmp_seq=1 ttl=64 time=0.036 ms64 bytes from 172.18.0.10: icmp_seq=2 ttl=64 time=0.049 ms--- 172.18.0.10 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 11msrtt min/avg/max/mdev = 0.036/0.042/0.049/0.009 ms$ ping -c 2 172.18.0.20PING 172.18.0.20 (172.18.0.20) 56(84) bytes of data.64 bytes from 172.18.0.20: icmp_seq=1 ttl=64 time=0.059 ms64 bytes from 172.18.0.20: icmp_seq=2 ttl=64 time=0.056 ms--- 172.18.0.20 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 4msrtt min/avg/max/mdev = 0.056/0.057/0.059/0.007 ms

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

$ sudo nsenter --net=/var/run/netns/netns0$ ip route add default via 172.18.0.1$ ping -c 2 10.0.2.15PING 10.0.2.15 (10.0.2.15) 56(84) bytes of data.64 bytes from 10.0.2.15: icmp_seq=1 ttl=64 time=0.036 ms64 bytes from 10.0.2.15: icmp_seq=2 ttl=64 time=0.053 ms--- 10.0.2.15 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 14msrtt min/avg/max/mdev = 0.036/0.044/0.053/0.010 ms# And repeat the change for netns1

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

Отлично, нам удалось добиться сетевой связности контейнеров с корневым пространством имён. Теперь давайте попробуем подключить их к внешнему миру. По умолчанию переадресация пакетов (ip packet forwarding), то есть функциональность маршрутизатора в Linux отключена. Нам нужно её включить

# In the root namespacesudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

Теперь самое интересное - проверка подключения:

$ sudo nsenter --net=/var/run/netns/netns0$ ping 8.8.8.8# hangs indefinitely long for me...

Всё равно не работает. Мы что-то упустили? Если бы контейнер отправлял пакеты во внешний мир, сервер-получатель не смог бы отправлять пакеты обратно в контейнер, потому что IP-адрес контейнера является частным и правила маршрутизации для этого конкретного IP-адреса известны только в локальной сети. К тому же многие контейнеры в мире имеют один и тот же частный IP-адрес 172.18.0.10. Решение этой проблемы называется преобразованием сетевых адресов (NAT). Принцип работы, следующий - перед отправкой во внешнюю сеть пакеты, отправленные контейнерами, заменяют свои исходные IP-адреса (source IP addesses) на адрес внешнего интерфейса хоста. Хост также будет отслеживать все существующие сопоставления (mapping) и по прибытии будет восстанавливать IP-адреса перед пересылкой пакетов обратно в контейнеры. Звучит сложно, но у меня для вас хорошие новости! Нам нужна всего одна команда, чтобы добиться требуемого результата:

$ sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/16 ! -o br0 -j MASQUERADE

Команда довольно проста. Мы добавляем новое правило в таблицу nat цепочки POSTROUTING с просьбой выполнить MASQUERADE всех исходящих пакетов из сети 172.18.0.0/16, но не через интерфейс моста.

Проверьте подключение:

$ sudo nsenter --net=/var/run/netns/netns0$ ping -c 2 8.8.8.8PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=43.2 ms64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=36.8 ms--- 8.8.8.8 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 2msrtt min/avg/max/mdev = 36.815/40.008/43.202/3.199 ms
$ sudo nsenter --net=/var/run/netns/netns0$ ping -c 2 8.8.8.8PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=43.2 ms64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=36.8 ms--- 8.8.8.8 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 2msrtt min/avg/max/mdev = 36.815/40.008/43.202/3.199 ms

Помните, что политика iptables по умолчанию - ACCEPT для каждой цепочки, она может быть довольно опасной в реальных условиях:

sudo iptables -S-P INPUT ACCEPT-P FORWARD ACCEPT-P OUTPUT ACCEPT

В качестве хорошего примера Docker вместо этого ограничивает все по умолчанию, а затем разрешает только для известных маршрутов:

$ sudo iptables -t filter --list-rules-P INPUT ACCEPT-P FORWARD DROP-P OUTPUT ACCEPT-N DOCKER-N DOCKER-ISOLATION-STAGE-1-N DOCKER-ISOLATION-STAGE-2-N DOCKER-USER-A FORWARD -j DOCKER-USER-A FORWARD -j DOCKER-ISOLATION-STAGE-1-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT-A FORWARD -o docker0 -j DOCKER-A FORWARD -i docker0 ! -o docker0 -j ACCEPT-A FORWARD -i docker0 -o docker0 -j ACCEPT-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 5000 -j ACCEPT-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2-A DOCKER-ISOLATION-STAGE-1 -j RETURN-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP-A DOCKER-ISOLATION-STAGE-2 -j RETURN-A DOCKER-USER -j RETURN$ sudo iptables -t nat --list-rules-P PREROUTING ACCEPT-P INPUT ACCEPT-P POSTROUTING ACCEPT-P OUTPUT ACCEPT-N DOCKER-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 5000 -j MASQUERADE-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER-A DOCKER -i docker0 -j RETURN-A DOCKER ! -i docker0 -p tcp -m tcp --dport 5005 -j DNAT --to-destination 172.17.0.2:5000$ sudo iptables -t mangle --list-rules-P PREROUTING ACCEPT-P INPUT ACCEPT-P FORWARD ACCEPT-P OUTPUT ACCEPT-P POSTROUTING ACCEPT$ sudo iptables -t raw --list-rules-P PREROUTING ACCEPT-P OUTPUT ACCEPT

Настроим сетевой доступ из внешнего мира в контейнеры (port publishing)

Публикация портов контейнеров для некоторых (или всех) интерфейсов хоста - популярная практика. Но что на самом деле означает публикация порта?

Представьте, что у нас есть сервис, работающий внутри контейнера:

$ sudo nsenter --net=/var/run/netns/netns0$ python3 -m http.server --bind 172.18.0.10 5000

Если мы попытаемся отправить HTTP-запрос этому сервису с хоста, все будет работать (ну, есть связь между корневым пространством имён и всеми интерфейсами контейнера, почему бы и нет?):

# From root namespace$ curl 172.18.0.10:5000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"># ... omitted lines ...

Однако, если бы мы получили доступ к этому серверу из внешнего мира, какой IP-адрес мы бы использовали? Единственный IP-адрес, который мы можем знать, - это адрес внешнего интерфейса хоста eth0:

$ curl 10.0.2.15:5000curl: (7) Failed to connect to 10.0.2.15 port 5000: Connection refused

Таким образом, нам нужно найти способ перенаправить все пакеты, поступающие на порт 5000 интерфейса eth0 хоста, на адрес172.18.0.10:5000. Или, другими словами, нам нужно опубликовать порт 5000 контейнера на интерфейсе eth0 хоста.

# External trafficsudo iptables -t nat -A PREROUTING -d 10.0.2.15 -p tcp -m tcp --dport 5000 -j DNAT --to-destination 172.18.0.10:5000# Local traffic (since it doesn't pass the PREROUTING chain)sudo iptables -t nat -A OUTPUT -d 10.0.2.15 -p tcp -m tcp --dport 5000 -j DNAT --to-destination 172.18.0.10:5000

Кроме того, нам нужно включить iptables intercepting traffic over bridged networks (перехватывать трафик bridged networks):

sudo modprobe br_netfilter

Время проверить!

curl 10.0.2.15:5000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"># ... omitted lines ...

Разбираемся в работе Docker network drivers

Но что же вам сделать теперь со всеми этими бесполезными знаниями? Например, мы могли бы попытаться разобраться в некоторых сетевых режимах Docker!

Начнем с режима --network host. Попробуйте сравнить вывод следующих команд ip link и sudo docker run -it --rm --network host alpine ip link. Сюрприз, они совпадут! Таким образом host mode Docker просто не использует изоляцию сетевого пространства имён и контейнеры работают в корневом сетевом пространстве имён и совместно используют сетевой стек с хост-системой.

Следующий режим, который нужно проверить, - это --network none. Вывод команды sudo docker run -it --rm --network none alpine ip link показывает только один сетевой интерфейс обратной loopback. Это очень похоже на наши наблюдения за только что созданным сетевым пространством имен. То есть до того момента, когда мы добавляли какие-либо veth устройства.

И последнее, но не менее важное: режим --network bridge (по умолчанию), это именно то, что мы пытались воспроизвести в этой статье.

Сети и rootless контейнеры

Одной из приятных особенностей диспетчера контейнеров podman является его ориентация на rootless контейнеры. Однако, как вы, вероятно, заметили, в этой статье мы использовали много эскалаций sudo и без root-прав настроить сеть невозможно. При настройке сетей rootful контейнеров Podman очень близок к Docker. Но когда дело доходит до rootless контейнеров, Podman полагается на проект slirp4netns:

Начиная с Linux 3.8, непривилегированные пользователи могут создавать network_namespaces (7) вместе с user_namespaces (7). Однако непривилегированные сетевые пространства имен оказались не очень полезными, потому что для создания пар veth (4) в пространствах имен хоста и сети по-прежнему требуются привилегии root (иначе доступ в Интернету будет отсутствовать).

slirp4netns позволяет получить доступ из сетевое пространства имен в Интернет непривилегированным пользователям, подключая устройство TAP в сетевом пространстве имен к стеку TCP/IP usermode (slirp).

Сеть rootless контейнера весьма ограничена: технически сам контейнер не имеет IP-адреса, потому что без привилегий root невозможно настроить сетевое устройство. Более того, проверка связи (ping) из rootless контейнера не работает, поскольку в нем отсутствует функция безопасности CAP_NET_RAW, которая необходима для работы команды ping.

Заключение

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

Подробнее..

Recovery mode Древний костыль на старом костыле

23.09.2020 20:15:33 | Автор: admin

Начну без обиняков, как-то раз меня постигло откровение(ну не сильно мощное скажу по-честному) и возникла идея напечатать программу которая передает изображение с клиента на сервер. Достаточно просто да? Ну для программиста со стажем так и будет. Условия просты - не использовать сторонние библиотеки. В принципе немного сложнее, но если учесть что придется разбираться и искать примеры, ну такое себе занятие. Я решил, что эта задача мне по плечу. Плюс желательно чтобы было кода столько, чтобы его можно было запостить на форуме, в случае если понадобится помощь. В первую очередь мой взгляд пал на FTP, к слову ОС в которой разрабатывается Windows. Плюс FTP в том, что можно через него передать не только изображение, а любой файл. Скачав Filezilla Server, расшарив одну директорию на чтение/запись и создав юзера с паролем, попробовал подключится Filezilla Client все работало. Создал простенький пример кода на С/С++:

#include <iostream>void main(){FILE* fs;fopen_s(&fs, "1.txt", "w");if (fs){    fwrite("user\r\npassword\r\nsend D:\\share\\1.txt\r\nbye", 1, sizeof("user\r\npassword\r\nsend D:\\share\\1.txt\r\nbye"), fs);    fwrite("\000", 1, sizeof("\000"), fs);    fclose(fs);}system("ftp -s:1.txt 127.0.0.1");}

Если мне не изменяет память, то на локалхосте все работало, а при передаче по сети возникала ошибка в строчке с send. Что здесь удобно а)коротко б)не нужно устанавливать клиент, а использовать уже встроенную тулзу для ftp от майкрософта. Хотя по-мойму ее надо активировать через программы и компоненты. Если вы разберетесь в чем проблема данного метода и напишите в комментарии, будет отлично.

Не найдя ответа на куче форумов, я оставил данный код и решил использовать интерфейс для сетей сокеты. У меня уже был опыт передачи массива char'ов для другой программы. Кстати можете почитать у Таненбаума, Компьютерные сети, в главе про транспортный уровень. Там есть пример клиента и сервера, правда не для соединения "много клиентов - один сервер", а только "один клиент - один сервер". Поскольку передача идет через Интернет, то нужно зашифровать хоть как-то данные. Для этого используется блочный шифр - сеть Фейстеля. Плюсом на сервере надо сделать несколько(больше одного клиента) клиентов. Для этого воспользуемся Thread'ами, изображение для передачи будет брать скриншот экрана с клиента шифроваться и передаваться на сервер, на котором будет расшифровано и сразу же выведено на экран через дефолтную программу для открытия *.tga изображения.

Код сервера:

#include <iostream>#include <WinSock.h>#pragma comment (lib,"WS2_32.lib")#include <fstream>#include <algorithm>#include <string>#include <iterator>#include <vector>void error(const char* msg){    //perror(msg);    std::cout<<'\n'<<WSAGetLastError();    WSACleanup();    std::cin.ignore();    exit(1);}void bzero(char*buf, int l){    for (int i = 0; i < l; i++)        buf[i] = '\0';}struct arg_s{    unsigned char* buffer2;    bool exit;};char** buffer;struct arg_sa{    struct arg_s* lalk;    int current;};#define type struct arg_saint sockfd, * newsockfd;//слушающий и массив клиентских сокетовint buflen2 = 10292000;//максимальный размер изображения в байтах для RGBA*Width*Heightstruct sockaddr_in *cli_addr;int* clilen;int currentclient,cc;//сс-клиент по счету(для записи инкремента имени файла клиента изображения)typedef unsigned long long uint64_t;typedef unsigned int uint32_t;#define N 8//размер блока#define F32 0xFFFFFFFFuint32_t RK[N];//раундовые ключи#define size64 sizeof(uint64_t)#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))#define RKEY(r)((ROR(K,r*3,size64*8))&F32)const uint64_t K = 0x96EA704CFB1CF671;//ключ шифрованияstruct hostent* server;uint32_t F(uint32_t subblk, uint32_t key){    return subblk + key;//функция шифрования}void createRoundKeys(){    for (int i = 0; i < N; i++)        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;}uint64_t decrypt(uint64_t c_block)//расшифровка блоков сетью фейстеля{    //select subblocks    uint32_t left = (c_block >> 32) & F32;    uint32_t right = c_block & F32;    uint32_t left_, right_;//subblock in the end of round    for (int r = N - 1; r >= 0; r--)    {        uint32_t fk = F(left, RK[r]);        left_ = left;        right_ = right ^ fk;        if (r > 0)//swap places to next round        {            left = right_;            right = left_;        }        else //last round not swap        {            left = left_;            right = right_;        }    }    //collect subblock in block    uint64_t block = left;    block = (block << 32) | (right & F32);    return block;}void session_(LPVOID args)//функция потока ля каждого клиента{    int current = currentclient++;    bzero((char*)&(cli_addr[current]), sizeof(&(cli_addr[current])));    newsockfd[current] = accept(sockfd, (struct sockaddr*)&(cli_addr[current]), &(clilen[current]));    if (newsockfd[current] < 0)    {        error("Error on accept\n");    }    char* s = new char[100];    int n = recv(newsockfd[current], s, 100, 0);    int buflen2 = atoi(s);//получаем число байтов изображения    FILE* f;    std::string name = "Screen";    cc++;    _itoa_s(cc, s, 100, 10);    name += s;    name += ".tga";    fopen_s(&f,name.c_str(), "wb");//создаем файл изображения с увеличиваещимся на 1 именем, чтобы не перезаписать    if (f != NULL)    {        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };        unsigned char header[6];        n = recv(newsockfd[current], buffer[current], sizeof(tgaHeader), 0);        fwrite((unsigned char*)buffer[current], 1, sizeof(tgaHeader), f);        bzero(buffer[current], buflen2);        n = recv(newsockfd[current], buffer[current],sizeof(header), 0);        fwrite((unsigned char*)buffer[current], 1, sizeof(header), f);//записали хидеры        bzero(buffer[current], buflen2);        n = recv(newsockfd[current], buffer[current], buflen2, 0);//получили байты самого изображения        //        //расшифровка байтов        createRoundKeys();        unsigned long long id;        std::vector<uint64_t>* plaintext = new std::vector<uint64_t>();        int i = 0;        while (i<buflen2)        {            memcpy(&id, (buffer[current]) + i, N);            plaintext->push_back(decrypt(id));            i += 8;        }        std::cout << "i=" << i << std::endl;        i = 0;        char str_[N + 1];        memset(str_, 0, N);        str_[N] = '\0';        for (std::vector<uint64_t>::iterator it = plaintext->begin(); it != plaintext->end(); ++it)        {            memcpy(str_, &*it, N);            fwrite((unsigned char*)str_, sizeof(unsigned char), N/*strlen(str_)*/, f);            i += 8;        }        std::cout << "i=" << i << std::endl;        //конец рашифровки байтов        //fwrite((unsigned char*)buffer[current], sizeof(char), buflen2, f);        fclose(f);    }    system(name.c_str());//открываем изображение *.tga встроенным редактором}int main(){    cc = 0;    WSADATA ws = { 0 };    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)    {        currentclient = 0;        int maxclients = 2;//максимальное число клиентов        cli_addr = new struct sockaddr_in[maxclients];        clilen = new int[maxclients];        buffer = new char* [maxclients];        for (int i = 0; i < maxclients; i++)        {            clilen[i] = sizeof(cli_addr[i]);        }        sockfd = socket(AF_INET, SOCK_STREAM, 0);//tcp сокет        if (sockfd < 0)            error("ERROR opening socket");        struct sockaddr_in serv_addr;        bzero((char*)&serv_addr, sizeof(serv_addr));        serv_addr.sin_family = AF_INET;        serv_addr.sin_addr.s_addr = INADDR_ANY;        int port = 30000;//порт        serv_addr.sin_port = htons(port);        if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)            error("ERROR on binding");        if (listen(sockfd, 10) < 0)            error("ERROR listen");        HANDLE* thread;//массив потоков для каждого клиента отдельный        struct arg_sa* args;        while (true)        {            newsockfd = new int[maxclients];            thread = (HANDLE*)malloc(sizeof(HANDLE) * maxclients);            args = new struct arg_sa[maxclients];            for (int i = 0; i < maxclients; i++)            {                args[i].lalk = new struct arg_s();                buffer[i] = new char[buflen2];            }            int i = -1;            while (++i < maxclients)            {                Sleep(1);                args[i].current = i;                args[i].lalk->exit = false;                thread[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)(session_), args, 0, 0);            }                for (int i = 0; i < maxclients; i++)                    WaitForSingleObject(thread[i], INFINITE);//ждем завершения всех потоков            i = -1;            while (++i < maxclients)            {                shutdown(newsockfd[i], 0);                TerminateThread(thread[i], 0);            }            //delete[] newsockfd;            //free(thread);            currentclient = 0;            for (int i = 0; i < maxclients; i++)            {                //delete args[i].lalk;                //delete[] args[i].lalk->buffer;            }            //delete[] args;        }        shutdown(sockfd, 0);        WSACleanup();        return 0;    }    std::cin.ignore();}

Вкратце в вечном цикле создаются потоки для каждого клиента и ждут accept пока клиенты подключится. После чего WaitForSingleObject ждет пока они все передадут. У каждого клиента свой сокет и свой буфер передачи. То есть на сервере M+1 сокет, где M количество клиентов. После завершения всех передач, всё повторяется.

Теперь рассмотрим клиент:

#include <iostream>#include <WinSock.h>#include <vector>#pragma comment (lib,"WS2_32.lib")void error(const char* msg){    //perror(msg);    std::cout << '\n' << WSAGetLastError();    WSACleanup();    std::cin.ignore();    exit(1);}void bzero(char* buf, int l){    for (int i = 0; i < l; i++)        buf[i] = '\0';}typedef unsigned long long uint64_t;typedef unsigned int uint32_t;#define N 8#define F32 0xFFFFFFFFuint32_t RK[N];//раундовые ключи#define size64 sizeof(uint64_t)#define ROR(x,n,xsize)((x>>n)|(x<<(xsize-n)))#define ROL(x,n,xsize)((x<<n)|(x>>(xsize-n)))#define RKEY(r)((ROR(K,r*3,size64*8))&F32)const uint64_t K = 0x96EA704CFB1CF671;//ключ шифрованияvoid createRoundKeys(){    for (int i = 0; i < N; i++)        RK[i] = (ROR(K, i * 8, size64 * 8)) & F32;}uint32_t F(uint32_t subblk, uint32_t key){    return subblk + key;//функция шифрования}uint64_t encrypt(uint64_t block)//зашифровка блоков сетью Фейстеля{    //select subblocks    uint32_t left = (block >> 32) & F32;    uint32_t right = block & F32;    uint32_t left_, right_;//subblock in the end of round    for (int r = 0; r < N; r++)    {        uint32_t fk = F(left, RK[r]);        left_ = left;        right_ = right ^ fk;        if (r < N - 1)//swap places to next round        {            left = right_;            right = left_;        }        else//last round not swap        {            left = left_;            right = right_;        }    }    //collect subblock in block    uint64_t c_block = left;    c_block = (c_block << 32) | (right & F32);    return c_block;}int main(){    keybd_event(VK_LWIN, 0, 0, 0);    keybd_event('M', 0, 0, 0);    keybd_event('M', 0, KEYEVENTF_KEYUP, 0);    keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);//эти строки сворачивают все приложения    Sleep(1000);//чтобы сделать скриншот рабочего стола    WSADATA ws = { 0 };    if (WSAStartup(MAKEWORD(2, 2), &ws) == 0)    {        int sockfd;        sockfd = socket(AF_INET, SOCK_STREAM, 0);        struct sockaddr_in serv_addr, cli_addr;        bzero((char*)&serv_addr, sizeof(serv_addr));        bzero((char*)&cli_addr, sizeof(cli_addr));        serv_addr.sin_family = AF_INET;        const char* add = "127.0.0.1";//адрес сервера        serv_addr.sin_addr.s_addr = inet_addr(add);        int port = 30000;//порт        serv_addr.sin_port = htons(port);        int servlen = sizeof(serv_addr);        int n = connect(sockfd, (struct sockaddr*)&serv_addr, servlen);                //ниже код делает скриншот        HDC ScreenDC = GetDC(0);        HDC MemoryDC = CreateCompatibleDC(ScreenDC);        int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);        int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);        ScreenWidth = ((ScreenWidth - 1) / 4 + 1) * 4;        BITMAPINFO BMI;        BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);        BMI.bmiHeader.biWidth = ScreenWidth;        BMI.bmiHeader.biHeight = ScreenHeight;        BMI.bmiHeader.biSizeImage = ScreenWidth * ScreenHeight * 3;        BMI.bmiHeader.biCompression = BI_RGB;        BMI.bmiHeader.biBitCount = 24;        BMI.bmiHeader.biPlanes = 1;        DWORD ScreenshotSize;        ScreenshotSize = BMI.bmiHeader.biSizeImage;        unsigned char* ImageBuffer;        HBITMAP hBitmap = CreateDIBSection(ScreenDC, &BMI, DIB_RGB_COLORS, (void**)&ImageBuffer, 0, 0);        SelectObject(MemoryDC, hBitmap);        BitBlt(MemoryDC, 0, 0, ScreenWidth, ScreenHeight, ScreenDC, 0, 0, SRCCOPY);        DeleteDC(MemoryDC);        ReleaseDC(NULL, ScreenDC);        FILE* sFile = 0;        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };        unsigned char header[6];        unsigned char tempColors = 0;        fopen_s(&sFile, "S.tga", "wb");        if (!sFile) {            exit(1);        }        header[0] = ScreenWidth % 256;        header[1] = ScreenWidth / 256;        header[2] = ScreenHeight % 256;        header[3] = ScreenHeight / 256;        header[4] = BMI.bmiHeader.biBitCount;        header[5] = 0;        fwrite(tgaHeader, 1, sizeof(tgaHeader), sFile);        fwrite(header, sizeof(header), 1, sFile);        //конец записали изображение в файл                //шифруем блоками полезную нагрузку изображения кроме хидеров        createRoundKeys();        std::vector<uint64_t>* msg = new std::vector<uint64_t>(),*crpt = new std::vector<uint64_t>();        unsigned long long id;        int i = 0;        while (i < BMI.bmiHeader.biSizeImage)        {            memcpy(&id, (ImageBuffer + i), N);            msg->push_back(id);            i += 8;        }        std::cout << "i=" << i << std::endl;         uint64_t cipher;        i = 0;        char str_[N + 1];        memset(str_, 0, N);        str_[N] = '\0';        for (std::vector<uint64_t>::iterator it = msg->begin(); it != msg->end(); ++it)        {            cipher = encrypt(*it);            memcpy(str_, &cipher, N);            fwrite((unsigned char*)str_, sizeof(unsigned char), N, sFile);            i += 8;        }        std::cout << "i=" << i << std::endl;        //        //fwrite(ImageBuffer, BMI.bmiHeader.biSizeImage, 1, sFile);        std::cout << BMI.bmiHeader.biSizeImage << std::endl;        fclose(sFile);        DeleteObject(hBitmap);        FILE* f;        fopen_s(&f, "S.tga", "rb");        int count = 0;        if (f != NULL)        {            while (getc(f) != EOF)                count++;//считаем байты изображения в счетчик чтобы потом передать            fclose(f);        }        count -= 18;        std::cout << count<< std::endl;        char* s = new char[100];        _itoa_s(count, s, 100, 10);        n = send(sockfd, s, 100, 0);//передаем счетчик        char* buffer = new char[count];        fopen_s(&f, "S.tga", "rb");        size_t bytes;        if (f != NULL)        {            memcpy(buffer, tgaHeader, sizeof(tgaHeader));            n = send(sockfd, buffer, sizeof(tgaHeader), 0);            bzero(buffer, count);            memcpy(buffer, header, sizeof(header));            n = send(sockfd, buffer, sizeof(header), 0);            bzero(buffer, count);//передаем хидеры            for(int i=0;i<18;i++)                fgetc(f);            bzero(buffer, count);            bytes = fread(buffer, sizeof(unsigned char), count, f);            n = send(sockfd,buffer, count, 0);//передаем шифрованные байты изображения            fclose(f);        }        Sleep(1000);        shutdown(sockfd, 0);        WSACleanup();        //system("del S.tga");        delete[] buffer,s;        return 0;    }    //std::cin.ignore();}

Вот результат работы клиента файл скриншота S.tga, зашифрованный

Видно, что это рабочий стол

А вот результат который был передан на сервер и расшифрован Screen.tga

Как видите обычная сеть Фейстеля не подходит для шифрования, но можно воспользоваться CBC и CFB методами, возможно будет лучше зашифровано, если честно не проверял.

Спасибо за внимание!

Подробнее..

Перевод Инструмент для отслеживания DNS-запросов dnspeep

07.05.2021 18:23:01 | Автор: admin

Недавно я создала небольшой инструмент под названием dnspeep, который позволяет понять, какие DNS-запросы отправляет ваш компьютер и какие ответы он получает. Всего мой код занял 250 строк на Rust. В этой статье я расскажу о коде, объясню, для чего он нужен, почему в нём возникла необходимость, а также расскажу о некоторых проблемах, с которыми я столкнулась при его написании. И, конечно, вы сами сможете попробовать код в действии.


Что нужно для начала работы с кодом

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

Команды для Linux (x86):

wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-linux.tar.gztar -xf dnspeep-linux.tar.gzsudo ./dnspeep

Команды для Mac:

wget https://github.com/jvns/dnspeep/releases/download/v0.1.0/dnspeep-macos.tar.gztar -xf dnspeep-macos.tar.gzsudo ./dnspeep

Коду необходим доступ ко всем отправляемым компьютером пакетам DNS, поэтому его необходимо запускать от имени root. По этой же причине утилиту tcpdump также нужно запускать от имени root: код использует libpcap ту же библиотеку, что и tcpdump. Если вам по какой-либо причине не захочется загружать бинарные файлы и запускать их от имени root, вы можете воспользоваться моим исходным кодом и создать на его основе собственный.

Что получается в результате

Каждая строка представляет собой DNS-запрос и соответствующий запросу ответ.

$ sudo dnspeepquery   name                 server IP      responseA       firefox.com          192.168.1.1    A: 44.235.246.155, A: 44.236.72.93, A: 44.236.48.31AAAA    firefox.com          192.168.1.1    NOERRORA       bolt.dropbox.com     192.168.1.1    CNAME: bolt.v.dropbox.com, A: 162.125.19.131

Эти запросы отражают мои визиты на сайт neopets.com в браузере, а запрос bolt.dropbox.com возник потому, что у меня запущен агент Dropbox, и, как я полагаю, время от времени он заходит на свой сайт для синхронизации.

Зачем создавать ещё один инструмент DNS?

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

Ваш браузер (и другие компьютерные программы) постоянно отправляет DNS-запросы. Если знать, какие запросы отправляет компьютер и какие ответы он получает, можно получить более реальную картину "жизни" компьютера.

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

Можно увидеть, какое программное обеспечение "тайно" выходит в Интернет

Мне нравится в этом инструменте, что он даёт представление о том, какие программы моего компьютера пользуются Интернетом! Например, я обнаружила, что какая-то утилита на моём компьютере время от времени по непонятной причине отправляет запросы на ping.manjaro.org, вероятно, чтобы проверить, подключён ли мой компьютер к Интернету.

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

Если вы раньше не работали с tcpdump, поначалу может быть непонятно, что делает эта утилита

Рассказывая людям об отправляемых с компьютера DNS-запросах, я почти всегда хочу добавить: "Всю информацию можно получить через tcpdump!" Что делает утилита tcpdump? Она осуществляет разбор пакетов DNS! Например, вот как выглядит DNS-запрос incoming.telemetry.mozilla.org.:

11:36:38.973512 wlp3s0 Out IP 192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48)11:36:38.996060 wlp3s0 In  IP 192.168.1.1.53 > 192.168.1.181.42281: 56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 35.244.247.133 (180)

Сначала эта информация может показаться "тёмным лесом", но её при некоторых навыках можно научиться читать. Давайте для примера разберём такой запрос:

192.168.1.181.42281 > 192.168.1.1.53: 56271+ A? incoming.telemetry.mozilla.org. (48)
  • A? означает DNS-запрос типа A;

  • incoming.telemetry.mozilla.org. это имя объекта, к которому осуществляется запрос;

  • 56271 это идентификатор DNS-запроса;

  • 192.168.1.181.42281 исходный IP/порт;

  • 192.168.1.1.53 IP/порт назначения;

  • (48) длина DNS-пакета.

Ответ выглядит следующим образом:

56271 3/0/0 CNAME telemetry-incoming.r53-2.services.mozilla.com., CNAME prod.data-ingestion.prod.dataops.mozgcp.net., A 35.244.247.133 (180)
  • 3/0/0 количество записей в ответе: 3 ответа, 0 полномочий, 0 дополнительно. Исходя из моего опыта, tcpdump выводит только количество ответов на запрос.

  • CNAME telemetry-incoming.r53-2.services.mozilla.com, CNAME prod.data-ingestion.prod.dataops.mozgcp.net. и A 35.244.247.133 это те самые три ответа

  • 56271 идентификатор ответов, соответствующий идентификатору запроса. По этому идентификатору можно понять, что это ответ на запрос из предыдущей строки.

С таким форматом, конечно, работать довольно сложно, ведь человеку нужно просто посмотреть на трафик DNS, к чему все эти нагромождения? И вот ему приходится вручную сопоставлять запросы и ответы, к тому же не всегда находящиеся на соседних строках. Здесь в дело вступают компьютерные возможности!

Я решила написать небольшую программку dnspeep, которая будет сама выполнять такое сопоставление, а также удалять определённую (на мой взгляд, лишнюю) информацию.

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

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

  • Мне пришлось несколько изменить библиотеку pcap, чтобы заставить её правильно работать с Tokio на Mac OS вот эти изменения. Это была одна из тех ошибок, на поиск которой ушло много часов, а всё исправление уложилось в одну строку.

  • Разные дистрибутивы Linux, по всей видимости, используют разные версии libpcap.so, поэтому мне не удалось воспользоваться непосредственно бинарным файлом, динамически компонующим libpcap (у других пользователей возникала такая же проблема, например здесь). Поэтому компилировать библиотеки libpcap в инструмент на Linux мне пришлось статически. Я до сих пор не понимаю, как такое правильно организовать на Rust, но я добилась, чего хотела, и всё заработало я скопировала файл libpcap.a в каталог target/release/deps, а затем просто запустила cargo build.

  • Используемая мною библиотека dns_parser поддерживает не все типы DNS-запросов, а только некоторые самые распространённые. Возможно, для разбора DNS-пакетов можно было использовать другую библиотеку, но я не нашла подходящей.

  • Поскольку интерфейс библиотеки pcap выдает набор "голых" байтов (в том числе для данных Ethernet-фреймов), мне пришлось написать код, который определял, сколько байтов нужно отсечь от начала строки, чтобы получить IP-заголовок пакета. Но я уверена, что в моей задаче ещё остались "подводные камни".

Кстати, вы даже не представляете, каких сложностей мне стоило подобрать название для своей утилиты ведь инструментов для работы с DNS великое множество, и у каждого своё название (dnsspy! dnssnoop! dnssniff! dnswatch!) Сначала я хотела включить в название слово spy (шпион) или его синонимы, а затем остановилась на показавшемся мне забавным названии, которое о чудо! ещё никто не занял для собственного DNS-инструмента.

У моей утилиты есть один недостаток: она не сообщает, какой именно процесс отправил DNS-запрос, но выход есть используйте инструмент dnssnoop. Этот инструмент работает с данными eBPF. Судя по описанию, он должен работать нормально, но я его ещё не пробовала.

В моём коде наверняка ещё много ошибок

Мне удалось его протестировать только на Linux и Mac, и я уже знаю как минимум об одной ошибке (из-за того, что поддерживаются не все DNS-запросы). Если найдёте ошибку, пожалуйста, сообщите мне!

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

Мне нравится составлять небольшие учебные материалы

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

  • Простой способ составления DNS-запросов;

  • Рассказывается, что происходит внутри компьютера при отправке DNS-запроса;

  • Ссылка на dnspeep.

Ранее в своих постах я просто объясняла, как работают существующие инструменты (например dig или tcpdump), а если и писала собственные инструменты, то довольно редко. Но сейчас для меня очевидно, что выходные данные этих инструментов довольно туманны, их сложно понять, поэтому мне захотелось создать более дружественные варианты просмотра такой информации, чтобы не только гуру tcpdump, но любые другие пользователи могли понять, какие DNS-запросы отправляет их компьютер.

А если вы хотите не только понимать, что происходит с запросами и ответами DNS на вашем компьютере, но и писать собственные протоколы для своих приложений, обратите внимание на профессии C++ разработчик или Java-разработчик, позволяющие с нуля освоить эти языки или прокачать своё владение ими. Приходите опытные менторы и эксперты своего дела с удовольствием поделяться с вами своими знаниями.

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

Перевод Сеть в bitly Linux tc для минимизации издержек и забавы ради

02.06.2021 20:09:34 | Автор: admin

Представьте, что вы, например, bitly то есть очень большой сервис сокращения ссылок. И вот, вы хотите скопировать свои 150 ТБ сжатых данных с одного физического кластера на другой, новый. Чтобы сделать это, вы запускаете distcp из набора инструментов hadoop и рады тому, насколько быстро он работает. Но, несколько позже, вы уже совсем не радуетесь жалобам обычных пользователей веб-сайта и API-клиентов случаются ошибки, задерживаются ответы, а данные их дата-центра только запутывают. К старту курса о DevOps мы перевели материал о том, что делать, если вы, как и bitly, оказались в подобной ситуации.


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

Важной частью инфраструктуры bitly и основным инструментом команды Data Science и рабочей группы обслуживания операций и инфраструктуры (Ops/Infra) в течение довольно долгого времени был физический кластер hadoop набор утилит, библиотек и фреймворк для разработки и выполнения распределённых программ, работающих на кластерах из сотен и тысяч узлов. Мы уже давно вынашивали идею подключения нового кластера, копирования и объединения данных старого кластера с данными нового.

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

  • bitly работает с огромными объёмами данных: на момент миграции кластер hadoop занимал более 150 ТБ дискового пространства сжатых потоковых данных, то есть данных, полученных в результате работы наших различных приложений. Объёмы таких данных продолжали увеличиваться в результате дополнительной обработки другими приложениями;

  • физически инфраструктура bitly располагается в центре обработки данных нашего партнёра. Она состоит из трёх физических видов шасси (приложения, хранилище и база данных), расположенных в ряд в смежных стойках. На момент написания этой статьи каждое шасси имело три физических гигабитных Ethernet-канала (каждый логически изолирован посредством организации сети VLAN) прямой канал, обратный канал и схему удалённого управления (для внеполосного управления серверными шасси). Каждое соединение после прохождения через ряд патч-панелей и коммутаторов подключается к нашим главным коммутаторам через стеклянное оптоволокно 10 Gb по звездообразной схеме сети;

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

Вернёмся к нашей истории.

Для быстрого копирования данных с одного кластера на другой мы воспользовались инструментом distcp, поставляемом в комплекте с кластером hadoop. Говоря просто, инструмент distcp выдаёт задание программному фреймворку mapreduce (используемому для параллельных вычислений над очень большими наборами данных в компьютерных кластерах) на перемещение данных из одного кластера hdfs в другой при копировании узлов в режиме "многие ко многим". Инструмент distcp сработал быстро, и это нас порадовало.

Но тут сломался сервис bitly, и это не привело в восторг команду Ops/Infra.

Пользователи веб-сайта и API-клиенты стали жаловаться на ошибки и задержки в получении ответов. Нам удалось выяснить, что причиной ошибок было получение нашим сервисом ошибок от других сервисов, что приводило к превышению времени ожидания при вызове баз данных и даже сбоям при обработке DNS-запросов внутри нашей собственной сети. Мы выяснили, что копирование данных привело к необъяснимому увеличению нагрузки на сетевые устройства, особенно на устройства, передающие трафик через физические стойки. Мы надеялись решить проблему, получив информацию от нашего партнёра из центра обработки данных, но эта информация не только не помогла, но и ещё больше нас запутала: ни одно соединение и ни одна стойка не проявляли никаких признаков насыщения, перегруженности или ошибок.

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

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

В новом кластере было больше узлов, значит, по идее, hadoop должен был работать быстрее.

Мы, кажется, осчастливили команду Data Science.

Но, к сожалению, поскольку кластер hadoop стал крупнее и быстрее, во время работы mapreduce на большее количество узлов стало передаваться большее количество данных, и это привело к непредвиденному эффекту:

Сервис bitly опять сломался, на этот раз очень серьёзно. Команда Ops/Infra была от этого не в восторге.

Первым импульсивным действием было вообще отрубить hadoop.

Но такое решение очень не понравилось команде Data Science.

Отключение кластера hadoop самое плохое из возможных решений (по последствиям может сравниться разве что с поломкой bitly), поэтому мы вернули кластер в состояние 1995 года, заставив все сетевые карты перейти на 100 Мбит/с (с 1 Гбит/с) с помощью команды ethtool -s eth1 speed 100 duplex full autoneg on. Теперь можно было спокойно подключить hadoop, но какой же медленной стала его работа!

Команда Data Science по-прежнему не выказывала признаков восторга.

И действительно, работа кластера была настолько "тормозной", что при вводе данных, выполнении запланированных заданий ETL (извлечения, преобразования и загрузки) и выдаче отчётов стали часто возникать сбои, постоянно срабатывали аварийные сигналы, будившие среди ночи членов команды Ops/Infra.

Надо ли говорить, как это не нравилось команде Ops/Infra!

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

Сделаем ещё одно небольшое отступление:

Что нам было доступно в bitly?

  • roles.json : список серверов (app01, app02, userdb01, hadoop01 и т. д.), ролей (userdb, app, web, monitoring, hadoop_node и т.д.), а также сведения об отображении серверов на роли (app01,02 -> app, hadoop01,02 -> hadoop_node и т. д.);

  • $datacenter/jsons/* : каталог, содержащий json-файл для каждого логического сервера с атрибутами, описывающими сервер, IP-адресами, именами, информацией конфигурирования и, что наиболее важно в нашей истории, расположением стоек.;

  • Linux : Linux.

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

Но команда Ops/Infra не проявляла признаков радости.

Её не устраивал синтаксис системы контроля сетевого трафика (Traffic Control, tc) в Linux, не говоря уже о совершенно неудобочитаемой документации. После напряжённого периода работы (с многочисленными проклятиями и разбиванием о стену клавиатур) мы смогли, наконец, создать не вызывающие отторжения работающие сценарии в tc. Были открыты ветви, написаны скрипты, выполнены развёртывания, проведены эталонные тестирования, и в результате было создано несколько тестовых узлов с таким кодом:

$ tc class show dev eth1class htb 1:100 root prio 0 rate 204800Kbit ceil 204800Kbit burst 1561b    cburst 1561bclass htb 1:10 root prio 0 rate 819200Kbit ceil 819200Kbit burst 1433b     cburst 1433bclass htb 1:20 root prio 0 rate 204800Kbit ceil 204800Kbit burst 1561b     cburst 1561b$ tc filter show dev eth1filter parent 1: protocol ip pref 49128 u32 filter parent 1: protocol ip pref 49128 u32 fh 818: ht divisor 1 filter parent 1: protocol ip pref 49128 u32 fh 818::800 order 2048 key     ht 818 bkt 0 flowid 1:20     match 7f000001/ffffffff at 16filter parent 1: protocol ip pref 49129 u32 filter parent 1: protocol ip pref 49129 u32 fh 817: ht divisor 1 filter parent 1: protocol ip pref 49129 u32 fh 817::800 order 2048 key     ht 817 bkt 0 flowid 1:10     match 7f000002/ffffffff at 16filter parent 1: protocol ip pref 49130 u32 filter parent 1: protocol ip pref 49130 u32 fh 816: ht divisor 1 filter parent 1: protocol ip pref 49130 u32 fh 816::800 order 2048 key     ht 816 bkt 0 flowid 1:20     match 7f000003/ffffffff at 16<snipped>$ tc qdisc showqdisc mq 0: dev eth2 root qdisc mq 0: dev eth0 root qdisc htb 1: dev eth1 root refcnt 9 r2q 10 default 100     direct_packets_stat 24

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

class htb 1:100 root prio 0 rate 204800Kbit ceil 204800Kbit burst 1561b cburst 1561b

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

Каждый фильтр это конкретное правило для конкретного IP (к сожалению, каждый IP выводится в шестнадцатеричном формате), поэтому фильтр:

filter parent 1: protocol ip pref 49128 u32 filter parent 1: protocol ip pref 49128 u32 fh 818: ht divisor 1 filter parent 1: protocol ip pref 49128 u32 fh 818::800 order 2048 key     ht 818 bkt 0 flowid 1:20     match 7f000001/ffffffff at 16

можно интерпретировать как "subscribe hadoop14 to the class 1:20", где "7f000001" можно интерпретировать как IP для hadoop14, а "flowid 1:20" класс для подписки. Затем запускаем команду qdisc, формирующую более или менее активную очередь для устройства eth1. Данная очередь по умолчанию помещает любой хост, не определённый в фильтре класса, в класс 1:100:

qdisc htb 1: dev eth1 root refcnt 9 r2q 10 default 100 direct_packets_stat 24

В такой конфигурации любой хост (hadoop или другой), находящийся в одной стойке с конфигурируемым хостом, получает фильтр, назначенный классу "1:10", разрешающий скорость передачи до ~800 Мбит/с для класса в целом. Аналогичным образом для предопределённого списка ролей, считающихся "ролями приоритетных узлов", создаётся фильтр по тому же правилу "1:100". Такие узлы выполняют довольно важные задачи, например запускают сервисы hadoop namenode или jobtracker, а также наши узлы мониторинга. Любой другой хост hadoop, не находящийся в той же стойке, подключается к классу "1:20", ограниченному более консервативным классом ~200 Мбит/с.

Как было сказано выше, любой хост, не определённый в фильтре, попадает в класс по умолчанию для eth1 qdisc, то есть в класс "1:100". Как это выглядит на практике? Вот хост, подпадающий под действие правила "1:100":

[root@hadoop27 ~]# iperf -t 30 -c NONHADOOPHOST------------------------------------------------------------Client connecting to NONHADOOPHOST, TCP port 5001TCP window size: 23.2 KByte (default)------------------------------------------------------------[  3] local hadoop27 port 35897 connected with NONHADOOPHOST port 5001[ ID] Interval       Transfer     Bandwidth[  3]  0.0-30.1 sec   735 MBytes   205 Mbits/sec

Теперь при подключении к другому хосту, расположенному в той же стойке или подпадающему под правило "1:10":

[root@hadoop27 ~]# iperf -t 30 -c CABINETPEER------------------------------------------------------------Client connecting to CABINETPEER, TCP port 5001TCP window size: 23.2 KByte (default)------------------------------------------------------------[  3] local hadoop27 port 39016 connected with CABINETPEER port 5001[ ID] Interval       Transfer     Bandwidth[  3]  0.0-30.0 sec  2.86 GBytes   820 Mbits/sec

Что произойдёт при подключении к двум серверам, подпадающим под правило "1:10"?

[root@hadoop27 ~]# iperf -t 30 -c CABINETPEER1------------------------------------------------------------Client connecting to CABINETPEER1, TCP port 5001TCP window size: 23.2 KByte (default)------------------------------------------------------------[  3] local hadoop27 port 39648 connected with CABINETPEER1 port 5001[ ID] Interval       Transfer     Bandwidth[  3]  0.0-30.0 sec  1.47 GBytes   421 Mbits/sec[root@hadoop27 ~]# iperf -t 30 -c CABINETPEER2------------------------------------------------------------Client connecting to 10.241.28.160, TCP port 5001TCP window size: 23.2 KByte (default)------------------------------------------------------------[  3] local hadoop27 port 38218 connected with CABINETPEER2 port 5001[ ID] Interval       Transfer     Bandwidth[  3]  0.0-30.0 sec  1.43 GBytes   408 Mbits/sec

Трафик уменьшится вдвое? Похоже на правду. Даже лучше стало относительно проще отслеживать тренды данных, анализируя статистические данные, выводимые на наши сервисы трендов:

$ /sbin/tc -s class show dev eth1 classid 1:100class htb 1:100 root prio 0 rate 204800Kbit ceil 204800Kbit     burst 1561b cburst 1561b Sent 5876292240 bytes 41184081 pkt (dropped 0, overlimits 0 requeues 0) rate 3456bit 2pps backlog 0b 0p requeues 0 lended: 40130273 borrowed: 0 giants: 0tokens: 906 ctokens: 906

После тестирования мы проверили хосты hadoop, подняв их скорости до первоначальных 1Gb после применения ролей traffic control. После всех описанных действий кластер hadoop вновь обрёл достаточно высокую производительность.

Мы осчастливили команду Data Science.

Команда Ops/Infra смогла приступить к устранению неполадок и поиску решений, при этом спокойно спать по ночам, зная, что сервис bitly будет вести себя нормально.

Мы осчастливили и команду Ops/Infra.

Выводы:

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

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

  • Linux TC это дорогой инструмент, но и отдача от него очень большая. Этот инструмент почти наверняка создавали бородатые люди с самыми мохнатыми свитерами на свете, и для его применения требуются время и терпение. В любом случае это невероятно мощный инструмент он помог нам исправить наши собственные ошибки.

  • Linux: Linux

И последнее

Эта история хорошая иллюстрация "закона Мерфи для девопсов":

Закон Мёрфи для девопсов: "Если что-то может пойти не так, значит, что-то уже идёт не так, просто Nagios ещё не предупредил".

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

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

Узнайте, как прокачаться и в других специальностях или освоить их с нуля:

Другие профессии и курсы
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru