Глава 15. Безопасность LDAP

  1. Обзор безопасности LDAP
  2. Настройка SASL в OpenLDAP
  3. Настройка SASL — TLS в OpenLDAP
  4. Настройка TLS в OpenLDAP
  5. Настройка смешанного доступа TLS/SSL в OpenLDAP

Обзор безопасности LDAP

У LDAP, и особенно у OpenLDAP, есть ряд возможностей обеспечения безопасности, которые на первый (да и на второй и третий) взгляд могут показаться немного сложными. Рисунок 15-1 показывает общую картину проблемы, перед тем как углубиться в детали. Далее демонстрируются различные методы доступа и интерфейсы к LDAP-системе, а затем описываются проблемные вопросы безопасности и доступные методы управления рисками. Цель данного упражнения — либо определиться с набором политик безопасности, либо выделить приоритеты реализации.

Обзор безопасности

Рисунок 15-1. Общая картина вопросов обеспечения безопасности

Все номера, встречающиеся в описании ниже, ссылаются на рисунок 15-1.

  1. Взаимодействие с удалёнными абонентами (1): Обеспечение безопасности при взаимодействии с удалёнными абонентами может как быть, так и не быть проблемным вопросом. При предоставлении неограниченного (анонимного) доступа к неконфиденциальной LDAP-информации вопросы обеспечения безопасности не ставятся. Внимание: в этих условиях Ваш сервер всё равно становится потенциальным объектом DoS/DDoS-атак посредством нагрузки его вредоносными LDAP-запросами. Таким образом, даже такая на первый взгляд тривиальная реализация может потребовать тщательного проектирования.

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

    Когда взаимодействие с LDAP осуществляется через ненадёжные сети, у деструктивных личностей в сети сразу находится, чем заняться: будьте готовы к тому, что перехваты, отслеживания, атаки типа "человек посередине" ("man-in-the-middle") и т.п. будут постоянным явлением. Также имейте в виду, что использование онлайн-конфигурации OLC (cn=config) и функций мониторинга (cn=monitor) может привести к тому, что LDAP-браузеры станут обычным инструментом для удалённого администрирования и управления LDAP-серверами. А этот трафик по своей природе невероятно конфиденциален.

    Если решено, что некоторый уровень обеспечения безопасности всё же необходим, то первый вопрос, возникающий в этом случае: нужно ли нам защищать только пароли (1-1), или нужно защищать и данные (1-2), и пароли (1-1)? В зависимости от ответа на этот вопрос будут определяться наши следующие шаги.

  2. Пароли (1-1): Не следует путать защиту паролей во время передачи по сети с защитой их в конфигурационных файлах или в DIT. Даже если Вы защитили все пароли в конфигурационных файлах или в DIT с помощью методов хэширования, таких как {SSHA}, при отправке пароля клиентом серверу для аутентификации он посылается в открытом виде, хэшируется на сервере и сравнивается с хранимым значением. Без принятия дополнительных мер он, таким образом, может быть перехвачен (или отслежен, в зависимости от ваших предпочтений к подобным терминам). Примечание: Когда клиент запрашивает запись, содержащую, скажем, атрибут userPassword, значение которого захэшировано, допустим, по алгоритму {CRYPT}, то этот пароль посылается не в открытом виде, а в своей хэшированной форме (то есть в той, в которой он хранится). Однако, когда осуществляется доступ от имени этой же самой записи, клиент посылает пароль (с помощью которого он проходит аутентификацию) в открытом виде, и, естественно, если аутентификация прошла успешно, перехватывающий может вполне резонно предположить, что посланный в открытом виде пароль был верен.

    При пересылке хэшированных паролей в потоке данных, который может подвергнуться перехвату, они становятся уязвимыми к атакам по словарю — получив хэшированный пароль, атакующий прогоняет список паролей (так называемый словарь) через алгоритм хэширования, пока не найдёт совпадения. Использование соли (одного или нескольких байт, — в зависимости от реализации, — добавляемых к паролю перед хэшированием и отбрасываемых перед сравнением) значительно повышает безопасность хэшированных паролей, и, если у Вас нет веских причин к обратному, нужно всегда использовать форму того или иного алгоритма хэширования с солью. Нужно также использовать ACL для предоставления доступа к паролям только определённому кругу авторизованных пользователей. Например, подразумевая, что пароли хранятся в атрибуте userPassword, следующий ACL будет разрешать доступ к данному атрибуту только владельцу записи и определённой группе пользователей (admin):

    # Форма OLC (cn=config)
    olcAccess: to attrs=userpassword
     by self       write
     by anonymous  auth
     by group.exact="cn=admin,ou=groups,dc=example,dc=com" write
     by *          none
    
    # Формат slapd.conf
    access to attrs=userpassword
     by self       write
     by anonymous  auth
     by group.exact="cn=admin,ou=groups,dc=example,dc=com" write
     by *          none
    

    Если требуется защитить только пароли, то решением может стать использование SASL с каким-либо алгоритмом (например CRAM-MD5), обеспечивающим выполнение безопасного диалога подключения (с помощью общей секретной последовательности), во время которого пароли никогда не передаются в открытом виде (примеры конфигурации SASL). Альтернативой может стать использование TLS/SSL (с или без SASL) или Kerberos 5. В этом случае можно использовать простые механизмы паролей, поскольку весь обмен по сети шифруется, и потому не может быть подвержен перехвату.

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

  3. Данные (1-2): Если данные, поступающие от LDAP-сервера, требуется защитить от перехватов, единственным решением становится шифрование всего потока данных с помощью TLS/SSL (с SASL или без SASL) или Kerberos (SASL). Обратная сторона такого подхода заключается в том, что шифрование интенсивно использует процессор, и если потребление ресурсов и производительность являются основными критериями, то выбор подходящего метода шифрования из доступных в пакете TLS/SSL становится очень ответственным решением (смотрите конфигурирование TLS/SSL и конфигурирование TLS/SSL через SASL). Существует возможность смешивать и сочетать различные методы при передаче информации по сети. Например, приемлемой может оказаться такая ситуация: для обычного удалённого доступа к LDAP используются простые пароли в открытом виде (или даже анонимный доступ), но для некоторых классов пользователей требуются дополнительные меры защиты (примеры конфигурации для смешанного доступа TLS/SSL и SASL смотрите здесь).

    До сих пор мы обсуждали вопросы только простого получения доступа к данным. А как насчёт изменения или модификации этих данных? OpenLDAP предоставляет две возможности для ведения аудита: наложение auditlog (для получения дополнительной информации смотрите man-страницу slapo-auditlog) и наложение accesslog. У обоих есть функции журналирования изменений, вносимых в рабочее DIT, а у accesslog даже есть возможность помещать в журнал информацию о подключениях, доступах для чтения/поиска, а также предыдущее содержимое записей или атрибутов.

  4. Локальный доступ (2): Под локальным доступом подразумеваются любые события, происходящие непосредственно на LDAP-сервере или кластере серверов (либо посредством защищённого удалённого доступа к серверу с помощью, например, ssh). Наиболее очевидно, под эту категорию попадают манипуляции с конфигурационными файлами/директориями (2-1) и локально выполняемые команды (2-2).

  5. Конфигурационные файлы (2-1): Здесь мы должны рассмотреть два компонента:

    1. Владельцы и права: По умолчанию, современные системы LDAP работают от имени учетных записей пользователя/группы с ограниченными привилегиями (обычно ldap:ldap). OpenLDAP загружается с правами root (чтобы открыть привилегированные порты), а затем очень быстро переходит к работе со своими нормальными (низкими) рабочими привилегиями. При использовании OLC (cn=config) OpenLDAP требует, чтобы у содержимого конфигурационной директории были права как минимум 0750 для учётной записи, от имени которой он будет работать (обычно ldap:ldap), однако самостоятельно соответствующие привилегии он не выставляет. Это поведение отличается от работы с конфигурационным файлом slapd.conf, которому автоматически назначаются права 0600.

    2. Пароли: Пароли, встречающиеся в директориях slapd.d (при использовании OLC (cn=config)) и конфигурационном файле (slapd.conf), такие как olcRootPw/rootpw, относятся к категории особо конфиденциальных. Лучше вообще полностью удалить и olcRootDn/rootdn, и olcRootPw/rootpw после того, как DIT было запущено в эксплуатацию. Ну и, конечно, все пароли следует хранить в хэшированной форме для предотвращения случайной компрометации (это должно оговариваться на уровне политики безопасности).

  6. Команды (2-2): Исторически LDAP администрировался через локальный интерфейс, в основном из командной строки. Предполагалось, что локальный (внутрисерверный) трафик не подвержен отслеживанию, и потому даже применение простых паролей в открытом виде считалось адекватной мерой защиты для большинства административных сервисов. Однако, как отмечалось выше, увеличение количества реализаций каталогов с конфигурацией времени исполнения (OLC, cn=config) и мониторингом (cn=monitor) может означать, что удалённые LDAP-браузеры становятся нормой в вопросах администрирования LDAP-систем. В этом случае доступ к указанным сервисам порождает передачу по сети информации высокой степени важности, которую необходимо защищать с помощью специальных технологий обеспечения безопасности данных, таких как TLS/SSL.

    Наконец, поскольку при конфигурации времени исполнения все настройки хранятся в DIT (cn=config), стоит рассмотреть использование мощных возможностей наложения accesslog — инструмента генерации журнала для аудита изменений, вносимых в данное DIT.

  7. DIT (3): Безопасность DIT определяется моделью безопасности LDAP и реализуется исключительно при помощи olcAccess/access to Права должны ограничиваться насколько это возможно более строго, и ACL должны тестироваться с помощью slapacl после каждого изменения.

  8. Репликация (1-3): Даже если обычный клиентский доступ к LDAP-системе не требует серьёзных мер безопасности, иная ситуация может быть при репликации того же DIT. Во время цикла репликации на том или ином этапе все данные в DIT (пользовательские и операционные атрибуты) будут передаваться по сети. Вероятно, часть этой информации будет весьма важной. Сетевое взаимодействие при репликации заслуживает отдельного рассмотрения. Вы можете настроить смешанное соединение TLS/SSL и другого защищённого (или даже незащищённого) типа к одному серверу (смотрите примеры конфигурации смешанного доступа TLS/SSL и SASL здесь).

Наверх

Настройка SASL в OpenLDAP

Мы закончим этот раздел уже совсем скоро (one day real soon now ™)

Наверх

Настройка SASL TLS/SSL в OpenLDAP

В руководстве администратора OpenLDAP утверждается, что при использовании TLS с механизмом EXTERNAL SASL и клиенту, и серверу необходимо иметь действительный сертификат X.509. Если это правда, то мы получаем излишне сложную конфигурацию, а уровень безопасности повышается незначительно, и потому в большинстве случаев её использование представляется сомнительным (но есть заметные исключения, такие как репликация). В настоящее время подробно обсуждать это мы не будем.

Наверх

Настройка TLS/SSL в OpenLDAP

Обзор

TLS (Transport Level Security) — это просто название стандартизированной IETF версии Secure Sockets Layer (SSL) от Netscape. Практически нет никаких различий между SSL(v3) и TLS(v1), и в этой документации данные термины считаются синонимами. TLS/SSL поддерживается OpenLDAP начиная с версии 2.1.

Обычно для работы TLS/SSL требуется сертификат X.509 (более известный как сертификат SSL), который можно приобрести в коммерческом центре сертификации или удостоверяющем центре (Certificate Authority, CA), либо это может быть самоподписанный сертификат. В этой документации дано пошаговое руководство по созданию самоподписанных сертификатов, а также, в случае необходимости, приводятся дополнительные замечания по использованию коммерческих сертификатов.

Сессия TLS/SSL начинается с переговоров о выборе набора шифров, включающего в себя шифр обмена ключами, шифр для шифрования данных и алгоритм MAC (Message Authentication Code, представляет собой хэш). Шифр для шифрования данных или массового шифрования (который всегда является симметричным шифром, использующим вычисленный ключ сессии) и MAC используются при передаче данных и потребляют значительно меньше ресурсов CPU, чем шифр обмена ключами (асимметричный шифр, например RSA или DSA/DSS), применение которого ограничивается посылкой ключа pre-master (на основании которого вычисляется ключ сессии) в начале обмена.

При использовании с контекстом TLS термин аутентификация указывает только на аутентификацию сервера (с помощью сертификата X.509), его не следует путать с аутентификацией LDAP, используемой для контроля доступа к DIT. При защите сессии с помощью TLS/SSL аутентификация LDAP с использованием простого (simple) механизма подсоединения становится полностью безопасной, поскольку, не смотря на то, что пароли отправляются открытым текстом, они инкапсулируются в шифрованный поток данных, таким образом, при пересылке как по доверенным, так и по недоверенным сетям, перехват (прослушивание) данных становится невозможным.

Приводимые ниже конфигурации не дают исчерпывающего описания всех возможностей использования TLS с LDAP. Скорее, они представляют собой те варианты конфигурации, которые охватывают наиболее часто встречающиеся ситуации, и, надеемся, поддаются относительно простому внедрению даже со скромным уровнем знаний в области TLS/SSL и сертификатов X.509. Однако, если пользовательские требования выдвигают какие-то специфические условия, могут понадобиться более глубокие знания. Тогда Вам может быть полезно это руководство по выживанию, дающее жуткие подробности протокола TLS/SSL, форматов сертификатов X.509 и генерации самоподписанных сертификатов для использования в различных условиях.

Процесс инициации сессии TLS может происходить одним из двух способов:

  1. Автоматически: Если клиент использует LDAP URL в форме ldaps://hostname/, то диалог TLS инициируется автоматически (обе стороны ожидают элементов протокола TLS/SSL) на порту по умолчанию для ldaps 636. Порт по умолчанию для ldaps может быть изменён на альтернативный путём использования URL в форме ldaps://hostname:port/, при этом сервер должен быть настроен на приём соединений на этом альтернативном порту (с помощью параметра -h при запуске slapd). Чтобы окончательно всех запутать, можно даже указать в качестве альтернативного ldaps порта 389-й (то есть нормальный порт ldap), при этом даже не придётся перенастраивать фаервол. Даже в этом случае диалог TLS будет по-прежнему инициироваться автоматически благодаря использованию схемы ldaps в URL.

  2. Согласно определению: LDAP также может быть настроен на приём соединений TLS/SSL на стандартном порту LDAP при использовании URL ldap://hostname (порт по умолчанию — 389, но это можно изменить). В этом случае клиент должен быть явно запрограммирован (или ему должно быть указано) использовать последовательность StartTLS (сообщение с запросом расширенной операции с OID элемента управления StartTLS 1.3.6.1.4.1.1466.20037). Например, при использовании syncrepl с TLS и URL в форме ldap://hostname/ ДОЛЖЕН быть задан параметр starttls=yes или starttls=critical (если же используется URL в форме ldaps://hostname/, задавать его не обязательно).

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

  1. Для вызова защищённого соединения в настройках клиента TLS должна всегда использоваться схема ldaps. Это упрощает настройку клиента и даёт понять пользователям, что они получают доступ к защищённому серверу, аналогично тому, что при доступе к защищённому web-сайту используется схема https.

  2. Серверы TLS должны иметь сертификаты X.509. Предполагается, что у клиентов TLS, напротив, НИКОГДА НЕТ сертификатов X.509, то есть атрибут olcTlsVerifyClient (директива TLSVerifyClient) всегда имеет значение по умолчанию never. Существуют обстоятельства, например, конфигурация потребителя репликации в стиле syncrepl (или поставщика при репликации с несколькими главными серверами), когда взаимная аутентификация может быть необходима, однако в нашей политике подразумевается, что это лишь исключение, а не общее требование. После того, как конфигурация TLS-сервера полностью отлажена и он находится в рабочем состоянии, относительно просто добавить взаимную TLS-аутентификацию, тем более, что пользователь уже будет хорошо знаком с основными механизмами безопасности. Если же начинать с такой конфигурации, пользователь просто столкнётся с множеством ошибок, разочарований, метаний из стороны в сторону, либо погрязнет в бесконечном количестве новой информации. Лучше наращивать сложность шаг за шагом.

  3. Всегда используются только самоподписанные сертификаты (и процесс их генерации подробно документирован). Это сделано по двум причинам: во-первых, самоподписанные сертификаты имеют неоценимое значение в процессе тестирования, так как они ничего не стоят и предоставляют дополнительные знания о использовании и функциональности X.509; во-вторых, преимущество от приобретения и использования с LDAP коммерческих сертификатов на данном этапе невелико. В этом отношении есть отличие от web-серверов, клиенты которых (браузеры) изначально оснащены несколькими коммерческими CA (корневыми) сертификатами, а также подсветкой адресной строки (жёлтой для сертификатов SSL или зелёной для сертификатов EV), подтверждающей подлинность сайта, что позволяет пользователю чувствовать себя комфортно, и потому может принести коммерческую выгоду. В случае же с LDAP мы пока не нашли ни одного клиентского дистрибутива с предустановленными коммерческими CA (корневыми) сертификатами. Для установки в LDAP-клиент CA (корневого) сертификата потребуется предпринять некоторые усилия, при этом нет никакой разницы по сложности установки коммерческого или самоподписанного сертификата — различается только их стоимость. Тем не менее, многие пользователи предпочтут установить коммерческие сертификаты X.509, и потому, если имеются различия в установке, мы их обязательно опишем.

  4. Для аутентификации и обмена ключами используются только асимметричные алгоритмы RSA (Rivest, Shamir и Adleman). В целом, работать с ними значительно проще. Хотя в некоторых случаях может потребоваться применение алгоритмов DSA (Digital Signature Architecture), например, в правительственных интересах, в настоящее время они используются не так широко, как RSA. Вопросы применения DSA будут рассматриваться в разделе примечаний в конце описания каждой конфигурации.

В первой из представленных конфигураций подразумевается, что LDAP-сервер будет принимать только TLS-соединения с использованием схемы ldaps. Все остальные попытки доступа к серверу будут отклоняться. В ещё двух представленных конфигурациях сервер поддерживает смешанный TLS (ldaps) и не-TLS трафик LDAP.

Настройка защищённого (только TLS соединения) сервера (и клиентов) OpenLDAP

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

LDAP-серверу требуется принимать только защищённые TLS-соединения от клиентов с проверкой подлинности LDAP. Поддерживается единственное пользовательское DIT с включённой службой репликации — то есть данный сервер использует наложение syncprov, кроме того, требуется доступ к сервисам cn=monitor и cn=config. Во всех случаях используются самоподписанные сертификаты (с соответствующими замечаниями по использованию коммерческих сертификатов).

  1. Генерация сертификатов LDAP-сервера и CA: На данном этапе будет сгенерирован самоподписанный сертификат — если будет использоваться коммерческий сертификат X.509 (SSL), данный процесс не требуется и может быть полностью пропущен. Для генерации единого сертификата X.509, который может применяться и для проверки подлинности сервера, и в качестве CA (корневого) сертификата для клиента, используется простой метод в одну команду. Данный метод детально (со всеми диалогами) документирован здесь. Последовательность команд:

    # создаём новые директории (опционально)
    mkdir /certs
    mkdir /certs/keys
    cd /certs
    # создаём сертификат сервера/CA и закрытый ключ без парольной фразы
    # действительный в течение 10 лет, использующий текущие рекомендации RSA по размеру ключа
    # RSA используется в качестве протокола обмена ключами
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 
      -keyout keys/ldapskey.pem -out ldapscert.pem
    
    # сертификат может использоваться в качестве сертификата сервера или сертификата CA 
    # помещаем сертификат в:
    /certs/ldapscert.pem 
    # помещаем закрытый ключ в:
    /certs/keys/ldapskey.pem
    
    # устанавливаем права доступа
    chown -R ldap:ldap /certs/*
    chmod 0400 keys/ldapskey.pem
    

    Примечания:

    1. Полное объяснение параметров команды openssl смотрите здесь.
    2. У файлов ключей обычно есть парольная фраза (пароль) для защиты конфиденциальных данных. Если сертификат генерируется для сервера, подобная парольная фраза никогда не используется (её генерация подавляется аргументом -nodes).
    3. В зависимости от требований, предъявляемых к сертификату, могут использоваться другие методы генерации самоподписанных сертификатов, описанные здесь.
  2. Добавление настроек TLS в OLC (cn=config): Атрибуты настройки TLS требуется добавить в запись глобальных настроек (строки, начинающиеся с символа #, приведены только для пояснения, их можно удалить):

    # cn=config base (global section)
    
    dn: cn=config
    changetype: modify
    # Безопасность - раздел TLS
    add: olcTLSCertificateFile
    olcTLSCertificateFile: /certs/ldapscert.pem
    -
    add: olcTLSCertificateKeyFile
    olcTLSCertificateKeyFile: /certs/keys/ldapskey.pem
    -
    add: olcTLSCipherSuite
    olcTLSCipherSuite: TLSv1+RSA:!NULL
    -
    # значение следующего атрибута установлено так по умолчанию,
    # однако мы приводим его здесь для наглядности
    add: olcTLSVerifyClient
    olcTLSVerifyClient: never
    
    
  3. Альтернативная конфигурация для тех, кто использует slapd.conf: Необходимые директивы TLS добавляются в раздел глобальных настроек:

    # slapd.conf
    # раздел глобальных настроек
    ...
    # Безопасность - раздел TLS
    TLSCertificateFile /certs/ldapscert.pem
    TLSCertificateKeyFile /certs/keys/ldapskey.pem
    TLSCipherSuite TLSv1+RSA:!NULL
    # значение следующей директивы установлено так по умолчанию,
    # однако мы приводим её здесь для наглядности
    TLSVerifyClient never
    ...
    # пользовательское DIT
    database bdb
    suffix "d=example,dc=com"
    ...
    # поставщик репликации
    overlay syncprov
    
    # cn=config DIT
    database config
    rootdn="cn=admin,cn=config"
    rootpw ....
    
    # cn=monitor DIT
    database monitor
    rootdn="cn=admin,cn=monitor"
    rootpw ....
    
    

    Примечания:

    1. Дополнительная информация по TLSCipherSuite здесь. Используемые параметры исключают применение NULL-шифров (без шифрования). TLSv1 охватывает SSLv3. Разрешены EXPORT-шифры — допускаются международные подключения. Если вопросы производительности и нагрузки стоят остро, лучше явно задать список шифров с приемлемыми характеристиками производительности и загрузки системы, чем оставлять возможность произвольного выбора шифра во время переговоров TLS/SSL.
    2. Конфигурация DSA: скоро будет.
  4. Блокировка сервера: (замечания по cn=config смотрите в конце раздела). Согласно выдвинутым требованиям, данный сервер будет поддерживать только соединения TLS. По этой стратегии сервер не будет ожидать подключений для стандартного трафика с LDAP URL (порт 389), ожидаются только подключения с LDAPS URL. Кроме того, вводится пара простых правил безопасности, требующих обязательного выполнения простого подсоединения (bind) при подключении и предотвращающих анонимное подключение. Косвенный эффект такой политики — запрет анонимных подключений с LDAP URL к rootDSE и некоторые другие интересные вещи. Для высокозащищённых серверов это, вероятно, оправданный шаг. Для достижения аналогичных целей можно было бы использовать директивы access to, однако, поскольку ACL игнорируются при подключении от имени rootdn (например, в случае с cn=config и cn=monitor), эффект от их применения ограничен. Данный метод применяется в конфигурации смешанного доступа и описан здесь. Наконец, при запуске LDAP-сервера ему указывается принимать соединения только на порту по умолчанию для LDAPS URL 636 (смотрите примечания ниже). Итак, начнём. Во-первых, внесём дополнительные настройки в slapd.conf (добавляются директивы disallow, require и security):

    # slapd.conf
    # раздел глобальных настроек
    ...
    # Безопасность - раздел TLS
    TLSCertificateFile /certs/ldapscert.pem
    TLSCertificateKeyFile /certs/keys/ldapskey.pem
    TLSCipherSuite TLSv1+RSA:!NULL
    # значение следующей директивы установлено так по умолчанию,
    # однако мы приводим её здесь для наглядности
    TLSVerifyClient never
    
    # Безопасность - другие директивы
    # предотвращаем анонимные подключения при любом типе соединения
    disallow bind_anon
    # требуем выполнения операции bind перед доступом к DIT
    require bind
    # Ожидание подключения только на порту ldaps требует использовать TLS/SSL,
    # но не выдвигает требований к минимальной длине ключа.
    # Требования к минимальной длине ключа выдвигает следующая директива:
    security simple_bind=128
    
    # DIT
    database bdb
    suffix "d=example,dc=com"
    ...
    # replica provider
    overlay syncprov
    
    # cn=config DIT
    database config
    rootdn="cn=admin,cn=config"
    rootpw ....
    
    # cn=monitor DIT
    database monitor
    rootdn="cn=admin,cn=monitor"
    rootpw ....
    
    

    Примечания:

    1. cn=config: скоро будет.
    2. Ожидаем подключения только для LDAPS URL: Управление портами, на которых ожидаются подключения, осуществляется с помощью аргумента -h при запуске slapd. По умолчанию данное значение не задаётся, что (обычно) соответствует -h ldap:///. По требованиям данной конфигурации мы должны разрешить только операции ldaps, поэтому при запуске slapd должна использоваться команда:

      slapd -h ldaps:/// -u ldap -g ldap
      

      Чтобы это выполнялось автоматически, необходимо подправить сценарии запуска в linux (/etc/rc.d/init.d/slapd), а в BSD /etc/rc.conf должен содержать такую строку: slapd_flags="ldaps:///".

      Если Вы переживаете о конфигурации фаервола, то LDAPS может быть настроен на использование порта 389 (LDAPS — это схема URL, говорящая о том, что будет использоваться TLS, а не о том, какой будет использоваться порт). В этом случае команда запуска будет такая:

      slapd -h ldaps://:389/ -u ldap -g ldap
      # при подключении ldaps URL должны быть в форме:
      ldaps://ldap.server.name:389
      
    3. Директивы disallow, require и security: Ожидание подключений только на порту (портах) LDAPS приводит к принудительному использованию TLS/SSL при всех соединениях. Никакие другие типы соединений не будут приниматься в данной конфигурации сервера. Чтобы обязать пользователей проходить LDAP-аутентификацию, используется директива require bind, а для предотвращения анонимных подсоединений используется директива disallow bind_anon. Таким образом, чтобы получить какой-либо доступ к DIT, при любом подключении должна выполняться операция подсоединения (bind), и это подсоединение не может быть анонимным. Если указать только директиву security simple_bind=128, это не приведёт к обеспечению требуемого уровня защиты. Данная директива просто говорит: если выполняется простое подсоединение (simple bind), то должно использоваться TLS/SSL. Она не требует, чтобы подсоединение выполнялось обязательно. Единственная цель использования security simple_bind=128 в данной конфигурации — определить минимальное значение SSF. Если это не нужно, данную директиву можно не указывать.
    4. Доступ к rootDSE: Побочный эффект данной политики — запрет анонимного доступа к rootDSE, что, как уже отмечалось, может быть вполне оправдано для защищённых серверов.
    5. Директивы ACL: В данной конфигурации не предусмотрено дополнительных мер безопасности, основанных на применении ACL — безопасность сервера полностью обеспечивается глобальными директивами конфигурации и ограничением подключений только на LDAPS портах. ACL может использоваться для установления необходимого разграничения доступа на основании учётных данных пользователей.
  5. Настройка клиентов: Из требования, что сервер LDAP будет обслуживать только соединения TLS, следует, что все клиенты при подключении должны использовать URL со схемой LDAPS и выполнять проверку сертификата X.509 сервера, для чего требуется доступ к CA (корневому) сертификату. В нашем контексте под клиентами подразумеваются утилиты и инструменты ldap, а также серверы LDAP, на которых выполняется сервис репликации с использованием syncrepl. Очевидно, что, поскольку утилиты и инструменты ldap являются клиентами, они получают свои настройки из файла ldap.conf. Возможно менее очевидно, что LDAP-серверы, на которых выполняется сервис репликации, также являются TLS-клиентами, и потому также получают информацию по CA (корневым) сертификатам из ldap.conf. Конфигурация ldap.conf:

    # скопируйте сертификат, сгенерированный на шаге 1,
    # в подходящее место на клиентской системе 
    # подразумевается: /certs/ldapscert.pem
    
    # добавьте в ldap.conf
    TLS_CACERT /certs/ldapscert.pem 
    

    Конфигурация LDAP-сервера, на котором запущена реплика:

    # slapd.conf
    # раздел глобальных настроек
    ...
    # Безопасность - раздел TLS
    # нет никаких настроек
    
    # реплицируемое DIT
    database bdb
    suffix "d=example,dc=com"
    ...
    # настройки потребителя репликации
    syncrepl
     rid=000
     type=RefreshandPersist
     provider=ldaps://ldap-master.example.com
     bindmethod=simple
     searchbase="dc=example,dc=com"
     retry="5 3 300 +"
     attrs="*,+"
     binddn="...."
     credentials=....
    ...
    
    

    Примечания:

    1. CA (корневой) сертификат, используемый в примере потребителем syncrepl (и определяемый директивой TLS_CACERT в ldap.conf), является тем же самым, что используется и в качестве сертификата сервера поставщиком главного DIT. Это следствие применения метода с единственным сертификатом, который мы использовали для генерации данного сертификата: он функционирует сразу и как сертификат сервера, и как сертификат CA. При использовании других методов генерации самоподписанных сертификатов сертификат сервера и сертификат CA могут быть различными, и, конечно, они всегда различны при использовании коммерческих сертификатов.

    2. Если, как обсуждалось выше, сервис ldaps обслуживается на порту 389 (например, для устранения вопросов блокировки трафика фаерволом), то определение syncrepl будет использовать расширенный формат URL с указанием порта:

      syncrepl 
       ...
       provider=ldaps://ldap-master.example.com:389
       ...
      
    3. LDAP-серверы в качестве TLS-клиентов: Когда сервер LDAP выступает в качестве потребителя репликации syncrepl, он выступает в роли TLS-клиента, и потому ему требуется осуществлять проверку подлинности серверного сертификата с помощью CA (корневого) сертификата, которым он подписан. Поскольку данный сервер выступает в роли TLS-клиента, он будет использовать директивы TLS (и, соответственно, файлы сертификатов TLS), определяемые для клиентов LDAP — в частности, он будет использовать директиву TLS_CACERT в ldap.conf. Клиенту TLS требуется сгенерировать сообщение обмена ключами (key-exchange message), зашифрованное с помощью открытого ключа (public key) сервера, который извлекается из посылаемого сервером сертификата X.509. Также клиент TLS при первоначальной установке соединения по протоколу TLS на этапе ClientHello посылает список разрешенных наборов шифров, который контролируется директивой настройки клиента TLS TLS_CIPHER_SUITE (по умолчанию посылаются все возможные наборы шифров (ALL), что эквивалентно команде openssl ciphers -v ALL). Перед прочтением следующего предложения сделайте глубокий вдох. Если сервер LDAP, являющийся потребителем репликации syncrepl и потому клиентом TLS, также предоставляет доступ к другому DIT (например, к cn=config) и при этом подразумевается, что для контроля этого доступа также необходима поддержка TLS, то он одновременно будет сервером TLS и для него требуется задать все директивы сервера TLS, которые определялись выше на шаге 2 и 3.

Наверх

Настройка смешанного доступа TLS/SSL в OpenLDAP

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

Конфигурация — кто-то использует TLS, кто-то — нет

В данном случае выдвигается требование, что некоторые пользователи будут использовать TLS, а другие — нет. Например, политика может быть следующей:

  1. Разрешён анонимный доступ (и незащищённый обмен данными) к ограниченному набору общедоступных записей LDAP.
  2. Пользователям, прошедшим LDAP-аутентификацию (простое подключение с незащищённым обменом данными) разрешён доступ на чтение к общедоступным записям LDAP, плюс ограниченные права на обновление только той записи, владельцем которой является данный пользователь.
  3. Пользователи с привилегиями на обновление более одной собственной записи должны использовать TLS и проходить аутентификацию (подразумевается, что все они члены группы admins).
  4. Все потребители репликации должны использовать TLS/SSL.
  5. При удалённом доступе к cn=config должен использоваться TLS/SSL.

Данное решение требует применения ACL и директив настройки сервера, как показано ниже:

  1. Генерация сертификатов LDAP-сервера и CA: На данном этапе будет сгенерирован самоподписанный сертификат — если будет использоваться коммерческий сертификат X.509 (SSL), данный процесс не требуется и может быть полностью пропущен. Для генерации единого сертификата X.509, который может применяться и для проверки подлинности сервера, и в качестве CA (корневого) сертификата для клиента, используется простой метод в одну команду. Данный метод детально (со всеми диалогами) документирован здесь. Последовательность команд:

    # создаём новые директории (опционально)
    mkdir /certs
    mkdir /certs/keys
    cd /certs
    # создаём сертификат сервера/CA и закрытый ключ без парольной фразы
    # действительный в течение 10 лет, использующий текущие рекомендации RSA по размеру ключа
    # RSA используется в качестве протокола обмена ключами
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 
      -keyout keys/ldapskey.pem -out ldapscert.pem
    
    # сертификат может использоваться в качестве сертификата сервера или сертификата CA 
    # помещаем сертификат в:
    /certs/ldapscert.pem 
    # помещаем закрытый ключ в:
    /certs/keys/ldapskey.pem
    
    # устанавливаем права доступа
    chown -R ldap:ldap /certs/*
    chmod 0400 keys/ldapskey.pem
    

    Примечания:

    1. Полное объяснение параметров команды openssl смотрите здесь.

    2. У файлов ключей обычно есть парольная фраза (пароль) для защиты конфиденциальных данных. Если сертификат генерируется для сервера, подобная парольная фраза никогда не используется (её генерация подавляется аргументом -nodes).

    3. В зависимости от требований, предъявляемых к сертификату, могут использоваться другие методы генерации самоподписанных сертификатов, описанные здесь.

  2. Добавление директив TLS и ACL в slapd.conf: (замечания по cn=config смотрите в конце раздела). Необходимые директивы TLS добавляются в раздел глобальных настроек:

    # slapd.conf
    # раздел глобальных настроек
    ...
    # Безопасность - раздел TLS
    TLSCertificateFile /certs/ldapscert.pem
    TLSCertificateKeyFile /certs/keys/ldapskey.pem
    TLSCipherSuite TLSv1+RSA:!NULL
    # значение следующей директивы установлено так по умолчанию,
    # однако мы приводим её здесь для наглядности
    TLSVerifyClient never
    ...
    
    # пользовательское DIT
    database bdb
    suffix "d=example,dc=com"
    # нет директив rootdn и rootpw
    # смотрите примечания по обеспечению безопасности доступа от имени rootdn
    ...
    # ACL
    # ACL1 - доступ для потребителя репликации
    # (подразумевается подсоединение от имени cn=replica,dc=example,dc=com)
    # потребителю, использующему TLS, разрешён доступ на чтение ко всему DIT
    # все остальные переходят к ACL2 (break)
    access to *
     by dn.exact="cn=replica,dc=example,dc=com" tls_ssf=128 read
     by * break
    # ACL2 - доступ к атрибуту userpassword
    # анонимные пользователи могут только проходить аутентификацию
    # пользователи, прошедшие аутентификацию, могут модифицировать свои собственные пароли (self)
    # члены группы admins, использующие TLS, могут модифицировать пароли 
    access to attrs=userPassword
     by self         write
     by anonymous    auth
     by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write
    # ACL3
    # ограниченный анонимный доступ только на чтение к поддереву public
    # любые пользователи, прошедшие аутентификацию, могут модифицировать свои
    # собственные записи (self) в пределах поддерева
    # члены группы admins, использующие TLS, имеют право на запись во всём поддереве public
    access to dn.subtree="ou=public,dc=example,dc=com"
     by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write
     by self      write
     by anonymous  read
     by users read
    # ACL4
    # члены группы admins, использующие TLS, имеют право на запись в остальном DIT
    access to * 
     by by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 write
    
    # последний ACL4 слишком прямолинеен - если требуются дополнительные правила,
    # его нужно заменить приведённым ниже, который будет отфильтровывать всех пользователей,
    # не использующих TLS. В данном случае break означает, что если пользователь использует TLS,
    # он переходит к следующему ACL, в противном случае - обработка останавливается.
    # ACL4
    access to * 
     by group.exact "cn=admins,ou=groups,dc=example,dc=com" tls_ssf=128 break
    # ACL5 etc.
    access ....
    
    # поставщик репликации
    overlay syncprov
    
    # cn=config DIT
    database config
    rootdn "cn=admin,cn=config"
    rootpw {SSHA} hfkhfhfldkhlkhh
    # SSF больший или равный 128 используется для обеспечения безопасного доступа к cn=config
    security simple_bind=128
    

    Примечания:

    1. Дополнительная информация по TLSCipherSuite здесь. Используемые параметры исключают применение NULL-шифров (без шифрования). TLSv1 охватывает SSLv3. Разрешены EXPORT-шифры — допускаются международные подключения. Если вопросы производительности и нагрузки стоят остро, лучше явно задать список шифров с приемлемыми характеристиками производительности и загрузки системы, чем оставлять возможность произвольного выбора шифра во время переговоров TLS/SSL.

    2. Конфигурация DSA: скоро будет.

    3. cn=config: скоро будет.

    4. Примечания по ACL:

      1. ACL1: Данный ACL, который можно с тем же успехом поместить в раздел глобальных настроек, разработан с целью вычленить на раннем этапе подключения потребителей репликации (DN cn=replica,dc=example,dc=com должен присутствовать в DIT с соответствующим паролем). by dn.exact="cn=replica,dc=example,dc=com" tls_ssf=128 read содержит два условия, которые работают (хотя явно не документированы), и совпадения по которым будут найдены в том случае, если потребитель успешно прошёл аутентификацию И использовал SSF (TLS) не ниже 128. Для того чтобы потребитель репликации (да и все остальные) смог пройти аутентификацию (или просто получить доступ к DIT), необходимо наличие условия by * break, позволяющего перейти к ACL2 и продолжить анализ подключения.

      2. ACL2: Позволяет любому пользователю, прошедшему аутентификацию, модифицировать свой пароль. Анонимный доступ предоставляется в целях аутентификации (auth). Любой член группы cn=admins,ou=groups,dc=example,dc=com, использующий при подключении TLS, может осуществлять изменения любого пароля.

      3. ACL3: В указанном порядке — любому члену группы cn=admins,ou=groups,dc=example,dc=com, использующему при подключении TLS, разрешено производить запись в любой атрибут любой записи поддерева public базы данных. Анонимным пользователям предоставляется доступ на чтение к поддереву public DIT (за исключением атрибутов userPassword). Пользователю, прошедшему аутентификацию, разрешено изменять любую часть своей записи. Наконец, пользователю, прошедшему аутентификацию (подключающемуся с использованием или без использования TLS), разрешён доступ только для чтения к поддереву public, за исключением атрибутов userPassword (а также за исключением своих собственных записей, контроль доступа к которым был указан в условии self).

      4. ACL4: Только членам группы cn=admins,ou=groups,dc=example,dc=com, использующим при подключении TLS, разрешён доступ на осуществление записи во все остальные части DIT. Всем остальным пользователям запрещён любой доступ (неявное условие by * none).

    5. Ожидаем подключения для LDAPS и LDAP URL: Управление портами, на которых ожидаются подключения, осуществляется с помощью аргумента -h при запуске slapd. По умолчанию данное значение не задаётся, что (обычно) соответствует -h ldap:///. По требованиям данной конфигурации мы должны разрешить как операции ldap, так и ldaps, поэтому при запуске slapd должна использоваться команда:

      slapd -h "ldap:/// ldaps:///" -u ldap -g ldap
      

      Чтобы это выполнялось автоматически, необходимо подправить сценарии запуска в linux (/etc/rc.d/init.d/slapd), а в BSD /etc/rc.conf должен содержать такую строку: slapd_flags="ldap:/// ldaps:///".

    6. Безопасность доступа от имени rootdn: После того, как DIT было первоначально загружено, какие функции выполняет rootdn? Во всех штатных случаях привилегии типа rootdn для DIT могут быть предоставлены какому-либо конкретному пользователю (назовём его псевдо-суперпользователь) с помощью ACL, и потому директиву rootdn можно смело удалять. В хорошо продуманной системе контроля можно предоставить новому псевдо-суперпользователю необходимые полномочия с помощью стандартных ACL — собственно, для этого они и предназначаются. Единственный подводный камень данного подхода — то, что ошибка в ACL может привести к ограничению необходимых полномочий. В худшем случае, rootdn может быть временно восстановлен, а потом удалён вновь, когда проблема будет решена. Лучшим решением обеспечения безопасности доступа от имени rootdn к обычному DIT будет удаление самого rootdn. И точка. Как в приведённой выше конфигурации.

      В тех случаях, когда rootdn является единственным методом доступа, таких как cn=config в приведённом выше примере, для принудительного включения механизмов защиты в конкретном разделе database используется директива security simple_bind=128.

Наверх



Проблемы, комментарии, предположения, исправления (включая битые ссылки) или есть что добавить? Пожалуйста, выкроите время в потоке занятой жизни, чтобы написать нам, вебмастеру или в службу поддержки. Оставшийся день Вы проведёте с чувством удовлетворения.

Нашли ошибку в переводе? Сообщите переводчикам!

Copyright © 1994-2017 ZyTrax, Inc. Все права защищены. Последнее изменение страницы: 21 октября 2015 г.
Переведено участниками проекта Pro-LDAP.ru в 2012-2017 г.