Безопасность: ACL, аутентификация и авторизация
Безопасность в системе координации и синхронизации данных, такой как ZooKeeper, имеет критическое значение. Даже если ваши сервисы хорошо масштабируются и устойчивы к сбоям, без правильной аутентификации и авторизации злоумышленник может получить доступ к конфигурациям, ключам и метаданным, что чревато нарушениями целостности и конфиденциальности. В этой главе мы рассмотрим безопасность в ZooKeeper через призму ACL, аутентификации и авторизации. Мы объясним термины и концепции так, чтобы вы могли быстро включиться в работу: как устроены ACL, какие схемы аутентификации существуют и как их применять на практике, какие есть реальные сценарии внедрения и какие риски стоят перед проектами. Мы будем приводить примеры как из открытых источников, так и отечественных решений, а также конкретные шаги настройки и тестирования. В конце — блок вопросов и ответов, который поможет закрепить материал.
Что такое ACL, аутентификация и авторизация
- ACL (Access Control List) — это список правил, ограничивающих доступ к узлу данных в дереве ZooKeeper. Каждый элемент ACL связывает набор прав доступа с конкретной идентификацией клиента и схемой аутентификации.
- Аутентификация — процесс, в ходе которого клиент доказывает свою личность ZooKeeper. В ZooKeeper поддерживаются несколько схем аутентификации, например digest, world, ip, host, SASL (Kerberos) и другие.
- Авторизация — после того как клиент аутентифицирован, ZooKeeper проверяет, имеет ли он разрешения на выполнение запрашиваемой операции (чтение, создание, запись, удаление, администрирование) на данном узле. Разрешения задаются через ACL.
- Схема (scheme) — способ идентификации пользователя или группы, который используется в ACL. Различают схемы world, digest, auth, ip, host, sasl и другие. Каждая схема определяет, как формируется идентификатор (Id) в ACL.
- Права доступа (Permissions) — перечисление PERMS: READ, WRITE, CREATE, DELETE, ADMIN. Комбинации прав формируют наборы, которые применяются к конкретному znodes через ACL.
- Разделение фаз: аутентификация vs авторизация. Аутентификация устанавливает личность, авторизация определяет, какие действия разрешены этой личности. ACL — это механизм, соединяющий личность и набор разрешений на конкретный узел.
Архитектура безопасности в ZooKeeper
- Клиент-зоо-зооподдержка. Клиент устанавливает соединение с сервером ZooKeeper. После начала сессии клиент может аутентифицироваться через выбранную схему и передавать credentials при необходимости.
- Хранение ACL. Каждый znodes имеет свой список ACL. По умолчанию ZooKeeper имеет набор ACL, которые можно изменить через API или административные команды. ACL могут быть применены как к новым, так и к существующим узлам.
- Фаза регистрации аутентификации. В некоторых схемах (например SASL) ZooKeeper использует внешние провайдеры (Kerberos, LDAP через SASL) и JAAS-конфигурацию для обмена ключами и билетом аутентификации между клиентом и сервером.
- Ограничение доступа внутри кластера. При правильно настроенной ACL вы можете обеспечить изоляцию между различными приложениями и командами, ограничив доступ к конфигурациям и состоянию координационной службы.
- Взаимодействие с внешними системами идентификации. В большинстве корпоративных сценариев ZooKeeper выступает как часть общей архитектуры IAM (Identity and Access Management). Это может включать Kerberos/SASL, LDAP, OAuth/OpenID Connect через прокси-решения или интеграцию с централизованными источниками удостоверений.
Типичные схемы аутентификации и их особенности
- world (или OPEN). Схема, которая по умолчанию ассоциирует ACL с любым клиентом. Используется только для открытых узлов или для тестирования. Не рекомендуется для продакшна, так как даёт доступ всем.
- digest. Основная схема для простого локального управления удостоверениями. Клиент отправляет имя пользователя и пароль; сервер проверяет, что предоставленная пара соответствует записи в ACL. Подходит для небольших команд и сценариев, когда нет внешнего центра удостоверений.
- auth. Схема, которая применяет уже аутентифицированную сессию. Чаще используется в сочетании с digest и SASL для автоматического переноса информации об аутентификации.
- ip/host. Учет по IP-адресу или имени хоста. Менее гибкая и подвержена подменам (из‑за прокси, NAT, динамических адресов). Обычно применяется как дополнительная фильтрация, но не как основной механизм безопасности.
- SASL (обычно Kerberos). Поддерживает межсерверную и межпроцессную аутентификацию на уровне SASL/GSSAPI. Часто применяется в больших системах, где требуется единая система аутентификации и централизованный аудит. Kerberos для многих организаций предлагает надёжный и масштабируемый способ аутентификации, особенно в средах с Microsoft Active Directory или Linux-подсистемами Kerberos.
- Примечание по JAAS. При использовании SASL/Kerberos конфигурация аутентификации часто требует JAAS-конфигурации на стороне сервера и клиента (файлы jaas.conf), а также параметров запуска JVM для указания файла конфигурации аутентификации.
Как работают ACL и разрешения на узлах
- ACL — это список записей, каждая запись связывает идентификатор (Id) и набор прав (Perms). Например, Id может быть digest:user:password или world:anyone, или Id с использованием SASL Kerberos.
- Разрешения определяют, какие операции можно выполнять: чтение дерева и содержимого узла, создание дочерних узлов, удаление, а также административные операции (например, изменение ACL).
- Наследование ACL. В ZooKeeper ACL применяются к конкретному znodes. Наследование не является автоматическим для всех потомков; вы можете устанавливать одинаковые ACL на группу узлов или различать ACL по путям.
- Безопасность по умолчанию. Если в кластере используется открытая ACL OPEN, то доступ к данным может быть слишком широким. В реальных проектах рекомендуется использовать строгие ACL на критически важных узлах и централизованную политику для всего дерева.
Риск моделей и ограничений
- Ошибки конфигурации. Неправильная настройка requireClientAuthScheme или неверно заданные ACL могут привести к тому, что легитимные клиенты будут заблокированы, а злоумышленники — получить доступ.
- Перекрестная проверка прав. При большом числе узлов и сложной иерархии ACL управление может стать громоздким, и легко допустить ошибку, которая отразится на части инфраструктуры.
- Распространение ключей и паролей. Если Digest является основным механизмом, хранение паролей (или digest-значений) требует особой осторожности. Плохая обработка паролей в коде и конфигурациях приводит к компрометации.
- Перекрестное влияние аутентификации и авторизации. Некоторые ошибки реализации, например, при использовании различных схем в одном пути, могут позволить обход ACL.
- Производительность. Включение SASL/Kerberos и сложных переменных ACL может повлиять на время авторизации и общий отклик системы в условиях высокой нагрузки.
- Совместимость и поддержка. Не все версии ZooKeeper и клиенты одинаково хорошо поддерживают все схемы. Необходимо тестировать обновления на совместимость и наличие уязвимостей.
- Транспортная безопасность. ACL и аутентификация защищают сам доступ к ZooKeeper, но не автоматически шифруют трафик. Для критичных сред рекомендуется рассмотреть транспортное шифрование (TLS/SSL на клиентской стороне или межсерверное шифрование), если версия ZooKeeper поддерживает это и ваша инфраструктура это требует. В большинстве реализаций TLS поддержка может требовать дополнительных конфигураций и времени на тестирование.
Практические примеры
1. Практический пример 1: Digest-аутентификация и ограничение доступа к узлу
Сценарий: у вас есть отдельный клиент, который должен иметь право читать и писать в узел /services/config, а другие клиенты — только читать.
Схема аутентификации: digest.
ACL: ограничение на конкретного пользователя, например user1:password1.
Пример кода на Java (с использованием клиента Curator, открытая библиотека):
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.ZooDefs.Perms;
import java.util.ArrayList;
import java.util.List;
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("zk1.example.com:2181")
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
client.start();
// Аутентификация Digest
client.getZookeeperClient().getZooKeeper().addAuthInfo("digest", "user1:password1".getBytes());
// Создание ACL для узла
Id digestId = new Id("digest", "user1:password1");
List<ACL> aclList = new ArrayList<>();
aclList.add(new ACL(Perms.ALL, digestId));
// Создание узла с ACL
client.create().creatingParentsIfNeeded().withACL(aclList).forPath("/services/config", "content".getBytes());
// Другие пользователи могут иметь только READ
Id readDigestId = new Id("digest", "user1:password1");
List<ACL> readAcl = new ArrayList<>();
readAcl.add(new ACL(Perms.READ, readDigestId));
client.setACL().withACL(readAcl).forPath("/services/config", "content".getBytes());
Комментарий: Этот пример иллюстрирует привязку ACL к конкретному пользователю через Digest и ограничение прав. Пользователь с credentials user1:password1 получает полный доступ, другие пользователи — нет, если они не имеют соответствующих ACL.
2. Практический пример 2: World-ACL для безопасного но ограниченного доступа
Сценарий: вы хотите разрешить чтение для большинства клиентов, но писать можно только авторизованным персоналам через индивидуальные ACL. Для разработки можно использовать OPEN ACL на тестовую ветку, а затем перейти кDigest.
Пример кода:
List<ACL> acls = new ArrayList<>(); acls.add(ZooDefs.Ids.OPEN_ACL_UNSAFE); // для тестирования — не рекомендуется в продакшене // Для реального продакшн-случая используйте Digest или SASL.
Пример для защиты на продакшн: используйте Digest в сочетании с конкретными ACL и ограниченной записью. OPEN_ACL_UNSAFE замените на рациональные ACL, например, созданные выше.
3. Практический пример 3: Kerberos/SASL (отечественные решения в рамках крупных организаций)
Сценарий: организация внедряет Kerberos как единую систему идентификации. ZooKeeper аутентифицируется через SASL, используя GSSAPI Kerberos.
Требования:
Включение SASL Authentication Provider в ZooKeeper:
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider requireClientAuthScheme=sasl
JAAS конфигурация (server-side) через файл jaas.conf, например:
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/zk_server.keytab"
storeKey=true
useTicketCache=false
principal="zookeeper/host1.example.com@EXAMPLE.COM";
};
JAAS конфигураия клиента может быть:
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/zk_client.keytab"
storeKey=true
renewalWindow=7200
principal="zookeeper/host1.example.com@EXAMPLE.COM";
};
Пример запуска и тестирования:
- Убедитесь, что Kerberos инфраструктура доступна, билеты получаются (kinit) и что клиент и сервер имеют корректные принципы.
- После настройки вы увидите, что ZooKeeper принимает только аутентифицированные SASL-сессии.
Отечественные контексты: в российских инфраструктурах Kerberos/LDAP часто используется как единая база идентификации в крупных организациях (банковский сектор, телеком и госсектор). Интеграция ZooKeeper через SASL/Kerberos позволяет использовать централизованные профили пользователей и единый аудит доступа. В рамках отечественных проектов такие интеграции обычно сопровождаются дополнительными модулями аудита, журналирования и мониторинга, чтобы соответствовать требованиям регуляторики.
4. Практические рекомендации по внедрению
- Начинать с минимально необходимого набора ACL и постепенно расширять — чтобы не «сломать» существующий функционал.
- Использовать подход «принцип наименьших привилегий»: по возможности задавать только нужные разрешения (READ, WRITE, CREATE, DELETE, ADMIN) конкретным узлам.
- Внедрять аудит и мониторинг изменений ACL. Следить за тем, какие пользователи и какие пары логин/ключи используются для аутентификации.
- Разделение схем. Одно дерево может использовать digest, другое — SASL, если это оправдано архитектурой и требованиями к безопасности.
- Планировать миграции ACL. При изменении политики доступа можем столкнуться с необходимостью обновлять ACL на большом наборе узлов; заранее тестируйте миграции на песочнице.
- Обеспечивать конфигурационную консистентность по всем нодам в кластере: одинаковые параметры аутентификации, одинаковые JAAS-настройки и одинаковое состояние сертификатов/ключей (для Kerberos).
- В случае продвижения в продакшн, протестировать под нагрузкой: время авторизации может вырасти, если ACL сложные или если используется SASL с Kerberos.
Резюме по конфигурации и настройке
Основные принципы
- ACL — список прав и идентификаторов.
- Схемы аутентификации — digest, world, auth, ip, host, sasl.
- Роль параметров zoo.cfg для безопасности: authProvider.1, requireClientAuthScheme и т.д.
Конфигурационные параметры
- authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider — включает SASL-поддержку и аутентификацию через Kerberos (SASL/GSSAPI) для клиентов и сервера.
- requireClientAuthScheme=sasl — просит клиентов подключаться через SASL (Kerberos) для защищенной аутентификации.
- JAAS-конфигурации — для сервера и клиента. Файлы jaas.conf содержат секции Server и Client (пример приведен выше).
Пример простого пищевого шага:
- Использование Digest-подхода без внешних IAM.
- Добавление authInfo на клиенте: client.addAuthInfo("digest","user1:password1".getBytes()).
- Присвоение ACL через ACL-объекты на путь:
Id digestId = new Id("digest","user1:password1");
List<ACL> aclList = new ArrayList<>();
aclList.add(new ACL(Perms.ALL, digestId));
zk.create("/services/config", data, aclList, CreateMode.PERSISTENT);
Демонстрационные команды для тестирования ACL
Получение ACL для узла:
zkCli.sh getAcl /services/config — вернет текущий ACL.
Изменение ACL на существующем узле:
setAcl /services/config newAclList
Проверка доступности для конкретного пользователя:
- Сначала аутентифицируйтесь через Digest или SASL, затем выполните чтение/запись на соответствующий узел.
Пример ухода по пути с различными ACL:
- Создать дочерний узел с свой ACL, например, /services/config/secret1 с Digest
- Использовать ADMIN, CREATE, WRITE и т.д. в ACL, чтобы определить доступ для каждой операции.
Примечания по безопасности
- Digest: хранение паролей в конфигурациях должно быть безопасным, избегайте хранения в открытом виде в коде. Лучше хранить только digest и соответствующим образом ограничивать доступ к ним.
- SASL/Kerberos: это требует централизованной инфраструктуры идентификации (KDC). Важно обеспечить корректную настройку JAAS и правильную работу ключевых tab-ов и билетов.
- Источник аутентификации: встраивание внешних IAM в ZooKeeper повышает управляемость и аудит. Но требует надлежащего мониторинга и обновления сертификатов, ключей и билетов.
- Бэкапы ACL. В случае редких ситуаций ACL можно потерять доступ, поэтому обязательно держите план восстановления и документированную процедуру восстановления доступа к узлам.
Риски и ограничения
- Риск блокировки доступа. Неправильная настройка схемы аутентификации или ACL может привести к ситуации, когда даже администратор не может войти. Важно иметь тестовую среду для проверки изменений.
- Усложнение инфраструктуры. Включение SASL/Kerberos и JAAS конфигураций требует дополнительных знаний и процессов, включая управление ключами, билетами и файл конфигурации.
- Производительность. Аутентификация и проверка ACL прибавляют задержку к операциям. На очень больших деревьях и при частых изменениях ACL нагрузка может стать заметной.
- Совместимость. Разные версии ZooKeeper и клиенты могут иметь различия в поддержке схем аутентификации, особенно в отношении Kerberos и SASL. Всегда тестируйте совместимость между версиями.
- Безопасность кроме ACL. ACL и аутентификация защищают доступ к данным в ZooKeeper, но не обеспечивают целостность трафика между клиентом и сервером, если не задействованы криптографические протоколы транспортного уровня. Рассмотрите возможность использования TLS для транспортного уровня, если ваша версия ZooKeeper это поддерживает и необходима защита трафика.
- Аудит и мониторинг. Без журналирования невозможно полноценно отслеживать попытки доступа. В крупных системах полезна интеграция с SIEM и аудитом событий аутентификации и ACL.
Безопасность ZooKeeper — многогранная задача, включающая понятие ACL, аутентификации и авторизации. ACL позволяют точно определить, кто может что делать на конкретных узлах дерева конфигурации, а схемы аутентификации — определить способ идентификации пользователей и сервисов. В зависимости от размера и требований вашей инфраструктуры можно использовать Digest для упрощенной политики доступа на небольших проектах, или SASL/Kerberos (Kerberos через JAAS) для крупных корпоративных сред с единым источником удостоверений. В любом случае рекомендуется начинать с минимально необходимых ACL, постепенно расширяя их, внедрять аудит и мониторинг, тестировать миграции и внимательно планировать переходы между схемами. Учитывая отечественную практику, Kerberos/LDAP часто используется в рамках комплексных IAM-решений, связанных с банковскими и госструктурными проектами, что обеспечивает единый вход и централизованный аудит.
FAQ — Вопрос–Ответ
1) Что такое ACL в ZooKeeper и зачем они нужны?
ACL — это список правил доступа к узлу znodes. Каждая запись ACL связывает идентификатор и набор разрешений (READ, WRITE, CREATE, DELETE, ADMIN). ACL позволяют ограничить доступ к данным в дереве ZooKeeper, разделить права между сервисами и пользователями, предотвратить несанкционированные изменения конфигураций и состояний.
2) Какие схемы аутентификации поддерживает ZooKeeper и как выбрать подходящую?
ZooKeeper поддерживает digest, world, auth, ip, host, SASL (Kerberos) и другие схемы. Digest подходит для простых сценариев и небольших команд. SASL/Kerberos — для крупных предприятий с централизованным управлением идентификацией. World или IPи Host-основанные схемы обычно применяют как дополнительную фильтрацию, но не как основной механизм безопасности. Выбор схемы следует осуществлять в зависимости от архитектуры вашей организации и требований к аудиту.
3) Что такое Digest и как он работает в ACL?
Digest — это схема, основанная на паре «имя пользователя:пароль» и хэшировании пароля на стороне сервера. В ACL Digest-пользователь определяется как Id("digest", "user:password"). Сервер сравнивает digest, полученный от клиента, с тем, что закодирован в ACL. Digest подходит для локальных сценариев, когда нет внешнего центра удостоверений, но требует безопасного обращения с паролями и их хранением.
4) Как устроен Kerberos/SASL в ZooKeeper и зачем он нужен?
SASL/Kerberos обеспечивает централизованную и масштабируемую аутентификацию. Клиенты и серверы обмениваются билетами Kerberos (TGT/Service Tickets) и проходят аутентификацию через GSSAPI. Это позволяет иметь единый источник удостоверений, упрощает аудит и управление доступом в больших кластерах.
5) Какие риски возникают при внедрении ACL и аутентификации?
Риски включают: риск блокировки доступа из-за неверной конфигурации; усложнение инфраструктуры от внедрения SASL и JAAS; производительная нагрузка на авторизацию; риск утечки паролей/digest-значений и возможность обхода ACL при неправильной настройке; недостаточный аудит и мониторинг.
6) Какие практические шаги помогут избежать ошибок при настройке ACL?
- Начинайте с минимально необходимого набора ACL и тестируйте в песочнице.
- Используйте концепцию принципа наименьших привилегий.
- Внедрите аудит изменений ACL и обнаружение несанкционированного доступа.
- Внедрите централизованную IAM-подсистему (SASL/Kerberos или Kerberos/LDAP) с JAAS-конфигурацией.
- Планируйте миграции ACL и регулярно тестируйте перенос данных и прав.
7) Какие открытые и отечественные примеры помогут в реализации?
- Открытое решение: Digest-ACL с использованием Curator и стандартными ACL в ZooKeeper. Пример с Digest-парой «user:password» и созданием защищённых узлов.
- О отечественных контекстах: Kerberos/SASL интеграции широко применяются в крупных организациях. В российских ИТ-проектах подобные интеграции обычно дополняют LDAP/AD и внутренние IAM-решения, чтобы обеспечить единый вход и аудит, а также соответствие регуляторике. В данных сценариях ZooKeeper взаимодействует через SASL и JAAS-конфигурацию, что позволяет централизованно управлять билетами и привилегиями.
8) Какие шаги тестирования безопасности стоит выполнить перед выводом в продакшн?
- Протестируйте доступность ACL на разных путях и уровнях.
- Выполните тесты на попытки несанкционированного доступа.
- Проведите нагрузочные тесты на аутентификацию и авторизацию, чтобы увидеть влияние на задержки.
- Проведите аудит и верификацию журналирования доступов.
- Проверьте совместимость версий клиента и сервера и корректность JAAS-конфигураций.
- Обеспечьте резервирование ключей, куки и билетов; настройте планы восстановления доступа.
9) Что делать, если забыли пароль Digest или потеряли ключи Kerberos?
- Для Digest: если вы забыли пароль, вам потребуется обновить ACL для нужного узла, добавить нового пользователя или изменить пароль. Обычно рекомендуется иметь резервную копию ACL и отдельный административный пользователь.
- Для Kerberos: обратитесь к администратору Kerberos/AD, чтобы выдали новый билет или обновили ключи в keytab. Обычно это делается через обновление keytab файлов на серверах и клиентах, а также перезапуск соответствующих служб ZooKeeper.
10) Как мониторить безопасность ZooKeeper в целом?
- Включить аудит по доступу к важным узлам и событиям аутентификации.
- Мониторить логи аутентификации и ACL-изменений.
- Подключить SIEM для корреляции попыток доступа и аномалий.
- Регулярно проверять состояние JAAS-конфигураций, ключей и билетов Kerberos.
- Проводить периодические аудиты прав доступа и ротацию учетных данных.
Обращаем внимание: приведённые примеры кода и конфигурации являются иллюстративными; в реальном проекте адаптируйте их под ваши версии ZooKeeper, клиента и инфраструктуру безопасности. При работе с отечественными решениями обратите внимание на регуляторные требования и специфику вашей организации: в крупных российских компаниях управляющие политики доступа связаны с LDAP/AD, Kerberos и корпоративными IAM-решениями, что позволяет централизовать аутентификацию и аудит.



