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

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

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

  • Аутентификация подключений к брокерам от клиентов (продьюсеров и консьюмеров), других брокеров и приложениями, использующими SSL или SASL (Kerberos).

  • Аутентификация подключений от брокеров к ZooKeeper.

  • Шифрование данных, передаваемых между брокерами и клиентами, между брокерами или между брокерами и инструментами, с использованием SSL (обратите внимание, что при включении SSL происходит снижение производительности, величина которого зависит от типа процессора и реализации JVM).

  • Авторизация операций чтения/записи, выполняемых клиентами.

  • Авторизация подключаема и поддерживается интеграция с внешними службами авторизации.

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

Работаем с SSL

SSL (secure sockets layer) представляет собой криптографический протокол для безопасной связи. В Kafka по умолчанию этот протокол отключен. Но мы можем в любой момент включить SSL.

Работа с SSL как и в большинстве других систем, в Kafka начинается с создания сертификата. Когда мы устанавливали Zookeeper и Kafka, то предварительно была развернута Java, в состав которой входит утилита keytool. Далее мы сгенерируем ключ во временном хранилище ключей, чтобы позже экспортировать и подписать его с центром сертификации  

keytool -keystore server.keystore.jks -alias localhost -validity {validity} -genkey

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

Параметр keystroke указывает в каком файле хранить ключ, а validity это период действия сертификата в днях. Помните про то, что для корректной работы сертификатов необходима правильная настройка DNS, позволяющая корректно разрешать имена узлов.

Приведенные выше действия по генерации ключей необходимо проделать на всех узлах кластера.

Сейчас у нас имеются сертификаты, но они являются самоподписанными, то есть злоумышленник может при желании тоже сгенерировать свой сертификат, и обменявшись открытыми ключами с парой легальных участников читать и модифицировать весь их трафик (атака Man in the Middle).  Поэтому важно предотвратить подделку сертификатов, подписав их для каждой машины в кластере. Для решения этой задачи необходим центр сертификации (CA), который отвечает за подписание сертификатов. Центр сертификации подписывает сертификаты, и криптография гарантирует, что подписанный сертификат сложно подделать с вычислительной точки зрения. Таким образом, пока центр сертификации является подлинным и заслуживающим доверия органом, клиенты могут быть уверены в том, что они подключаются к подлинным машинам.

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

openssl req -new -x509 -keyout ca-key -out ca-cert -days 365
keytool -keystore server.truststore.jks -alias CARoot -import -file ca-cert

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

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

keytool -keystore server.keystore.jks -alias CARoot -import -file ca-cert
keytool -keystore server.keystore.jks -alias localhost -import -file cert-signed

Настройка брокеров

Настройка брокеров начинается с указания списка портов, ка которых мы будем принимать соединения. Так как мы используем соединение по SSL, то на стороне брокера необходимо выполнить следующие настройки:

ssl.keystore.location=/var/private/ssl/kafka.server.keystore.jks
        ssl.keystore.password=…
        ssl.key.password=…
        ssl.truststore.location=/var/private/ssl/kafka.server.truststore.jks
        ssl.truststore.password=…

Для проверки корректности работы выполненных настроек, вы можете выполнить следующие команды:

openssl s_client -debug -connect localhost:9093 -tls1

Настраиваем SASL

SASL (Simple Authentication and Security Layer) — это платформа для аутентификации и защиты данных в интернет-протоколах. Он направлен на то, чтобы отделить интернет-протоколы от конкретных механизмов аутентификации. Рассмотрим принципы работы SASL.

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

 

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

Вернемся к настройке Kafka. Для настройки аутентификации нам потребуется протокол Kerberos, то есть мы можем использовать для аутентификации Active Directory. Если в вашей сети нет AD, то необходимо будет развернуть сторонний сервер Kerberos. Так или иначе вам необходимо создать записи (принципалы) в вашем каталоге AD или другой системе для каждого брокера Kafka в вашем кластере.

В каталоге с конфигурациями брокера создадим файл kafka_server_jaas.conf следующего содержания:

Затем нам необходимо указать Kafka пути к конфигурационным файлам:

    -Djava.security.krb5.conf=/etc/kafka/krb5.conf

    -Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf

Добавим порты, которые система должна слушать:

listeners=SASL_PLAINTEXT://host.name:port

Если используется SASL_SSL, то также необходимо настроить SSL. Если вы настраиваете только порт SASL (или если вы хотите, чтобы брокеры Kafka аутентифицировали друг друга с помощью SASL), то убедитесь, что вы установили один и тот же протокол SASL для взаимодействия между брокерами:

security.inter.broker.protocol=SASL_PLAINTEXT

Мы также должны настроить имя службы в server.properties, которое должно соответствовать основному имени брокеров kafka. В приведенном выше примере принципалом является "kafka/kafka1.hostname.com@EXAMPLE.com", так что:

sasl.kerberos.service.name=kafka

Подключаем клиентов

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

KafkaClient {

        com.sun.security.auth.module.Krb5LoginModule required
        useKeyTab=true
        storeKey=true
        keyTab="/etc/security/keytabs/kafka_client.keytab"
        principal="kafka-client-1@EXAMPLE.COM";
  
    };

В разделе Kafka Client описано, как клиенты, такие как продьюсеры и консьюмеры, могут подключаться к Kafka Broker. Далее передадим системе пути к конфигурационным файлам также, как мы это делали выше.

    -Djava.security.krb5.conf=/etc/kafka/krb5.conf

    -Djava.security.auth.login.config=/etc/kafka/kafka_client_jaas.conf

И в завершение нам необходимо настроить на наших продьюсерах и консьюмерах следующие свойства в producer.properties или consumer.properties

security.protocol=SASL_PLAINTEXT (or SASL_SSL)
    sasl.kerberos.service.name=kafka

Про ACL

В заключении темы безопасности Kafka рассмотрим возможности по работе со списками доступа ACL. По умолчанию, если какой-либо ресурс не связан с ACL, то никто, кроме суперпользователя не получит к нему доступ. Изменить эти настройки можно с помощью правок в файле broker.properties.

allow.everyone.if.no.acl.found=true

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

super.users=User:Bob;User:Alice

Заключение

На этом тему базовой настройки безопасности в Apache Kafka можно считать завершенной. Мы рассмотрели работу с SSL, SASL аутентификацию и соответствующие настройки на клиентах. А прямо сейчас хочу пригласить вас на бесплатный вебинар, в рамках которого рассмотрим как в приложениях на Spring Boot можно работать с Kafka. Узнаем, что предоставляет платформа Spring для ускоренной разработки приложений, работающих с Kafka. Посмотрим, какие есть настройки, как это все конфигурируется. Проведем границу между "родным функционалом" Kafka api и "добавками" от Spring Boot.

Комментарии (4)


  1. LeshaRB
    11.04.2023 15:38

    Уважаемый автор, представитель компании OTUS
    Вы так клепаете статьи, что вам уже плевать на читателей
    В одном месте есть форматирование кода, в другом нет

    Подход - пипл схавает?


    1. MaxRokatansky
      11.04.2023 15:38
      +4

      Добрый день. Конечно же нет. Автор действительно в одном месте забыл про форматирование кода. Исправили.

      Благодарю за замечание.


      1. sshikov
        11.04.2023 15:38

        Сильно лучше не стало.

        В каталоге с конфигурациями брокера создадим файл kafka_server_jaas.conf следующего содержания:

        Затем нам необходимо указать Kafka пути к конфигурационным файлам:


        И где kafka_server_jaas.conf следующего содержания? А нету…


  1. eliseisSmiRnov2
    11.04.2023 15:38

    Для обеспечения безопасности в Apache Kafka используются различные механизмы и инструменты, такие как:

    1. Аутентификация и авторизация
      Apache Kafka поддерживает механизмы аутентификации и авторизации, которые позволяют контролировать доступ пользователей к системе. Для аутентификации могут использоваться различные методы, такие как SSL/TLS, SASL (Simple Authentication and Security Layer) и OAuth 2.0. Для авторизации используется ACL (Access Control List), который определяет права доступа пользователей к топикам и группам потребителей.

    2. Шифрование
      Apache Kafka поддерживает шифрование данных в передаче, что позволяет защитить информацию от перехвата и несанкционированного доступа. Для шифрования могут использоваться SSL/TLS и SASL.

    3. Мониторинг и анализ
      Для обнаружения и предотвращения возможных атак и угроз в Apache Kafka используются инструменты мониторинга и анализа, такие как Apache Kafka Security Interceptor (Kafka-Security-Interceptor) и Apache Kafka Monitoring Interceptor (Kafka-Monitoring-Interceptor). Эти инструменты позволяют контролировать доступ пользователей к системе, отслеживать активность и анализировать данные.

    4. Обновление и патчи
      Для обеспечения безопасности в Apache Kafka необходимо регулярно обновлять систему и устанавливать патчи, которые исправляют уязвимости и ошибки в коде. Это позволяет минимизировать риски возникновения угроз и обеспечить стабильную работу системы.

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