RSS

Комментарии

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

Например:

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

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

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

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

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

Почему Kubernetes?

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

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

Kubernetes и контейнеры, конечно, самая важная часть облачного стека, но они не решают всех задач по управлению контейнеризированными облачными приложениями в производственной среде. Первым пользователям приходилось создавать собственные решения для управления сложностями, связанными с Kubernetes, и сопутствующими задачами. С развитием экосистемы появились различные типы вспомогательных решений. Прежде чем рассмотреть эти решения, давайте поговорим о сложностях, связанных с Kubernetes, и их влиянии на разные типы организаций.
Ясно, можете простыми словами объяснить почему организации так стремятся использовать контейнеры и Kubernetes?
Сегодня даже консервативные организации начинают внедрять Kubernetes. Платформа предлагает очевидные преимущества, — удобное развертывание, высокая скорость и гибкость, прозрачное управления расходами, — но при этом приводит к ряду новых проблем. Во многом эти проблемы в разных организациях схожи, но универсального решения для них не существует.
Ответ зависит от ряда факторов. Главный из них, предпочтительный для вас принцип управления рабочими нагрузками: с помощью Kubernetes или посредством стандартных инструментов публичного облака. На платформах Anthos и Tanzu, например, оркестратор с открытым кодом используется для координации всех процессов, тогда как в решениях вроде Outposts и Azure Stack для развертывания приложений и управления ими используются собственные облачные инструменты оператора (CloudWatch, CloudTrail, CloudFormation и т.д.). Если вы предпочитаете средства развертывания приложений и управления ими, которые предлагает сам оркестратор Kubernetes, возможно, стоит сделать выбор в пользу платформы, где есть эта возможность.

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

Неплохо также учесть долгосрочные перспективы самого Kubernetes. Сегодня он пользуется бешеной популярностью, в связи с чем платформу, собственно, и взяли на вооружение Google, VMware и другие компании, однако она появилась всего семь лет тому назад. Вполне возможно, что со временем Kubernetes уйдет в прошлое, как временное увлечение, а не станет одним из столпов мира ИТ.

Можно напомнить, что еще пять-шесть лет тому назад, когда о Kubernetes еще мало кто слышал, казалось, что технологическим миром будет править система контейнеризации Docker и что надо внедрять решения на ее основе. Но вышло по-другому: создатели Docker из одноименного стартапа раскрыли формат контейнеров, а Google передала сообществу Open Source свою разработку Kubernetes. В результате Docker стал лишь катализатором развития экосистемы Kubernetes. Альтернативой решению с открытым кодом мог бы стать оркестровщик контейнеров Mesosphere и другие, но поскольку Kubernetes взяли на вооружение тяжеловесы во главе с Microsoft, этого не произошло. Если история повторится, внедрять сейчас гибридную платформу на базе Kubernetes, — это все равно что несколько лет тому назад полностью перейти на Mesosphere. Все будет работать, пока будет сохраняться «хайп», но когда мода пройдет, возможно, понадобится полная перестройка.

И, напоследок, в процессе выбора стоит учесть еще один фактор. В целом гибридные облака на Kubernetes обеспечивают больше гибкости, чем среды, зависимые от собственных инструментов облачного оператора. Например, если вы пользуетесь Azure Stack, то в случае необходимости будет трудно перейти на AWS Outposts, ведь по сути это потребует полноценной миграции из Azure в AWS. А вот переход с Anthos на Tanzu пройдет проще (хотя тоже не идеально легко), поскольку обе платформы базируются на Kubernetes.

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

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

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

Учитывая эту возможность, часть поставщиков, предлагающих решения для построения гибридного облака, в последние годы выбрали Kubernetes в качестве основы таких решений. Возможно, наиболее яркий пример, — система Google Anthos, в которой оркестратор Google Kubernetes Engine может управлять кластерами, размещенными в любом общедоступном облаке и в частном центре обработки данных. Еще один такой пример — решение Tanzu компании VMware, которое она предлагает в облаках Azure и AWS.

Сервис EKS Anywhere от самой AWS, который может управлять кластерами в локальной среде и собственном облаке компании с помощью оркестратора Amazon Elastic Kubernetes, тоже в принципе относится к платформам гибридного облака. Однако это не главное гибридное решение Amazon. Основным является AWS Outposts, которое предоставляет более широкий набор соответствующих сервисов, но не базируется на Kubernetes. Однако учитывая, что EKS Anywhere поддерживает развертывание контейнерных приложений, работающих в разных средах, его в принципе можно отнести к платформам гибридного облака.

Этим перечень крупных гибридных платформ на базе Kubernetes по большей части исчерпывается. Другие решения такого рода, в том числе AWS Outposts, Azure Stack и Azure Arc, для управления гибридным облаком пользуются иными технологиями. Все эти решения поддерживают возможность развертывания Kubernetes в рамках гибридной архитектуры, но не применяют сам оркестратор в качестве слоя управления гибридным развертыванием.
Все существующие сейчас платформы гибридного облака можно отнести к одной из двух широких категорий — основанные на Kubernetes и остальные. Соответственно, использовать Kubernetes в качестве основы или нет — вот один из главных вопросов, которые сегодня приходится решать, приступая к интеграции внутренней (или размещенной в центре колокации) инфраструктуры с сервисами общедоступного облака.
Очень полезная статья и комментарии, всем большое спасибо
Сейчас как раз занимаемся подключением кассы. Очень полезная статья и комментарии, всем большое спасибо
Очень полезная статья и комментарии, всем большое спасибо
Очень полезная статья и комментарии, всем большое спасибо, мы заказали у юристов подготовить пакет документов по персональным данным и политике конфиденциальности
Очень полезная статья и комментарии, всем большое спасибо, сейчас как раз занимаемся оформлением документов для своего маркетплейса
Такое вполне возможно, когда сервис платежной системы используется «готовый» и интегрируется в существующее веб-приложение.
нет, потому что если разрабы не тупые джуны, они никому не доверяют, даже соседнему сервису (где вполне могут сидеть тупые джуны)
Все равно не совсем понятно. Можно подробнее пример взаимодействия, когда разработчики этих разных сервисов не совсем уж тупые джуны и чуть-чуть думают о входных данных?
Не совсем так. Исходный json подменить может любой. И если в компании разные службы обслуживаются разными (микро)сервисами, то вполне возможна такая ситуация. Тут уж зависит от уровня квалификации разработчиков.
Я чего-то не догоняю: а не пофиг ли вообще, как там распарсит парсер? Любые входные данные все равно будут проверяться бизнес-логикой. Скажем, в примере с пачкой чипсов возможность ставить отрицательное количество товара (если таковая вообще есть в принципе) будет зависеть как минимум от роли пользователя.

И это со всеми примерами так: не взломав авторизацию, ими не воспользуешься, а если взломать — так они уже и не нужны.
Описанные ранее уязвимости в основном находятся на уровне логики работы парсеров и обработчиков запросов. Защита достигается путем взаимной работы отдела разработчиков и ИБ-отдела. И если со стороны разработчиков все понятно — не использовать уязвимые библиотеки и вовремя обновляться, то ИБ-отдел может предложить использовать средства защиты веб-приложений — WAF (Web Application Firewall) с функциональностью API Protect. В таком случае WAF обычно выступает дополнительной точкой отказа.

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

Чем может похвастаться Nginx App Protect

Во-первых, в отличии от классического WAF, он достаточно гибко разворачивается в DevOps инфраструктуру. Является модулем для подписки NGINX Plus.

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

Функционал:

— Сигнатурный анализ. Автоматически или принудительно можно указать используемые технологии веб-приложения, и соответственно не «громоздить» сам nginx лишними проверками сигнатур. В общем для API обязательный функционал. Т.к. даже если злоумышленник не будет целиться непосредственно на библиотеки API, с помощью API вызовов вполне можно реализовать сценарий атаки на смежные технологии веб-приложения, передав злоумышленный пейлоад в API.

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

— HTTP Compliance — не совсем относится к API, тем не менее ограничивающие политики для запросов всегда нужны и важны.

— Data Guard — маскирование критических данных в запросах. Например, если в API передаются серия и номер паспорта, есть возможность маскировать эту информацию.

— Parameter parsing — автоматический парсинг параметров из запроса для создания отдельных логических объектов. Далее созданные объекты могут быть индивидуально настроены для применения тех или иных ограничений.

— JSON Content — в системе есть возможность создать логический профиль для описания разрешений при использовании JSON. Скажем, можно определить разрешенную длину полезной нагрузки JSON и длину массива, проверять возможные атаки на парсеры JSON.

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

— gRPC Content — в системе создается профиль содержимого gRPC. Nginx обнаруживает сигнатуры атак и запрещенные метасимволы. Кроме того, есть возможность запрещать использование неизвестных полей. Для этого необходимо будет указать файл определения языка (IDL).

Как и говорил ранее, немного о существующих решениях на российском рынке:

PTAF — разработка компании «Positive Technologies», не имеет каких-то автоматизированных протекторов API. Тем не менее у PTAF очень гибкий движок по написанию собственных правил, а также встроенные функции проверки потенциально нелегитимных JSON и XML файлов.

Wallarm API Security — продукт компании «Wallarm». Функционал направлен точечно на защиту API. Из коробки защищает по OWASP API TOP-10, имеет собственные API парсеры и протекторы JSON/XML.

InfoWatch Attack Killer — под капотом ядро «Wallarm», его API парсеры и механизмы защиты.

Фундаментально это все. Ограничения на точке отказа в любом случае не панацея, необходимо всегда анализировать уязвимые места парсеров и создавать виртуальные заплатки. Для этого во многих WAF реализован функционал создания своих сигнатур. Т.е., помимо того, чтобы просто внедрить WAF в свою инфраструктуру, необходимо постоянно его администрировать совместно с разработчиками веб-приложения.
Хорошо Арсений, а чем защищаться будем?
Давайте разберем тогда какие уязвимости у API?

Когда мы говорим об архитектуре REST чаще всего на ум приходит — JSON (хотя RESTfull API подразумевает под собой необязательно передачу только JSON файла, но тем не менее).

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

JSON уязвимости и их защита

Необходимо пояснить, что, разумеется, большинство атак на API нацелены именно на внутренние движки приложений и в полезной нагрузке (пейлоаде) могут быть любые сигнатуры (SQL инъекции, RCE, XSS, DoS и т.д.). Здесь я опишу именно специфичные уязвимости самих технологий API.

Как ранее упоминалось в статье, одна из атак нацелена на параметры. Как же это происходит?

На примере JSON в рамках официального RFC существует открытое руководство по некоторым темам, таким как обработка повторяющихся ключей и представление чисел. Хотя и в стандарте есть пункт об отказе совместимости, множество пользователей даже не знают о них.

Итак, первая категория уязвимостей JSON:

Неопределенный приоритет повторяющихся ключей.

Что будет если просто продублировать JSON ключ?

Например:

Test = { “bro”:1, “bro”:2}


Какое значение для bro будет итоговым при генерации такого запроса: 1 или 2, или будет ошибка? Согласно официальному стандарту оба варианта возможны (J). Причина, почему так возможно, кроется, как мне кажется, в том, что стандарт заранее сделан таким образом, чтобы не нарушать обратную совместимость с анализаторами предварительной спецификации.

Какая разница 2 или 1, или ошибка? Представим, что у вас сервис с платежной системой, можно покупать объекты для определенного ВАШЕГО аккаунта. Вы хотите купить пачку чипсов и 5 пачек жвачки:

POST /cart/checkout HTTP/1.1
...
Content-Type: application/json
{
    "orderId": 10,
    "paymentInfo": {
        //...
    },
    "shippingInfo": {
        //... 
    },
    "cart": [
        {
            "id": 0,
            "qty": 5
        },
        {
            "id": 1,
            "qty": -1,
            "qty": 1
        }
    ]
}


Где id чипсов — 1, id жвачки — 0 а их количество — qty. Пачка чипсов стоит при этом 100 рублей. При отправке такого запроса к веб-серверу, который использует для анализа JSON стандартную библиотеку Python, будет использоваться приоритет последнего ключа. Такой запрос успешно валидируется данным парсером и сырые данные отправляются дальше в систему генерации платежной квитанции, которая в свою очередь использует Golang для анализа (например, buger/jsonparser).

id, _ := jsonparser.GetInt(value, "id")
qty, _ := jsonparser.GetInt(value, "qty")
total = total + productDB[id]["price"].(int64) * qty;


Он же (Golang) использует приоритет первого ключа. Таким образом, если мы отправим запрос на 5 пачек жвачки стоимостью 500 рублей и чипсов стоимостью 100 рублей с дубликатом ключа, парсер веб-сервера проанализировав запрос (относительно json схемы) примет его как валидный, а данные, отправленные на сервис платежной системы сформируют квитанцию для qty размером -1.

Таким образом, при формировании платежной квитанции нам будет отправлено 5 пачек жвачки и 1 пачка чипсов стоимостью 500 рублей, но с нас возьмут 400 рублей, т.к. при qty -1 для пачки чипсов — их цена в чеке будет вычтена парсером Golang.

Следующий тип атаки — коллизия значений.

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

{"test": 1, "test\[raw \x0d byte]": 2} 
{"test": 1, "test\ud800": 2}
{"test": 1, "test"": 2}
{"test": 1, "te\st": 2} 


Эти строковые значения обычно не устойчивы к нескольким этапам сереализации и десереализации. Так, U+D800 и U+DFFF являются непарными суррогатными кодовыми точками в UTF-16 и пока они могут быть закодированы в UTF-8 байтовую строку, это будет уязвимостью. Предположим, что у нас есть приложение, в котором администратор приложения может создавать роли и пользователей через API. Также пользователи с повышенными правами имеют роль — superuser. Формат создания пользователя такой:

POST /user/create HTTP/1.1
...
Content-Type: application/json
 
{
   "user": "NoviiPolzak", 
   "roles": [
       "superuser"
   ]
}
 
HTTP/1.1 401 Not Authorized
...
Content-Type: application/json
{"Error": "Assignment of internal role 'superuser' is forbidden"}


Как мы видим, при попытке добавления пользователя “NoviiPolzak” с ролью “superuser” сервер отвечает ошибкой 401 и контентом, что доступ запрещен. Теперь самое интересное, с помощью API мы добавим новую роль следующим образом:

POST /role/create HTTP/1.1
...
Content-Type: application/json
 
{
   "name": "superuser\ud888"
}
 
HTTP/1.1 200 OK
...
Content-type: application/json
 
{"result": "OK: Created role 'superuser\ud888'"}


Также создадим еще раз пользователя:

POST /user/create HTTP/1.1
...
Content-Type: application/json
 
{
   "user": "NoviiPolzak", 
   "roles": [
       "superuser\ud888"
   ]
}
 
HTTP/1.1 200 OK
...
Content-Type: application/json
 
{"result": "OK: Created user “NoviiPolzak”}


Таким образом в системе на данный момент создан пользователь NoviiPolzak с ролью superuser\ud888 и при использовании парсера, который сокращает запрещенные кодовые точки система будет принимать просто роль “superuser”. То есть, когда с созданной записью пользователя мы будем обращаться, например, к панели администратора, система даст нам повышенные права.

Как известно, многие библиотеки JSON поддерживают комментирование из JavaScript интерпретатора, например /*,*/. Благодаря этому один запрос может быть обработан двумя разными парсерами по-разному:

obj = {"description": "Коллизия с помощью комментирования ", "test": 2, "extra": /*, "test": 1, "extra2": */}


GoLang распарсит так:

Description: “Коллизия с помощью комментирования”
Test= 2 
Extra= “”


Java JSON-iterator — вот так:

Description:
Extra=/*”
Extra2=”*/”
Test= 1


Выходит, основные уязвимости JSON связаны непосредственно с парсерами данных на стороне приложения во время их кодировки и декодирования. Такие уязвимости достаточно тяжело обнаружить, и они требуют общего подхода к их устранению — как со стороны разработчика, так и от команды ИБ. Ниже я опишу, какие существуют средства защиты API, а сейчас переходим к SOAP.
SOAP уязвимости

SOAP, как известно, в своем фундаменте имеет XML и основные уязвимости вытекают отсюда.

SOAP injection — самая простая, но тяжело детектируемая атака, непосредственно инъекция в теле SOAP запроса.

<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:web=”web:”>
    <soapenv:Header>
    </soapenv:Header>
<soapenv:Body>
        <web1:Login xmlns:web1=”http://ws.example.com/”> 
                <fname>Ivan</fname>
                <lname>Ivanov</lname>
                <password>lmao1337</password>
        </web1:Login>
    </soapenv:Body>
</soapenv:Envelope>


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

Error at line 66: lname == null | loginid
loginid cannot be null


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

<fname>Ivan</fname>
<password>lmao1337</password>
<loginid>1</loginid>


То мы сможем успешно авторизоваться и отправлять запросы на уровне администратора.

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

SOAP Action Spoofing — сам SOAP допускает использование дополнительного заголовка HTTP – SOAPAction. Данный заголовок содержит в себе имя выполняемой операции и служит для оптимизации анализа SOAP целевым приложением. Приложение, основываясь на заголовке, может не производить анализ целого пересылаемого XML.

Допустим, у нас есть приложение, уязвимое к SOAPAction — спуфингу по двум операциям: “createUser” и “deleteAllUsers”. При этом, перед приложением стоит шлюз, который блокирует все запросы на удаление всех пользователей, если они пришли извне (deleteAllUsers), т.е. только прямое подключение к приложению позволяет авторизованному пользователю выполнить удаление.

Пример запроса пользователя на создание нового пользователя:

POST /service HTTP/1.1
Host: myHost
SOAPAction: "createUser"
 
<Envelope>
  <Header />
  <Body>
    <createUser>
      <login>IVANPOPOLAM</login>
      <pwd>secret</pwd>
    </createUser>
  </Body>
</Envelope>


Теперь, если злоумышленник добавит в запрос заголовок SOAPAction:

POST /service HTTP/1.1
Host: myHost
SOAPAction: "deleteAllUsers"
 
<Envelope>
  <Header />
  <Body>
    <createUser>
      <login>IVANPOPOLAM</login>
      <pwd>secret</pwd>
    </createUser>
  </Body>
</Envelope>


Шлюз, стоящий перед приложением пропустит такой запрос, т.к. он смотрит только в тело SOAP и в следствии приложение прочитав заголовок SOAPAction удалит всех пользователей.

XXE — классическая уязвимость. На самом деле XXE эксплуатируется похожим образом, как и XSS, выполняя вредоносный код на стороне сервера, при разведке данных на приложении и т.п.

Заявка на услуги DST

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

Адрес

Ижевск, ул. Воткинское шоссе, д. 170 Е, Технопарк Нобель, офис 1117

8 495 1985800
Заказать звонок

Режим работы: Пн-Пт 10:00-19:00

info@dstglobal.ru

Задать вопрос по почте

Укажите ваше имя
Укажите ваше email
Укажите ваше телефон