В предыдущих статьях мы рассмотрели архитектуру решения 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.