Платформа Cloudflare — это критически важная система для самой компании Cloudflare. Мы являемся нашим собственным «Нулевым Клиентом» (Customer Zero) — используя наши же продукты для защиты и оптимизации наших собственных сервисов.
В нашем подразделении безопасности специальная команда Customer Zero использует свою уникальную позицию, чтобы обеспечить постоянную обратную связь высокого качества с продуктом и инженерными командами, что способствует непрерывному совершенствованию наших продуктов. И мы делаем это в глобальном масштабе — где одна неверная конфигурация может распространиться по нашей граничной сети за секунды и привести к непредвиденным последствиям. Если вы когда-либо колебались перед внесением изменений в продуктивную среду, покрываясь потом от мысли, что одна небольшая ошибка может заблокировать доступ всем сотрудникам к критически важному приложению или вывести из строя сервис, — вам знакомо это чувство. Риск непредвиденных последствий реален, и он не дает нам спать по ночам.
Это создает интересную задачу: как мы можем гарантировать, что сотни внутренних продуктовых учетных записей Cloudflare защищены одинаково, минимизируя при этом человеческий фактор?
Хотя панель управления Cloudflare отлично подходит для наблюдения и аналитики, ручной просмотр сотен аккаунтов для проверки идентичности настроек безопасности — верный путь к ошибкам. Чтобы сохранить рассудок и безопасность, мы перестали относиться к нашим конфигурациям как к ручной задаче «укажи и щелкни» и начали относиться к ним как к коду. Мы приняли принципы «shift left» (сдвига влево), чтобы перенести проверки безопасности на самые ранние стадии разработки.
Для нас это не была абстрактная корпоративная цель. Это был механизм выживания, позволяющий выявлять ошибки до того, как они приведут к инциденту, и это потребовало фундаментальных изменений в нашей архитектуре управления.
Что для нас означает «Shift Left»
«Сдвиг влево» (Shift left) означает перенос этапов валидации на более ранние стадии жизненного цикла разработки ПО (SDLC). На практике это означает интеграцию тестирования, аудитов безопасности и проверок соответствия политикам непосредственно в конвейер непрерывной интеграции и непрерывного развертывания (CI/CD). Выявляя проблемы или неверные конфигурации на стадии запроса на слияние (merge request), мы находим проблемы в тот момент, когда стоимость их исправления наименьшая, а не после развертывания.
Когда мы думаем о применении принципов shift left в Cloudflare, выделяются четыре ключевых принципа:
-
Единообразие: Конфигурации должны легко копироваться и повторно использоваться в разных учетных записях.
-
Масштабируемость: Крупные изменения могут быстро применяться к множеству учетных записей.
-
Наблюдаемость: Конфигурации должны быть доступны для аудита кем угодно на предмет текущего состояния, точности и безопасности.
-
Управление: Защитные механизмы должны быть проактивными — применяться до развертывания, чтобы избежать инцидентов.
Операционная модель IaC для продуктивной среды
Для поддержки этой модели мы перевели все продуктовые учетные записи на управление с помощью «Инфраструктуры как кода» (IaC). Каждое изменение отслеживается, привязывается к пользователю, коммиту и внутренней задаче. Команды по-прежнему используют панель управления для аналитики, но все критически важные изменения в продуктивной среде выполняются в коде.
Эта модель гарантирует, что каждое изменение проходит проверку коллегами, а политики, хотя и устанавливаются командой безопасности, реализуются самими инженерными командами-владельцами.
Эта система основана на двух основных технологиях: Terraform и собственном конвейере CI/CD.
Наш корпоративный стек IaC
Мы выбрали Terraform из-за его зрелой экосистемы с открытым исходным кодом, сильной поддержки сообщества и глубокой интеграции с инструментами «Политики как кода». Более того, внутреннее использование провайдера Terraform для Cloudflare позволяет нам активно тестировать этот опыт на себе (dogfooding) и улучшать его для наших клиентов.
Для управления масштабом в сотни учетных записей и около 30 запросов на слияние в день наш конвейер CI/CD работает на Atlantis, интегрированном с GitLab. Мы также используем собственную программу на Go, tfstate-butler, которая выступает в роли брокера для безопасного хранения файлов состояния (state files).
tfstate-butler работает как HTTP-бэкенд для Terraform. Основным драйвером проектирования была безопасность: он гарантирует использование уникальных ключей шифрования для каждого файла состояния, чтобы ограничить масштаб последствий в случае потенциальной компрометации.
Все внутренние конфигурации учетных записей определены в централизованном монорепозитории. Отдельные команды владеют и развертывают свои специфические конфигурации и являются назначенными владельцами кода для своих разделов в этом централизованном репозитории, что обеспечивает подотчетность. Чтобы узнать больше об этой конфигурации, ознакомьтесь с материалом Как Cloudflare использует Terraform для управления Cloudflare.
Диаграмма потока данных «Инфраструктура как код»
Базовые уровни и «Политики как код»
Вся стратегия shift left зависит от установления сильного базового уровня безопасности для всех внутренних продуктовых учетных записей Cloudflare. Базовый уровень — это набор политик безопасности, определенных в коде (Policy as Code). Этот базовый уровень — не просто набор рекомендаций, а обязательная конфигурация безопасности, которую мы применяем на всей платформе — например, максимальная длительность сессии, обязательные логи, определенные конфигурации WAF и т.д.
В этой системе обеспечение соблюдения политик переходит от ручных аудитов к автоматизированным проверкам. Мы используем фреймворк Open Policy Agent (OPA) и его язык политик Rego через функцию проверки политик Atlantis Conftest.
Определение политик в виде кода
Политики Rego определяют конкретные требования безопасности, составляющие базовый уровень для всех ресурсов провайдера Cloudflare. В настоящее время мы поддерживаем около 50 политик.
Например, вот политика Rego, которая проверяет, что в политике доступа разрешено использовать только email-адреса @cloudflare.com:
# проверка, что не используются email не из cloudflare
warn contains reason if {
r := tfplan.resource_changes[_]
r.mode == "managed"
r.type == "cloudflare_access_policy"
include := r.change.after.include[_]
email_address := include.email[_]
not endswith(email_address, "@cloudflare.com")
reason := sprintf("%-40s :: разрешены только email @cloudflare.com", [r.address])
}
warn contains reason if {
r := tfplan.resource_changes[_]
r.mode == "managed"
r.type == "cloudflare_access_policy"
require := r.change.after.require[_]
email_address := require.email[_]
not endswith(email_address, "@cloudflare.com")
reason := sprintf("%-40s :: разрешены только email @cloudflare.com", [r.address])
}
Применение базового уровня
Проверка политик выполняется для каждого запроса на слияние (MR), гарантируя соответствие конфигураций до развертывания. Результаты проверки политик отображаются непосредственно в ветке комментариев к MR в GitLab.
Применение политик работает в двух режимах:
-
Предупреждение: Оставляет комментарий в MR, но разрешает слияние.
-
Запрет: Полностью блокирует развертывание.
Если проверка политик определяет, что конфигурация в MR отклоняется от базового уровня, в выводе будет указано, какие ресурсы не соответствуют требованиям.
В примере ниже показан результат проверки политик, выявившей 3 несоответствия в запросе на слияние:
WARN - cloudflare_zero_trust_access_application.app_saas_xxx :: "session_duration" должна быть меньше или равна 10ч
WARN - cloudflare_zero_trust_access_application.app_saas_xxx_pay_per_crawl :: "session_duration" должна быть меньше или равна 10ч
WARN - cloudflare_zero_trust_access_application.app_saas_ms :: у вас должен быть хотя бы один оператор require с auth_method = "swk"
41 тест, 38 пройдено, 3 предупреждения, 0 сбоев, 0 исключений
Обработка исключений из политик
Мы понимаем, что исключения необходимы, но они должны управляться с той же строгостью, что и сама политика. Когда команде требуется исключение, она отправляет запрос через Jira.
После одобрения командой Customer Zero исключение оформляется путем создания pull request в центральный репозиторий exceptions.rego. Исключения могут быть сделаны на разных уровнях:
-
Учетная запись: Исключить account_x из политики_y.
-
Категория ресурсов: Исключить все ресурсы_a в account_x из политики_y.
-
Конкретный ресурс: Исключить ресурс_a_1 в account_x из политики_y.
В этом примере показано исключение для длительности сессии пяти конкретных приложений в двух отдельных учетных записях Cloudflare:
{
"exception_type": "session_length",
"exceptions": [
{
"account_id": "1xxxx",
"tf_addresses": [
"cloudflare_access_application.app_identity_access_denied",
"cloudflare_access_application.enforcing_ext_auth_worker_bypass",
"cloudflare_access_application.enforcing_ext_auth_worker_bypass_dev",
],
},
{
"account_id": "2xxxx",
"tf_addresses": [
"cloudflare_access_application.extra_wildcard_application",
"cloudflare_access_application.wildcard",
],
},
],
}
Трудности и извлечённые уроки
Наш путь не был лишён препятствий. За годы у нас накопились разрозненные ручные изменения, сделанные прямо в панели управления, в сотнях аккаунтов. Попытка импортировать существующий хаос в строгую систему "инфраструктура как код" была похожа на попытку сменить колесо на движущейся машине. И по сей день импорт ресурсов остается непрерывным процессом.
Мы также столкнулись с ограничениями наших собственных инструментов. Мы обнаружили крайние случаи в провайдере Cloudflare для Terraform, которые проявляются только при попытке управлять инфраструктурой в таком масштабе. Это были не просто мелкие неудобства. Это были суровые уроки о необходимости "пробовать собственный корм", чтобы мы могли создавать ещё более качественные решения.
Эти трудности чётко прояснили, с чем мы столкнулись, и привели нас к трём выстраданным урокам.
Урок 1: Высокие барьеры для входа тормозят внедрение
Первое препятствие для любого крупномасштабного внедрения IaC — это перенос существующих, настроенных вручную ресурсов. Мы дали командам два варианта: вручную создавать ресурсы Terraform с блоками import или использовать cf-terraforming.
Мы быстро выяснили, что уровень владения Terraform различается от команды к команде, а кривая обучения для ручного импорта существующих ресурсов оказалась гораздо круче, чем мы ожидали.
К счастью, утилита командной строки cf-terraforming использует Cloudflare API для автоматической генерации необходимого кода Terraform и команд import, что значительно ускорило процесс миграции.
Мы также создали внутреннее сообщество, где опытные инженеры могли направлять команды в тонкостях работы с провайдером и помогать разблокировать сложные импорты.
Урок 2: Дрейф конфигурации неизбежен
Нам также пришлось бороться с дрейфом конфигурации, который происходит, когда процесс IaC обходят, чтобы ускорить срочные изменения. Хотя внесение правок прямо в панели управления происходит быстрее во время инцидента, это приводит к рассинхронизации состояния Terraform с реальностью.
Мы внедрили собственную службу обнаружения дрейфа, которая постоянно сравнивает состояние, определённое Terraform, с фактически развёрнутым состоянием через Cloudflare API. При обнаружении дрейфа автоматическая система создаёт внутренний тикет и назначает его команде-владельцу с различными соглашениями об уровне обслуживания (SLA) для устранения.
Урок 3: Автоматизация — ключевой фактор
Cloudflare быстро внедряет инновации, поэтому наш набор продуктов и API постоянно растёт. К сожалению, это означало, что наш провайдер Terraform часто отставал с точки зрения функциональной полноты по сравнению с продуктом.
Мы решили эту проблему с выпуском нашего провайдера версии 5, который автоматически генерирует провайдер Terraform на основе спецификации OpenAPI. Этот переход не обошёлся без сложностей, пока мы оттачивали наш подход к генерации кода, но такой метод гарантирует, что API и Terraform остаются синхронизированными, снижая вероятность расхождения возможностей.
Главный урок: Проактивность лучше реактивности
Централизуя наши базовые уровни безопасности, требуя проверки коллегами и применяя политики до того, как любое изменение попадёт в прод, мы сводим к минимуму возможность ошибок конфигурации, случайных удалений или нарушений политик. Такая архитектура не только помогает предотвратить ручные ошибки, но и фактически повышает скорость разработки, поскольку команды уверены, что их изменения соответствуют требованиям.
Ключевой урок нашей работы с Customer Zero заключается в следующем: хотя панель управления Cloudflare отлично подходит для повседневных операций, достижение корпоративного масштаба и последовательного управления требует иного подхода. Когда вы относитесь к конфигурациям Cloudflare как к живому коду, вы можете масштабироваться безопасно и уверенно.