Изучаем Apache Kafka с нуля. Урок 24. kafka-acls.sh

Изучаем Apache Kafka с нуля. Урок 24. kafka-acls.sh

 

В уроке 23 мы разобрали kafka-replica-verification.sh — инструмент, который подключается к каждому брокеру напрямую и сравнивает смещения реплик. Там же мы отметили важную особенность: утилита общается с брокерами через Fetch API без каких-либо ограничений доступа. В реальном кластере это уже вопрос: а кто вообще имеет право подключаться?

В production-окружениях разные сервисы получают разные права. Один должен только читать из топика, другой — писать, третий — создавать топики и управлять группами. Без разграничения любой клиент с сетевым доступом делает всё что хочет. Именно для этого в Kafka есть система ACL (Access Control Lists) — и управляет ею утилита kafka-acls.sh.

Тема безопасности Kafka — настройка SASL, mTLS, тонкости политик ACL в многоброкерном кластере — разбирается в курсе «Администрирование кластера Kafka». Там же практика: разные роли клиентов, аудит прав, интеграция с LDAP.

 

Как устроена авторизация в Kafka

 

ACL (Access Control List) — это список правил, который определяет, кто и что может делать с ресурсами кластера. Ресурсы — это топики, группы потребителей, кластер в целом, транзакционные идентификаторы.

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

Авторизация в Kafka всегда работает вместе с аутентификацией. Сначала кластер проверяет, кто пришёл (через SASL/PLAIN, SASL/SCRAM, mTLS), получает имя принципала — и только потом смотрит ACL. Без аутентификации система не знает, кому давать права и кому отказывать.

В KRaft-режиме (Kafka 4.x) за авторизацию отвечает StandardAuthorizer. Он хранит ACL прямо в метаданных KRaft — никакого ZooKeeper не нужно. Старый AclAuthorizer, работавший через ZooKeeper, в Kafka 4.x больше не используется.

 

Apache Kafka: администрирование кластера

Код курса
KAFKA
Ближайшая дата курса
13 июля, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800

 

Включаем StandardAuthorizer в server.properties

 

Прежде чем использовать kafka-acls.sh, нужно включить авторизатор в конфиге брокера. Без этого шага утилита запустится, но правила не будут применяться.

# Фрагмент kraft/server.properties - включение авторизации

# Включаем StandardAuthorizer (только для KRaft-режима)
authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer

# Суперпользователи - обходят проверку ACL полностью
# User: - обязательный префикс для SASL-принципалов
super.users=User:admin;User:kafka-admin

# Поведение при отсутствии ACL для ресурса:
# false (по умолчанию) - запрещать, если нет явного Allow
# true - разрешать всем, пока нет явного Deny
allow.everyone.if.no.acl.found=false

После изменения конфига брокер нужно перезапустить. ACL, добавленные через kafka-acls.sh, применяются динамически — без перезапуска.

Параметр allow.everyone.if.no.acl.found — первая ловушка при внедрении ACL. Значение true удобно для постепенного перехода, когда нужно включить авторизатор, не сломав всё сразу. Но оставлять его в production нельзя — ресурсы без явных правил будут открыты всем.

Параметр super.users тоже требует внимания. Суперпользователи обходят ACL полностью — это инструмент администратора, а не сервисных аккаунтов.

 

Подключение с аутентификацией — command-config

 

Если на кластере включена SASL-аутентификация, то и kafka-acls.sh должна предъявить учётные данные. Для этого готовим файл конфига и передаём его через —command-config.

# Файл: /tmp/admin-client.properties
# Используется для подключения kafka-acls.sh к защищённому кластеру

security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
  username="admin" \
  password="admin-secret";

Этот файл передаётся в каждой команде. Без него при включённой аутентификации утилита получит Authentication failed и ничего не сделает.

 

Флаги kafka-acls.sh

Утилита поддерживает три основные операции (—add, —remove, —list) и набор параметров для описания правил. Ниже — полная справка.

Флаг Описание
—bootstrap-server Адрес брокера для подключения. Обязательный.
—command-config Файл с параметрами подключения — учётные данные SASL, SSL-настройки.
—add Добавить правило ACL.
—remove Удалить правило ACL. По умолчанию запрашивает подтверждение.
—list Показать текущие ACL. Без доп. флагов выводит все правила.
—topic <name> Ресурс — топик с указанным именем.
—group <name> Ресурс — группа потребителей.
—cluster Ресурс — кластер в целом. Нужен для Create, Alter, ClusterAction.
—transactional-id <id> Ресурс — транзакционный идентификатор продюсера.
—delegation-token <token> Ресурс — токен делегирования.
—allow-principal Принципал, которому разрешена операция. Формат: User:имя.
—deny-principal Принципал, которому явно запрещена операция.
—allow-host Ограничение разрешения по IP-адресу или хосту. По умолчанию * (любой хост).
—deny-host Ограничение запрета по хосту.
—operation Конкретная операция: Read, Write, Create, Delete, Alter, Describe, DescribeConfigs, AlterConfigs, ClusterAction, IdempotentWrite, CreateTokens, DescribeTokens, All.
—producer Шорткат: Write + Describe на топик, Create на кластер.
—consumer Шорткат: Read + Describe на топик, Read на группу.
—resource-pattern-type Тип сопоставления имени ресурса: Literal (точное, по умолчанию), Prefixed, Match, Any.
—force Удалить без запроса подтверждения (используется с —remove).

Флаги —producer и —consumer закрывают 80% типовых задач. Вместо трёх отдельных вызовов для типичного продюсера — один с шорткатом.

 

Ресурсы и операции — что с чем сочетается

 

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

Ресурс Применимые операции
Topic Read, Write, Create, Delete, Alter, Describe, DescribeConfigs, AlterConfigs
Group Read, Describe, Delete
Cluster Create, Alter, Describe, ClusterAction, DescribeConfigs, AlterConfigs, IdempotentWrite
TransactionalId Write, Describe
DelegationToken Describe

Операция All покрывает все применимые операции для выбранного типа ресурса. В production её стоит использовать только для административных принципалов — давать All сервисному аккаунту продюсера слишком широко.

Схема авторизации Kafka: клиент проходит SASL-аутентификацию, брокер проверяет ACL в StandardAuthorizer, суперпользователи обходят проверку, остальные получают Allow или Deny

 

Практика. Добавляем ACL

Права для продюсера

Самый частый сценарий — дать сервису право писать в конкретный топик. Флаг —producer разворачивается в Write + Describe на топик и Create на кластер. Именно Create на кластер нужен, чтобы продюсер мог создать топик автоматически, если он не существует.

# Разрешаем order-service писать в топик orders
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:order-service \
  --producer \
  --topic orders

Права для консюмера

Читающему сервису нужны Read + Describe на топик и Read на группу потребителей. Без права Read на группу клиент не сможет присоединиться к ней и зафиксировать смещения.

# Разрешаем analytics-service читать из топика events через группу analytics-group
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:analytics-service \
  --consumer \
  --topic events \
  --group analytics-group

Явное указание операции

Если шорткаты не подходят — указываем операцию напрямую через —operation. Например, дать мониторинговому агенту право только смотреть конфигурацию брокера, не давая ему ничего лишнего.

# Разрешаем monitor-agent смотреть конфигурацию топика payments
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:monitor-agent \
  --operation DescribeConfigs \
  --topic payments

# Явно запрещаем legacy-service писать в топик sensitive-data
# Deny действует даже если есть Allow от другого правила
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --deny-principal User:legacy-service \
  --operation Write \
  --topic sensitive-data

Явный запрет через —deny-principal приоритетнее разрешения. Если принципал попадает и под Allow, и под Deny — запрос будет отклонён. Это поведение нельзя переопределить.

 

Практика. Просматриваем ACL

—list без дополнительных параметров выводит все ACL кластера. На большом кластере список может быть длинным — полезнее фильтровать по конкретному ресурсу.

# Все ACL кластера
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --list

# ACL только для конкретного топика
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --list \
  --topic orders

# ACL для конкретной группы потребителей
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --list \
  --group analytics-group

# Найти все правила для конкретного принципала (через grep)
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --list | grep "User:order-service"

В выводе для каждого правила показан принципал, тип (Allow или Deny), операция, ресурс и хост. Звёздочка в поле хоста означает, что ограничений по IP-адресу нет.

 

Практика. Удаляем ACL

Удаление работает через —remove с теми же параметрами, что использовались при добавлении. По умолчанию утилита выводит список правил, которые будут удалены, и просит подтверждение.

# Удаляем права продюсера для order-service - с подтверждением
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --remove \
  --allow-principal User:order-service \
  --producer \
  --topic orders

# Удаляем без интерактивного запроса (для скриптов автоматизации)
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --remove \
  --allow-principal User:order-service \
  --producer \
  --topic orders \
  --force

При удалении важно указывать точно те же параметры, что были при добавлении. Если правило создавалось с —producer — удалять тоже нужно с —producer, а не через три отдельные команды с —operation.

 

Apache Kafka для инженеров данных

Код курса
DEVKI
Ближайшая дата курса
24 августа, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800

 

Префиксные ACL — права на группу ресурсов

По умолчанию kafka-acls.sh работает в режиме Literal — точное совпадение имени ресурса. Если нужно дать права сразу на все топики с определённым префиксом, используем —resource-pattern-type Prefixed.

# Разрешаем payment-service читать из всех топиков с префиксом "payment-"
# Покрывает payment-orders, payment-refunds, payment-notifications и все будущие
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:payment-service \
  --operation Read \
  --topic payment- \
  --resource-pattern-type Prefixed

# Просмотр именно префиксных правил
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --list \
  --topic payment- \
  --resource-pattern-type Prefixed

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

 

Права для транзакционных продюсеров

 

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

# Проверено: Apache Kafka 4.2.0, Ubuntu 22.04

# Права для транзакционного продюсера:
# 1. Стандартные права на топик
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:tx-producer \
  --producer \
  --topic orders

# 2. Права на использование transactional.id
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:tx-producer \
  --operation Write \
  --transactional-id orders-tx-producer

# 3. Идемпотентная запись (нужна для exactly-once)
kafka-acls.sh \
  --bootstrap-server localhost:9092 \
  --command-config /tmp/admin-client.properties \
  --add \
  --allow-principal User:tx-producer \
  --operation IdempotentWrite \
  --cluster

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

 

Подводные камни при работе с kafka-acls.sh

Несколько ситуаций, которые стабильно вызывают путаницу при первом знакомстве с ACL в Kafka.

  • Deny приоритетнее Allow. Если принципал попадает и под разрешающее, и под запрещающее правило — запрет побеждает всегда. Это не обходится ни суперпользователями, ни другими правилами.
  • Формат принципала зависит от типа аутентификации. Для SASL-пользователей — User:имя. Для mTLS-клиентов — User:CN=имя,OU=… (полный DN сертификата). Опечатка в имени — правило просто не применяется.
  • —resource-pattern-type обязателен при удалении префиксных правил. Если правило создавалось с Prefixed, удалять нужно тоже с Prefixed. В режиме Literal утилита не найдёт правило и ничего не удалит — без ошибки.
  • Create на кластер нужен для автосоздания топиков. Даже если у продюсера есть Write на топик — если топик не существует и нет Create на кластер, создать его не получится. Шорткат —producer добавляет это автоматически.
  • ACL применяются к принципалу, а не к IP. Ограничение по хосту через —allow-host — дополнительный фильтр, не замена аутентификации. Полагаться только на него не стоит.

Большинство проблем с ACL видны в логах брокера как Authorization failed — с указанием принципала, операции и ресурса. При дебаггинге первым делом смотрим туда.

 

Что дальше

В уроке 25 разберём kafka-broker-api-versions.sh — утилиту, которая показывает, какие версии API поддерживает каждый брокер кластера. Это важно при обновлении кластера и при диагностике проблем совместимости клиентов разных версий.

Референсные ссылки

Все уроки курса

Тема URL
1 Установка Kafka с Zookeeper https://bigdataschool.ru/blog/news/lesson1-kafka-zookeeper-install/
2 Установка Kafka в режиме KRaft https://bigdataschool.ru/blog/news/lesson2-kafka-kraft-install/
3 Docker KRaft. Однонодовый кластер https://bigdataschool.ru/blog/news/lesson3-kafka-docker-single/
4 Docker KRaft. 3-нодовый кластер https://bigdataschool.ru/blog/news/lesson4-kafka-docker-cluster/
5 Утилиты bin/. Переменные окружения и основы https://bigdataschool.ru/blog/news/lesson5-kafka-bin-intro/
6 kafka-topics.sh. Управление топиками https://bigdataschool.ru/blog/news/lesson6-kafka-topics/
7 kafka-console-producer.sh https://bigdataschool.ru/blog/news/lesson7-kafka-console-producer/
8 kafka-console-consumer.sh https://bigdataschool.ru/blog/news/lesson8-kafka-console-consumer/
9 kafka-server-start.sh / kafka-server-stop.sh https://bigdataschool.ru/blog/news/lesson9-kafka-server-start-stop/
10 kafka-storage.sh https://bigdataschool.ru/blog/news/lesson10-kafka-storage/
11 kafka-cluster.sh https://bigdataschool.ru/blog/news/lesson11-kafka-cluster/
12 kafka-metadata-quorum.sh https://bigdataschool.ru/blog/news/lesson12-kafka-metadata-quorum/
13 kafka-metadata-shell.sh https://bigdataschool.ru/blog/news/lesson13-kafka-metadata-shell/
14 kafka-features.sh https://bigdataschool.ru/blog/news/lesson14-kafka-features/
15 kafka-configs.sh https://bigdataschool.ru/blog/news/lesson15-kafka-configs/
16 kafka-log-dirs.sh https://bigdataschool.ru/blog/news/lesson16-kafka-log-dirs/
17 kafka-dump-log.sh https://bigdataschool.ru/blog/news/lesson17-kafka-dump-log/
18 kafka-delete-records.sh https://bigdataschool.ru/blog/news/lesson18-kafka-delete-records/
19 kafka-consumer-groups.sh https://bigdataschool.ru/blog/news/lesson19-kafka-consumer-groups/
20 kafka-streams-application-reset.sh https://bigdataschool.ru/blog/news/lesson20-kafka-streams-reset/
21 kafka-leader-election.sh https://bigdataschool.ru/blog/news/lesson21-kafka-leader-election/
22 kafka-reassign-partitions.sh https://bigdataschool.ru/blog/news/lesson22-kafka-reassign-partitions/
23 kafka-replica-verification.sh https://bigdataschool.ru/blog/news/lesson23-kafka-replica-verification/
24 kafka-acls.sh https://bigdataschool.ru/blog/news/lesson24-kafka-acls/
25 kafka-broker-api-versions.sh https://bigdataschool.ru/blog/news/lesson25-kafka-broker-api-versions/
26 kafka-get-offsets.sh https://bigdataschool.ru/blog/news/lesson26-kafka-get-offsets/
27 kafka-verifiable-producer/consumer.sh https://bigdataschool.ru/blog/news/lesson27-kafka-verifiable/
28 kafka-producer-perf-test.sh https://bigdataschool.ru/blog/news/lesson28-kafka-producer-perf/
29 kafka-consumer-perf-test.sh https://bigdataschool.ru/blog/news/lesson29-kafka-consumer-perf/
30 kafka-mirror-maker.sh https://bigdataschool.ru/blog/news/lesson30-kafka-mirror-maker/
31 connect-standalone.sh https://bigdataschool.ru/blog/news/lesson31-kafka-connect-standalone/
32 connect-distributed.sh https://bigdataschool.ru/blog/news/lesson32-kafka-connect-distributed/
33 kcat. Альтернативный CLI https://bigdataschool.ru/blog/news/lesson33-kcat/