Б значит не Безумие, а Безопасность: часть 1
Кибербезопасность сейчас в тренде, безопасность инфраструктуры и ПО, располагаемого в ней, тоже. В рамках серии статей хотелось бы поговорить об этом и поделиться нашим опытом.
В первой части я расскажу про проект, который недавно пришел к нам с таким ТЗ:
1. Замкнутый контур;
2. Отсутствие CVE во всех используемых продуктах;
3. Контроль безопасности уже имеющейся инфраструктуры;
4. Контроль доступа до среды;
5. Автоматизация процессов.
Давайте посмотрим, что из этого вышло.
Приглашаю вас подписаться на наш блог Хабр, TG-канал DevOps FM и познакомиться с YouTube — мы всегда рады новым друзьям :)
Глава 1: Окружение — это начало
Когда заказчик говорит, что хочет безопасную инфраструктуру, то первое, что приходит в голову любому архитектору — это замкнутый контур. Звучит красиво и легко, но способов реализации этого условия бесконечно много. В процессе осознания всех процессов от входящего пользовательского трафика до деплоя новых релизов, возникает большое количество вопросов, которые требуют дальнейшего research по каждой теме.
Перво-наперво необходимо определиться, где будет располагаться инфраструктура. Выбора как всегда имеется два:
Создавать свою собственную инфраструктуру на имеющемся железе и стоящем у вашего лучшего сотрудника в подвале дома;
Использовать ДЦ, которое предлагает широкий спектр услуг.
Первый вариант реализации предоставляет ощутимо в разы больше возможностей в плане контроля вашей инфраструктуры, но чем больше сила, тем больше ответственность. На обслуживание такого контура требуются дополнительные ресурсы, а также замена и обновление оборудования возлагается на ваши плечи. Я уже не говорю о том, что на ваши плечи также ляжет реагирование 24/7 в случае недоступности серверов из-за поломок оборудования. Так как не каждый бизнес на этапе роста желает сталкиваться с подобными проблемами, то всё чаще выбирается второй вариант — использование ДЦ с имеющимися сертификатами соответствия требованиям безопасности. Как правило вся эта информация предоставляется на самом сайте ДЦ и является своего рода его рекламной карточкой:
Какие плюсы из этого можно извлечь?
Вся ответственность, возлагаемая на вас в рамках первого пункта, переходит к ДЦ, но и тут нельзя забывать про важные минусы, как пример у облака должен быть отличный roadmap, которые он обязуется не только красиво расписывать на главной странице сайта, но и исполнять. Примером подобного поведения может быть регулярное обновление исходных образов, из которых поднимается ваша ВМ — это позволяет на постоянной основе обновлять версию вашего ядра и поможет избежать большого количества актуальных уязвимостей.
После обсуждения с клиентом различных плюсов и минусов, способов реализации, разумеется мы пришли к согласию: наш путь будет лежать через ДЦ Яндекса. Пришло время рисовать схему. Зная предпочтения клиента — что на стартовом этапе мы будем реализовывать тестовое развертывание нового продукта на виртуальных машинах, предлагаемых в Yandex Compute Cloud — результат получился следующим:
И тут стоит отметить важный момент: если ваши приложения, располагаемые на ВМ, не взаимодействуют со сторонними сервисами или партнёрами, то мы перекрываем полностью доступ по сети через предлагаемые для нас Security group, если картина обратная, то необходимо настраивать целевые правила для доступа к этим сервисам по destination ip. В итоге получаем следующую картину:
Входящий трафик на наши сервера разрешён только на определённые порты backend, открытые для балансировщика;
Исходящий трафик для наших серверов запрещен полностью.
Первый разумный вопрос, возникающий у всех: «А как с этим работать? Как деплоить приложения? Как обновлять или ставить пакеты на сервера?»
Ответом на все эти вопросы может быть самое простое решение. Нам нужен менеджер репозиториев. На ум приходит самый популярный опенсорсный продукт Nexus от компании Sonatype. Развернем его на отдельной ВМ с доступом в интернет и настроим ряд проксируемых репозиториев для пакетов. Вариантов реализации также несколько: ручное развертывание self hosted или docker, использование ansible ролей для автоматизации этих процессов. Ранее мы выбрали ОС Debian 11, поэтому перейдём к настройке официального репозитория для извлечения и установки deb пакетов.
И не забываем произвести настройку репозитория Debian, содержащего обновления безопасности.
Что в результате мы имеем?
На выходе, после описанных выше настроек, мы получаем ключи для добавления репозиториев и площадку, куда будут идти запросы с наших изолированных серверов. По такому же принципу можно произвести добавление всех минимально необходимых репозиториев для разворачивания postgres, ceph, mysql, nginx и т.д.
Этот вопрос можно считать закрытым, остается вопрос к процессу деплоя, если все наши приложения контейнеризированы, то их также нужно хранить в registry. Для этого нам понадобится ряд сущностей в Nexus — сам репозиторий, политики для очистки репозиториев и пользователь с правами на push и pull образов.
Но на этом моменте возникает проблема которая имеет как стандартное, так и нестандартное решение. Внутренние политики очистки registry Nexus имеют весьма сомнительную механику. Принцип действия очистки основан на двух правилах:
Удалять все образы опубликованные в Nexus старше n-дней и тэг которых попадает под регулярные выражения.
Удалять образы, которые не были загружены в последние n-дней и тэг которых попадает под регулярные выражения.
Если ваша концепция build образов построена на отсутствии использования latest тэга, то эти политики вам могут не подойти, так как рано или поздно случится ситуация, в которой образ, используемый в текущем проде, будет удален как с сервера, так и из registry — получается ваш контейнер упадет?
Наверняка кто-то уже сказал:
А что мешает использовать latest tag при релизе образа, навешивая на каждый уникальный билд два тэга? Один из них отличительный как пример CI_COMMIT_SHA, а второй latest.
Ответ на этот вопрос может быть весьма банальным. В таком случае необходимо при дальнейшем использовании указывать оркестратору политику регулярного извлечения вашего образа из Nexus при каждом перезапуске. Если вы используете alpine или slim, то это радость, но если, например, ваш front содержит большое количество node.js библиотек, то избежать больших размеров слоёв у вас не получится и это уже приведет к увеличению времени восстановления сервиса после reboot.
Многих подобный SLA устраивает и уменьшить его помогает использование нескольких реплик, расположенных в разных зонах доступности, а также применение проверок backend на уровне балансировщика, но если ваш проект чувствителен к малейшему простою, то можно либо использовать сторонние «костыли» для ротации образов, либо использовать в качестве registry другое ПО.
Но как мы все прекрасно знаем, нам нужно самое оптимальное и рациональное решение вопроса. Каждый понимает, что если использовать кастомное решение, то рано или поздно про него могут забыть даже при наличии документации и это приведёт к новому инциденту.
Так что же мы использовали?
Gitlab — наше всё и он имеет в себе registry, которое содержит логичные и привычные политики очистки, содержащие логику хранения последних 10 тэгов при очистке, попадающих под регулярное выражение.
Как выглядит наша инфраструктура вновь и получается ли у нас реализовать ТЗ?
Входящий трафик на наши сервера разрешён только на определённые порты backend, открытые для балансировщика и для деплоя раннеров по локальной сети;
Исходящий трафик разрешён по локальной сети до сервера с Gitlab, где у нас располагается хранилище образов, и до Nexus, где у нас располагаются репозитории с пакетами.
Глава 2: Common Vulnerabilities and Exposures или как знания, которые уже имеются, надо применять
CVE или база данных общеизвестных уязвимостей информационной безопасности. Здесь собрана информация о возможных проблемах продуктов, используемых вами, и надо всего лишь следить за актуальностью данных. Для решения подобной задачи имеется большое количество инструментов. Один из таких вариантов — Trivy, продукт Aqua Security.
Вариантов его установки существует два: использование готового образа с Trivy с последующим монтированием хостовой части в контейнер для сканирования или же инсталляция пакетов из общедоступных репозиториев Aqua Security.
apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | tee -a /etc/apt/sources.list.d/trivy.list
apt-get update sudo apt-get install trivy
Чем он хорош и какие проблемы могут быть при его эксплуатации?
Основные его преимущества — это регулярные релизы и обновление функционала, использование актуальной базы для поиска возможных CVE в вашей инфраструктуре, вариативность запуска сканирований:
Сканирование файловой системы;
Сканирование образов;
Сканирование репозитория с кодом;
Сканирование kubernetes;
Сканирование конфиг файлов;
Сканирование snapshot.
Минусы имеются тоже — необходимость извлечения актуальной БД с данными для сканирования. Так как у нас замкнутый контур, это весьма проблематично и либо мы разрешаем исходящий трафик до их репозитория ghcr.io/aquasecurity/trivy-db, который в перспективе может измениться, либо скачиваем БД на сервере открытого контура и вшиваем в образ. В таком случае необходимо будет по крону с завидным постоянством производить подобные обновления образа и, как бы это сомнительно не звучало, в наших условиях это единственно верный путь.
Глава 3: Сохранение безопасности важнее создания безопасности
После того, как все возможные уязвимости в пакетах устранены в нашей готовой инфраструктуре, нужно решить вопрос, как поддерживать и следить за тем, что имеем. В этом случае лучше всего подходят два ПО, которые можно и нужно интегрировать. В первую очередь рекомендуется использовать Wazuh — это SIEM система (Security information and event management). Wazuh своего род хлеб каждого сотрудника кибербезопасности и его дальнейшая эксплуатация сможет вас приятно порадовать.
Принцип его работы выглядит следующим образом. Агенты, расположенные на серверах согласно настройкам конфигурации, сканируют стандартные пути с логами. К примеру — /var/log/auth.log, и отправляют события на сервер Wazuh, который их декодирует, анализирует и передаёт в компонент «Wazuh indexer», где события индексируются, после чего появляется возможность выполнять полнотекстовый поиск средствами OpenSearch. По написанным заранее правилам можно производить инициацию событий мониторинга с последующем информированием заинтересованных лиц, с целью разбора инцидента.
Сейчас не будем углубляться в детальные способы установки и настройки Wazuh (это совсем отдельная тема не малых размеров), а перейдём к более важному вопросу: как предоставить доступ к закрытому контуру системным администраторам и разработке? Замечу, что в перспективе необходимо контролировать эти доступы и иметь возможности гибко отозвать привилегии.
Ранее в других наших статьях уже упоминался сервис Freeipa, которай имеет возможность централизованно управлять аутентификацией пользователей и устанавливать политики доступа для них. Этот вариант для нас идеален и остается лишь предоставить доступ пользователю в сеть с помощью того же OpenVPN, а значит наша схема приобретает следующий вид:
И тут хочется остановиться чуть подробнее. При выдаче доступов до сервера всегда стоит ряд задач:
Предоставлять ограниченный доступ сотрудникам;
Возможность быстро отозвать доступ сотрудника;
Гибкость управления.
Весь перечень этих задач можно решить, используя такие сущности в freeipa, как группы пользователей, группы серверов и правила HBAC. Создавая правила HBAC, необходимо закрепить группу серверов, содержащую наш список хостов и группу пользователей
Предоставление возможностей группе пользователей совершать ssh подключение к серверу.
Основное преимущество подобного подхода — разделение команд разработчиков и администраторов на группы пользователей и использование вложенностей групп, как в рамках нашей основной группы пользователей allow-users-from-servers-yandex-cloud, так и в рамках группы серверов.
Глава 4: Масштабная проблема требует масштабного решения
Зная схему инфраструктуры и понимая необходимый список технологий, остается еще одна значимая проблема. Если есть понимание, что бизнес будет расти и дальше, то логично предположить, что инфраструктура также будет развиваться быстрыми темпами. Если процесс настройки 3-х серверов по всем вышеописанным требованиям, может занимать до 8 часов, то как быть, когда серверов станет 20, 30, 100? Выход из этой ситуации только один и он заключается в автоматизации и шаблонизации всех процессов.
Когда говоришь об автоматизации, первое, что приходит на ум — это ansible и это правильный ответ. Но важно помнить — «красота в простоте». Решение должно быть элегантным и любой системный администратор должен уметь с легкостью применять ansible роли, без детального погружения в их конструктивные особенности применения.
AWX — это проект сообщества с открытым исходным кодом, спонсируемый Red Hat, который позволяет пользователям контролировать использование Ansible ролей в своей инфраструктуре.
Отсутствие CVE во всех используемых продуктах;
Контроль безопасности уже имеющейся инфраструктуры;
Контроль доступа до среды;
Автоматизация процессов.
Самое сложное или самое простое — это разворачивание AWX. Осуществить данный процесс можно либо с помощью использования helm chart-а, но для этого необходимо иметь k8s или же достаточно обычного сервера и гайда установки.
После несложных манипуляций необходимо понять, что мы имеем?
Подключение LDAP авторизации для предоставления доступов пользователям из нашей Freeipa;
WEB dashboard и нативное использование функционала ansible;
Возможность извлекать и хранить необходимые нам ansible role в git системе или локально;
Возможность хранения кредов авторизации по ssh для процессов AWX в хранилище;
История всех job в рамках которых отработали наши роли, а также история output выводов работы ролей;
Создание собственных inventory, включающих в себя определённые хосты и их переменные;
Но самое главное преимущество — это workflow.
Если вы уже произвели добавление хостов в ваши inventory и имеете заранее готовые ansible, то из них можно создать готовые templates, из которых в последующем получаются цельные workflow ролей, выполняющихся поэтапно.
Из этого можно сделать следующий вывод: после инсталляции AWX, написания ряда необходимых нам ролей и настройки сети наша схема приобретает следующий вид:
Глава 5: Идеология, концепция и результат
«Так что же у нас получается?» — это вопрос, который задаёт себе каждый человек в конце своей работы, но не каждый может дать на него ответ. Благо есть ТЗ :)
У нас получилось реализовать концепцию замкнутого контура, вследствии чего мы избежали нежелательного трафика извне. Обновили все актуальные CVE в рамках пакетов, что позволило закрыть уязвимости на случай проникновения нежеланных лиц в окружения инфраструктуры. Регулярный контроль безопасности — это лишь полёт фантазии, способов его реализации бесконечно множество, но в нашем случае был использован Wazuh с алёртингом и последующим разбором всех возможных инцидентов на основании собранных логов. Предоставление доступов — это как pet проект, каждый это делает и в будущем об этом забывает, но freeipa в нашем случае помогает решить этот вопрос при помощи наглядных разграничений на уровне групп пользователей и политик HBAC. Ну и для тех, кто читает как настоящий литературный критик, первые 3 абзаца и последние 3 абзаца, повторюсь. Проблему автоматизации и подготовку к перспективам развития нашей инфраструктуры также удалось победить и закрыть через AWX.
Так получается задача выполнена?
P.S. Пояснение слова «актуальные CVE»
Актуальные CVE — это те уязвимости, которые были обнаружены и исправление которых возможно обновлением версий пакетов. Речь в данном случае не касается уязвимостей обнаруженных вчера. Идеология «отсутствие CVE = отсутствие проблем» — это та грань, к которой необходимо тянуться, но достичь её невозможно, как и зарплатных требований востребованного инженера после оффера.
Замкнутый контур;
Отсутствие CVE во всех используемых продуктах;
Контроль безопасности уже имеющейся инфраструктуры;
Контроль доступа до среды;
Автоматизация процессов.
Как бы не так. Даже если требования заказчика выполнены, это не повод идти пить кофе и спать спокойно, ведь хорошая инфраструктура — это безопасная инфраструктура, а повышение безопасности процесс бесконечный. Понимание этой концепции говорит о том, что вы переживаете как за свой бизнес, так и за своих текущих или потенциальных клиентов. Не рекомендуется Нельзя заниматься внедрением КБ процессов уже на рабочей инфраструктуре, так как в лучшем случае это грозит лишь простоем или излишними трудозатратами, а в худшем — это уже совсем другая история.
Но как быть, если ваша инфраструктура располагается в рамках kubernetes оркестратора? Применимы ли данные подходы для организации безопасности? Как быть, если вы используете managed решение? К сожалению, ответы на эти вопросы плавно перетекают в объем книги, но можно попробовать описать это в виде серии статей.
Пожалуй второй вариант проще, а это означает лишь одно »to be continued…»