Девопс и безопасность: интервью с Сетом Варго и Лиз Райс +14


Контейнерами сегодня никого не удивишь. Удивишь вопросом про безопасность контейнеров. Особенно интересно спрашивать об этом коллег, которые используют контейнеры и микросервисы в продакшне на полном серьёзе: часто вижу удивленные лица и недоуменный вопрос, мол, «Что, зачем это»? Получается, что про технологию мы уже знаем (да и как тут не знать: кажется, что скоро даже школьники на уроках технологии будут всем классом строить кластер Kubernetes), а вот защищать составные части её — пока еще не научились. Быть может, просто некому было учить.

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



Участники:


Сет Варго работает Developer Advocate в Google. Ранее он работал в HashiCorp, Chef Software, CustomInk и нескольких других стартапах в Питтсбурге. Он является автором Learning Chef и ратует за сокращение неравенства в технологиях.



Лиз Райс — технический евангелист в компании Aqua Security, занимающейся безопасностью развертывания приложений в облачных средах и контейнерными решения для энтерпрайза. Лиз — весьма известный в сообществе человек, председатель KubeСon-ов.



Олег Чирухин, редакция JUG.ru Group




Давайте начнём с вопроса, который определит наш дальнейший разговор. Что DevOps значит для вас? Чем он отличается от менее известного SRE?
Например, на предыдущей работе, когда меня просили «реализовать DevOps», я просто шел по оглавлению SRE Book, хватал идеи и применял их одну за одной. Ну или по крайней мере старался доносить их до окружающих. Что скажете — это правильный подход?




Если говорить о DevOps, речь идет об уходе от пропасти, от разрыва, который обычно находился между процессами разработки кода (Dev) и его последующим поддержанием в работе (Ops). Представим, что перед нами высокая стена, по одну сторону которой сидят разработчики, он создают код, перебрасывают его через стену. С другой стороны стены находятся люди, занимающиеся поддержкой. Они ловят переброшенное приложение и приступают к запуску и сопровождению. И вот эти люди знают подробности, нужные при эксплуатации. Например, какие порты и где будут выделены и открыты.

Вместо того, чтобы у вас были две отдельные группы людей с различными интересами, хочется сделать так, чтобы они общались друг с другом, решали, что делать дальше, вместе определяли, какие цели они совместно постараются достичь в течение рабочего дня. Так что DevOps — это изменение культуры общения, которое помогает коллегам в разных технических командах работать на общее благо: создавать ценности для бизнеса, разворачивать программное обеспечение, поддерживать его в работе. Я думаю, что это очень важные изменения, и они несут с собой сопутствующие новые инструменты: если у вас нет культуры общения, то не так много смысла внедрять те же процессы CI/CD.




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

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




По-вашему, правилен ли термин «DevOps engineer»? Его можно каким-то образом заменить?




Я лично не считаю, что существует понятие «инженер DevOps». Вы можете прочитать подробнее в моей статье «10 мифов DevOps», что «DevOps» на самом деле представляет собой идеологию: больше коммуникаций и сотрудничества между разными, но сильно связанными по сути организационными подразделениями. Хотя сегодня это выглядит вполне здраво и привычно, поначалу такой подход вызывал как похвалу, так и резкую критику. С тех пор многие организации, включая Etsy, Facebook и Flick, на удивление успешно внедрили принципы DevOps.

Так вот, ни одна из этих организаций не нанимала «инженеров DevOps». Успехи внедрения можно отнести к появившемуся внутреннему сотрудничеству команд и готовности изменить свои существующие процессы и процедуры ради достижения общей цели. Роль так называемого «инженера DevOps» заключалась в поощрении совместной работы между группами и в обеспечении того, чтобы организационные подразделения регулярно обменивались идеями и целями. Собственно, у нас и сегодня уже есть эти люди, и мы называем их «менеджерами».




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

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

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




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




Смотря в чем цель. Многие люди и компании, с которыми я общаюсь в рамках консультаций, приходят к нам и говорят, что хотят развернуть Kubernetes и контейнеры. Но прежде чем говорить о технологиях, нужно понять, ради чего они пытаются сделать подобные шаги. И оказывается, что ожидаемая польза от изменений часто сводится к желанию быть более гибкими. Отсюда движение в сторону того, чтобы технические команды могли релизить результаты своего труда быстрее, что-то такое, объясняемое «на пальцах». В этой точке полезно перевести разговор в сторону того, что проблему отсутствия культуры (привычки, если хотите) общения между членами команды не поможет решить никакое «закидывание» новыми технологиями, что общение — это важнейший ресурс.

Кроме того, поскольку я часто оказываюсь вовлечена и в вопросы улучшения безопасности решений, то наш разговор смещается в сторону «Dev-**Sec**-Ops», и оказывается, что построение системы следует вести так, чтобы о безопасности начинали заботиться на самых ранних стадиях процессов, а не просто подходили к вопросу по старинке: сначала пишем код приложения, затем его разворачиваем, затем передаем службе эксплуатации, и только в самом конце кто-то начинает думать о безопасности запущенного.

На самом деле многие вопросы безопасности дешевле и проще решить в начале процесса, однако нужно с самого начала закладывать в проект много моментов. Например, если вы собираетесь работать с контейнерами, нужно побеспокоиться, чтобы образы собирались достаточно безопасным образом. Возможно, будет полезно сканировать их на наличие уязвимостей, чтобы хотя бы избежать развертывания ПО с уже известными проблемами безопасности. Возможно, вы постараетесь настроить контейнеры так, чтобы ПО в них запускалось по умолчанию не от root-а (как часто для простоты, без особой необходимости, делают при сборке контейнеров). Если предпринять подобные шаги, в итоге вы получите повышение безопасности вашего приложения, и можно будет, в контексте всего этого DevOps, говорить еще и о культуре SecOps.




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




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

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




Лично я считаю, что каждый инженер-программист должен иметь как минимум базовое понимание безопасности. Такие вещи, как подходы OWASP (Open Web Application Security Project), выручают, но в конечном итоге инженеры должны заниматься самообразованием. Вряд ли каждый инженер имеет степень доктора наук по криптографии, но, если мы хотим, чтобы наши коллеги серьезно относились к безопасности, мы должны облегчить им принятие правильных решений. Именно в этом могут помочь инструменты, такие как Vault – а команды по безопасности и профессионалы могут принимать решения и обеспечивать «безопасность как API».




Если я правильно понимаю, есть тенденция к превращению всего в код. Everything As Code. Инфраструктура как код, процессы как код, код как код. Каковы последствия?




Прежде чем говорить о последствиях, мы должны поговорить о преимуществах. Код существует очень давно. Приложения всегда были «кодом», и за это время была создана обширная экосистема инструментов и процессов для поддержки и улучшения процесса разработки приложений (CI/CD, линтинг, инструменты для совместной разработки и пр.). Описав инфраструктуру как код, процессы как код, безопасность как код, мы можем использовать эту же экосистему, причем дополнительно ничего не платя за это. Вы можете совместно разрабатывать изменения инфраструктуры, делать ревью политик и т.п. Вы можете тестировать изменения в инфраструктуре перед их развертыванием. Это лишь некоторые из преимуществ, которые возникают при переводе чего-то в код.

Я думаю, что самые большие последствия — это время и сложность. Когда вы работаете с чем-то «как с кодом» (например, через Terraform, Vault, CloudFormation, Deployment Manager и т.д.), иногда приходится натыкаться на несоответствия между тем, что записано в коде, и тем, что фактически происходит в облаке. Моделирование сложных отношений порой трудно произвести наглядно, особенно с учетом масштабирования. Кроме того, мы можем столкнуться и с неточностью абстракций — скажем, скрипт, работающий через API, может воспринимать текущее положение дел не так, как оно отображается пользователям через веб-интерфейс. Однако с течением времени сложность уменьшается, а гибкость возвращается.




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




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

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




Представим, что обычная команда разработчиков создаёт веб-приложение, размещает его в кластере Kubernetes. Как мы можем убедиться, что приложение защищено? Нанять хакера или специалиста «blackhat», который пытается найти слабые места в безопасности, или есть какие-то менее сложные способы?




Мы в Aqua Security не так давно выпустили инструмент с открытым исходным кодом под названием «kube-hunter». Он способен проводить тестирование Kubernetes на возможность взлома или проникновения – делая довольно простое тестирование. Вы можете взять этот инструмент и протестировать свой собственный кластер, и почти наверняка узнаете что-то интересное для себя, особенно если ваша инсталляция строилась еще на базе старой версии Kubernetes, где по умолчанию использовались менее безопасные значения настроек – у вас вполне могут быть, например, открытые порты.

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

Мы хотим, чтобы hunter помог обычным администраторам Kubernеtes лучше понять, есть ли проблемы настроек в их развертывании, поэтому он разработан исключительно для Kubernetes и сообщает о найденном на языке, понятном пользователям Kubernetes. Так что мы сообщим вам, что у вас открыт не какой-нибудь порт 6443, а, скажем, доступ вот к этому конкретному компоненту Kubernetes. Таким образом, людям легче определить, считать ли найденное проблемой с конфигурацией, ослабляющей безопасность, и стоит ли немедленно приступить к её устранению — притом не являясь экспертом по безопасности Kubernetes. Мы хотим попытаться сделать эти проверки доступными в любой момент, без необходимости привлечения сторонних экспертов.




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




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

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

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

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




И как ловить аномалии? Использовать что-то вроде антивирусных эвристик, нейронных сетей?




В течение жизненного цикла программного обеспечения мы используем различные инструменты безопасности. В данном случае это runtime enforcer — компонент, который знает, какой контейнер с каким имиджем мы запускаем и как он должен себя вести. Он «понимает», что, например, внутри будет работать nginx, поэтому загружает преднастроенный профиль для этого ПО и начинает отслеживать действия, которых от nginx нельзя ожидать. Ему можно также просто указать на образ, для которого профиля не задано, затем включить режим обучения и таким образом получить картину «нормального» поведения, на фоне которого уже можно будет заметить аномалии. Плюс он контролирует, какие исполняемые файлы используют сетевой трафик, какие идентификаторы пользователей используются внутри отдельных контейнеров. Работа такого компонента управления и защиты выглядит просто потрясающе: ты вдруг понимаешь, что машина сама следит за необычными моментами в поведении и реагирует сразу, как только требуется вмешательство.




Давайте поговорим немного о другом. Serverless хайпанул на полную мощь, но очень мало специалистов, которые имеют глубокое понимание этих технологий. У всех почти нулевой опыт использования его в продакшене. Что не так с идеей работы «без сервера»? Что мы должны понимать, чтобы начать с пользой применять подобные подходы?




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

Одна из самых больших сложностей с serverless – «как сделать нужное локально». Обычным подходом является связать serverless-приложения при помощи pub/sub, облачного хранилища, Redis и некоторого количества кода для склейки этого всего воедино. Трудно проверить эти изменения в любом месте, кроме продакшна, из-за жесткой связи между этими разными (облачными) компонентами.




Шумиха вокруг severless-подхода к построению сервисов довольно необычна, и это очень интересно. Для компаний, которые используют сервера под серьезной, настоящей нагрузкой, перевести все приложения на serverless-модель будет затруднительно. Но кое-что перевести будет можно. Безопасность контейнеров строится на понимании используемого ПО, на проверках уязвимостей, на постоянном контроле, что это ПО ведёт себя ожидаемым образом. Эти же основные принципы применимы и к serverless, и кое-что мы увидим уже в ближайшем будущем.




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




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

Вспомните, например, самый распространенный на сегодня формат файла конфигурации: YAML. Вы знаете, что нельзя запустить Kubernetes или приложение в Kubernetes, без написания полдюжины файлов YAML. Ходят шутки, что для запуска простого приложения нужно написать минимум 30 000 строк YAML. Так вот, я думаю, что вскоре мы увидим инструменты, которые помогут нам на самом деле не писать эти 30 000 строк YAML, а просто сделают все сами, а им лишь дадим им код, который нужно запустить.





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




Я работаю с Kubernetes последние года два и соглашусь, что он довольно сложен для понимания. Есть много разных видов ресурсов, типов объектов и другого, в чем нужно хорошо и глубоко разбираться, понимая, почему что-то сделано так, а не иначе. Кроме того, используется декларативный подход, когда ваш YAML-файл описывает то, что вы хотели бы достичь, а затем Kubernetes будет пытаться поддерживать состояние системы в соответствии с этим описанием. Это очень удобно для самовосстановления сервисов, но принять такой подход поначалу трудно. Нужно научиться понимать, как будет вести себя вся система.

Еще одной причиной, по которой изучение Kubernetes оказывается довольно сложным делом — то, что он постоянно развивается. За последние два года он сильно изменился и стал намного более стабильным. Кстати, Kubernetes наконец получил в CNCF статус graduated, что, в основном, означает, что продукт стал стабильным, что CNCF рекомендует компаниям его использовать.




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




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





Кстати, как вы видите будущее Kubernetes, например, на ближайшие три года?




Хороший вопрос. На самом деле, нужно смотреть не только на него, но и на стремительно растущий ландшафт компонентов и проектов вокруг, которые создают надежную платформу для развертывания облачных продуктов, включая реализацию таких вещей как безопасность. Как отличный пример – это Istio (и другие варианты service mesh), он недавно подошел к версии 1.0. Я думаю, это хороший пример действительно мощного инструмента, который добавляет уровень безопасности и позволяет делать понятные и нужные вещи, вроде развертывания «канарейки».

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




Если бы у вас был шанс дать читателям только один совет, что бы вы им сказали?




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




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




Уже в следующее воскресенье на конференции DevOops 2018 Сет выступит с докладом «Modern security with microservices and the cloud», а Лиз представит «Practical steps for securing your container deployment». Билеты можно приобрести на официальном сайте.




К сожалению, не доступен сервер mySQL