Перейти к содержимому

Mtls что это

  • автор:

Что такое mTLS

Обновлено и опубликовано

Опубликовано: 15.10.2023

протокол, основанный на TLS с усиленной безопасностью. Он включает дополнительную аутентификацию клиента с помощью сертификата. Таким образом, при обмене данными, клиент проверяет сервер, а сервер — клиента. Полное название Mutual TLS, а в переводе, Взаимный TLS.

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

Для mTLS, как и для TLS используются сертификаты стандарта x509. Их можно сгенерировать самому, например, с помощью утилиты openssl, купить или получить бесплатно от центра сертификации Let’s Encrypt.

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

  • Защищенный https на NGINX или Apache.
  • Защита Service Mesh с использованием istio.
  • Конфиденциальность при общении в Skype for Business.

Основные недостатки mTLS:

  1. Повышенная нагрузка. Шифровка и дешифровка — операции, которые сильно нагружают систему.
  2. Несовместимость. Не все клиенты могут быть настроены для взаимного TLS шифрования.

Дополнительно про Mutual TLS можно почитать на Википедии (только на английском).

Поддержка mTLS в своём Service Mesh: чему мы научились

Салют! На связи команда платформы Авито, сегодня будем рассказывать про service mesh.

У Авито самописный service mesh — сначала это был Netramesh, который потом трансформировался в собственный control-plane и envoy в качестве data-plane. В начале этого года я добавлял в него поддержку mTLS, а сейчас мы успешно раскатываем это решение для межсервисного взаимодействия.

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

Подходы к аутентификации сервисов в разных решениях для service mesh

В зависимости от того, как устроен service mesh, будет отличаться и подход к авторизации сервисов. Например, если он построен на умных клиентах, то логику аутентификации нужно будет реализовывать в них. Это значит, что придётся подумать, как обеспечить ротацию и обновление секретов, которые используются для «подтверждения личности сервиса».

Имеющиеся опенсорсные решения для service mesh обычно применяют другой подход — использование sidecar proxy рядом с каждым экземпляром сервиса. Ниже я проведу небольшой обзор того, как устроена аутентификация в распространённых решениях для service mesh.

Istio

Для межсервисной аутентификации в Istio предлагается один из двух способов: mutual TLS для аутентификации сервисов и использование JWT-токенов для аутентификации на уровне запросов.

Первый способ предполагает заворачивание всего обмена между сервисами в TLS-туннель. Он устанавливается между двумя sidecar proxy и аутентифицирует клиентскую и серверную сторону по TLS-сертификатам. Сертификаты содержат идентификаторы сервисов, а управление ими берёт на себя control plane компонент istiod. Авторизация сервисов, т.е. правила, по которым определяется, какие сервисы могут друг с другом взаимодействовать, задаётся набором политик в CRD. Политики могут распространяться как на весь меш, так и на отдельные сервисы.

Для более простой и безопасной миграции Istio даёт возможность использовать PERMISSIVE режим. В нём разрешается использовать и TLS- и plaintext-трафик.

Если mutual TLS работает на уровне транспорта, то JWT-токены— на уровне запросов. Второй способ предполагает, что приложение должно будет получить JWT-токен от одного из провайдеров и использовать его на каждый запрос. Такой подход позволяет более гибко настраивать политики разграничения доступа на уровне конкретных эндпоинтов и методов.

Consul Service Mesh

Консул использует похожий подход как и в Istio для контроля доступа сервисов внутри меша — Intentions. Есть Identity-based Intentions, которые работают на уровне соединений (L4) и Application-Aware Intentions на уровне отдельных запросов (L7).

Подход Identity-based Intentions при установке соединений между сайдкарами использует тот же mTLS. Внутри сертификатов задаётся идентификатор сервисов, соответствующий спецификации SPIFFE X.509 Identity Document (о ней я ещё буду говорить дальше). Сертификаты управляются консулом, а хранятся в Vault, с котором у него есть встроенная интеграция.

Application-Aware Intentions позволяют задать политики авторизации на основе параметров HTTP-запросов дополнительно к аутентификации на L4. Enterprise-версия Consul Service Mesh предлагает ещё более гибкие возможности авторизации.

Linkerd

Control plane Linkerd является Certificate Authority, который выпускает сертификаты, привязанные к сервис-аккаунту, и распространяет их до data-plane компонентов. Компоненты, в свою очередь, используют сертификаты для установки TLS-сессии и взаимной аутентификации сервисов. Политики авторизации задаются через CRD на уровне отдельных сервисов.

Open Service Mesh

Sandbox-проект CNCF. Здесь также используется envoy sidecar в качестве data-plane. Для аутентификации сервисов использует mTLS. Подписывать и выпускать сертификаты может отдельный компонент Tresor, возможна интеграция с Vault или cert-manager. Распространяет сертификаты control plane, используя протокол SDS.

Traefik Mesh

Достаточно легковесное решение по сравнению с Istio, которое использует несколько иной подход внедрения service mesh в работу сервисов. Разворачивается в виде даемонсета. Трафик сервисов заворачивается на него за счёт либо явных походов на сервисы через DNS имена вида ..traefik.mesh, либо настройки search в resolv.conf для всех контейнеров с сервисами. Так как межсервисный трафик проходит через proxy только со стороны клиента, обеспечить прозрачный для сервисов механизм аутентификации Traefik Mesh не может.

Для чего нам нужен mTLS в service mesh

У нас собственный service mesh, организованный по принципе sidecar proxy, и самописный control plane. Сейчас это нечто сложившееся исторически, про появление решения можно почитать тут. Я же расскажу про контекст, который мы имели на момент внедрения аутентификации.

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

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

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

Mutual TLS — это TLS соединение, в котором верифицируется не только серверный, но и клиентский сертификат. В процессе установления соединения стороны обмениваются сертификатами и публичными ключами, которые в них находятся. Далее каждая сторона может проверить целостность сертификата — ведь он передавался по открытой сети — за счёт проверки подписи на открытом ключе CA, которые эти сертификаты выпустил. Обычно, конечно, есть некая цепочка CA, вплоть до корневого CA.

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

Таким образом, mTLS между сервисами решает сразу две проблемы: проблему аутентификации и проблему защиты передаваемых данных от прослушивания и подделки.

Межсервисная авторизация

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

Envoy, который мы используем в качестве сайдкаров, позволяет это сделать через параметр match_subject_alt_names в блоке конфигурации TLS на листенере:

Чтобы сформировать эту конфигурацию, control plane должен знать обо всех потребителях сервиса и их идентификаторах. У нас это уже было реализовано — в тех CRD, которые деплоятся вместе с сервисом, все эти зависимости перечислены. Изначально в кластера их деплоит PaaS, который требует от каждого сервиса явного указания зависимостей в app.toml.

Бесшовная ротация секретов в Envoy

Для поддержки mTLS в service mesh важно, чтобы data plane компоненты могли автоматически и при этом бесшовно получать и обновлять сертификаты и ключи. Ротировать их лучше достаточно часто, чтобы снизить риск компрометации. В нашем случае срок жизни такого сертификата составляет часы.

Для загрузки сертификатов envoy использует SDS, который является частью XDS-протокола. XDS — это стандартизированный API поверх GRPC, который envoy использует для обновления свой конфигурации. Поддержка SDS в control plane или в каком-либо другом компоненте означает, что envoy может запросить нужный ему сертификат и бесшовно обновить своё внутреннее состояние.

В качестве SDS и инфраструктуры управления идентификаторами и сертификатами мы использовали Spire. Оказалось что его можно достаточно легко встроить в service mesh.

Что такое Spire

Spire — это эталонная реализация SPIFFE. SPIFFE — это стандарт, описывающий подход к идентификации и управлению секретами для инфраструктурных компонентов. SPIFFE и Spire, по сути, — ответ на проблемы масштабирования подходов к аутентификации компонентов в микросервисной среде.

Инсталляция spire cостоит из агентов, каждый из которых запускается на ноде кластера и сервера:

Сервер предоставляет API для администратора, который управляет набором идентификаторов сервиса (SPIFFE ID) и правилами их выдачи компонентам (Селекторы). Он же является CA для выпускаемых им сертификатов (SVID).

Агент запускается на ноде, регистрируется и подтверждает свою identity у spire-сервера. Он безопасно запрашивает у сервера SVID и хранит их у себя. Агент — это точка входа для sidecar proxy, которые запрашивают у него свои SVID. Он является SDS-сервером, который предоставляет доступ через UNIX-сокет. Почему через UNIX-сокет? Об этом я расскажу чуть ниже, сначала — про стандарт SPIFFE.

Что такое SPIFFE

SPIFFE — это набор спецификаций, решающий проблему идентификации и аутентификации приложений в динамичной микросервисной среде.

  • Как приложения идентифицируются. Для этого используется SPIFFE ID — структурированная в форме URI строка, которая уникально идентифицирует экземпляр приложения. Она состоит из имени trust domain и path.
  • Как SPIFFE ID кодируются в криптографически верифицируемый документ (SVID). Это может быть определённым образом сформированный сертификат или JWT-токен, которые содержат SPIFFE ID.
  • Как SVID выпускаются или перевыпускаются (Workload API): принципиально не требует никакой аутентификации со стороны приложения, идентифицируя его при помощи out-of-band механизмов.

Workload API стоит рассмотреть отдельно.а мой взгляд, он достаточно интересно решает проблему первоначального получения SVID тем компонентом, у которого пока нет никакого секрета, чтобы аутентифицировать себя.

Первичное получение SVID: проблема курицы и яйца

Представим такую ситуацию.

Человек получает свой первый паспорт. Для этого ему нужно прийти в паспортный стол с фотографией и назвать свои данные или предъявить свидетельство о рождении. Будущий паспорт — первый документ человека с фотографией, поэтому ему нечего предъявить сотруднику паспортного стола, чтобы удостоверить свою личность. Теоретически, он может договориться с кем-то и поменяться своими данными. Тогда он получит паспорт со своей фотографией, но чужим именем, и обманет систему.

Здесь и кроется проблема первичного получения идентифицирующего документа. В Spire её успешно решает Workload API.

Выше я акцентировал внимание на том, что Workload API предоставляется в пределах машины через UNIX-сокет, вот как это работает:

  1. Приложение обращается к Workload API агента через UNIX-сокет, запрашивает SVID. В случае envoy это происходит по протоколу SDS.
  2. Агент через вызов getsockopt с опцией SO_PEERCRED получает PID, UID и GID клиентского процесса. В дальнейшем он использует их для получения дополнительной информации о процессе.
  3. Агент берёт PID процесса, получает имя контейнера через cgroup, идёт на /pods локального kubelet, получает спеку пода и использует её для формирования селекторов: имя пода, ноды, неймспейс, имя сервис-аккаунта и т.д.
  4. Затем агент отдаёт тот SVID, который наиболее точно матчится на набор селекторов, зарегистрированных заранее через Registration API сервера.

Селектор может выглядеть так: выдавать указанный spiffeID только процессу, запущенному в неймспейсе X.

В дальнейшем envoy использует этот SVID в качестве клиентского сертификата при установлении TLS-соединения до сервиса, в котором включён mTLS.

Eventual consistency конфигурации service mesh и переходные режимы работы mTLS

Конфигурация service-mesh является eventual-consistent системой. Для нас это значило то, что легко может возникнуть ситуация, когда принимающий запросы сервис ожидает подключения по TLS, а сервис-клиент ещё не получил актуальную конфигурацию и работает в обычном режиме. Это привело бы к потерянным запросам при включении mTLS, т.к. сервис-получатель ожидал бы TLS соединения от клиента, который его установить ещё не готов.

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

В режиме INITIAL, сервис готов получать TLS запросы, но принимает запросы от всех клиентов по-прежнему в plain-тексте. После этого сервис переходит в режим PERMISSIVE, в котором все его клиенты отправляют запросы по TLS. При этом он по-прежнему готов принимать и plain-текст запросы. Такой переходный режим позволяет «дождаться» пока все envoy-сайдкары клиентских сервисов получат актуальные конфигурации от control-plan и перейдёт на использование TLS. Финальный режим STRICT отключает возможность принимать запросы без использования TLS.

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

Подведём итоги

Существуют разные подходы к авторизации в разных service-mesh решениях. Условно их можно разделить на две категории — авторизация на уровне транспорта (mTLS) и авторизация на уровне запросов. На своём собственном service-mesh мы реализовали первое решение с помощью возможностей envoy по бесшовной ротации сертификатов/ключей (SDS) и данных о связях между сервисами в нашем PaaS. А для решения проблемы управления и выдачи сертификатов использовали Spire — это интересный проект CNCF, который реализует спецификацию SPIFFE.

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

  • Блог компании AvitoTech
  • Информационная безопасность

Особенности самообслуживаемой аутентификации Apache Kafka на примере Booking.com

Big Data, Большие данные, предиктивная аналитика, обработка данных, Kafka, администрирование, архитектура, Security

Продолжая разбирать доклад Александра Миронова из Booking.com, который был представлен 23 января 2020 года на зимнем Kafka-митапе Avito.Tech, сегодня мы рассмотрим, с какими проблемами столкнулись администраторы Big Data при обеспечении информационной безопасности своих Кафка-кластеров. Читайте в нашей статье про возможные методы аутентификации в Apache Kafka и их практическое использование в самообслуживаемой ИТ-инфраструктуре одной из крупнейших travel-компаний.

SASL или mTLS: какой метод аутентификации выбрать для Kafka-кластера

Напомним, Apache Kafka поддерживает целый ряд методов аутентификации [1]:

  • SASL (Simple Authentication and Security Layer — простой уровень аутентификации и безопасности), включая следующие вариации:
    • PLAIN (простой механизм передачи паролей открытым тектом),
    • SCRAM (Salted Challenge Response Authentication Mechanism – механизм хранения данных и протокол аутентификации через хэши паролей, которые хранятся в Apache Zookeeper),
    • GSSAPI (Generic Security Services API, общий программный интерфейс сервисов безопасности),
    • OAUTHBEARER (на базе фреймворка OAuth 2.0, который позволяет стороннему приложению получать ограниченный доступ к службе HTTP от имени владельца ресурса через согласование взаимодействия между ними или разрешая стороннему приложению получать доступ от своего имени [2].

    Проанализировав все вышеописанные методы аутентификации в Kafka, команда администраторов Big Data инфраструктуры компании Booking.com выбрала именно mTLS по следующим соображениям [4]:

    • SASL/PLAIN не подошел из-за представления паролей в виде текстовых файлов, которые необходимо поддерживать вручную;
    • SASL/SCRAM предполагает хранение хэшей паролей в Apache Zookeeper, что проблематично при наличии множества этих распределенных сервисов, не синхронизованных между собой;
    • SASL/GSSAPI в связке с защищенным сетевым протоколом Kerberos слишком сложен для настройки и конфигурирования;
    • SASL/OAUTHBEARER требует стороннего сервиса для хранения REQUEST-токенов;
    • mTLS позволяет относительно просто обеспечить двустороннюю аутентификацию брокера и клиента с помощью SSL-сертификатов.

    Однако, при практической реализации mTLS перед администраторами Kafka-кластеров в Booking.com возник вопрос «Как обеспечить обновление и распределение по клиентам SSL-сертификатов в условиях самообслуживаемой Big Data инфраструктуры (self-service)?». Далее мы рассмотрим, как именно была решена эта задача.

    Автоматическое управление SSL-сертификатами для mTLS-аутентификации

    В компании уже имеется сервис, который выписывает SSL-сертификаты через вызовы по API (Certificate API). К нему обращается кластер Kafka по защищенному mTLS-соединению, чтобы проверить SSL-сертификат брокера и по необходимости получить новый с поддержкой динамического обновления конфигурации. Это делается с помощью Puppet-модуля, который раз в полчаса обращается к Certificate API и проверяет наличие действующих сертификатов на узле кластера и срок их действия. При необходимости обновить SSL-сертификат брокера этот Puppet-модуль автоматически получает его от Certificate API и отправляет на нужный узел, перезагружая SSL-контекст в самом брокере.

    Аутентификация на стороне клиентского приложения обеспечивается с помощью внутреннего сервиса c метаданными (Service Directory) и хранилища сертификатов (Vault), взаимодействие между которыми организовано через собственный сервис Authr.

    аутентификация Кафка, mTSL, Kafka Authentication

    Примечательно, что весь этот процесс взаимной аутентификации полностью автоматизирован и особенности его реализации скрыты от пользователя. Это повышает уровень абстракции всей Big Data системы и улучшает пользовательский опыт, обеспечивая бесперебойную работу в режиме самообслуживания (self-service). Подробности решения изложены в видеодокладе Александра Миронова, представленном 23 января 2020 года на зимнем Kafka-митапе Avito.Tech [4]. По аналогичному принципу администраторы кластеров Kafka в Booking.com организовали авторизацию, о чем мы поговорим в следующей статье.

    А как на практике обеспечить информационную безопасность кластера Apache Kafka для потоковой обработки больших данных в проектах цифровизации своего бизнеса, а также государственных и муниципальных предприятий, вы узнаете на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

    • Администрирование кластера Kafka
    • Kafka Streams для разработчиков
    • Kafka интеграция для разработчиков

    Источники

    1. https://docs.confluent.io/current/security/security_tutorial.html
    2. https://docs.confluent.io/current/kafka/authentication_sasl/authentication_sasl_oauth.html
    3. https://docs.confluent.io/current/kafka/encryption.html
    4. https://habr.com/ru/company/avito/blog/486278/

    «Стандарт Банка России «Безопасность финансовых (банковских) операций. Прикладные программные интерфейсы обеспечения безопасности финансовых сервисов на основе протокола OpenID. Требования» СТО БР ФАПИ.СЕК-1.6-2020″ (принят и введен в действие приказом Банка России от 09.10.2020 N ОД-1650)

    Этот документ в некоммерческой версии КонсультантПлюс доступен по расписанию:

    • по рабочим дням с 20-00 до 24-00 (время московское)
    • в выходные и праздничные дни в любое время

    Вы можете заказать документ на e-mail

    Тексты документов всегда доступны в коммерческой версии КонсультантПлюс.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *