Configure active directory integration

Настройка сервера аутентификации посредством связки kerberos+ldap на базе rosa enterprise linux server

Настройка клиента

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

Для начала отредактируйте файл /etc/nsswitch.conf. Он позволяет настроить изменение учетных данных LDAP при запуске пользователями определённых команд аутентификации.

Найдите в файле строки passwd, group и shadow и отредактируйте их следующим образом:

Затем нужно добавить некоторые значения в настройки PAM.

PAM (или Pluggable Authentication Modules) – это система, которая соединяет приложения, обеспечивающие аутентификацию в тех приложениях, которые требуют проверки подлинности.

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

Отредактируйте файл /etc/pam.d/common-session:

В конец файла добавьте строку:

Это создаст на клиентской машине домашний каталог при подключении пользователя LDAP, у которого нет такого каталога.

Чтобы обновить настройки, перезапустите сервис:

Подключаем поддержку OpenID Connect

Переходим к настройке кластера Kubernetes.

Домен dex.ash.dtln.cloud используем для обращения Dex к API-серверу, а login.ash.dtln.cloud – для получения доступа к кластеру.

Мы разворачивали кластер без установщиков kubeadm или kops, так что OIDC-конфигурацию можно сразу добавлять в systemd-юнит. В остальных случаях настройку лучше сделать с помощью этих утилит.

  1. Редактируем юнит /etc/systemd/system/kube-apiserver.service и добавляем параметры запуска в секцию ExecStart:

    —oidc-client-id=dex-k8s-authenticator \

    —oidc-groups-claim=groups \

    —oidc-issuer-url=https://dex.ash.dtln.cloud/ \

  2. Рестартуем наши API, проверяем, что они поднялись:

    sudo systemctl daemon-reload

    sudo systemctl restart kube-apiserver

    sudo systemctl status kube-apiserver

How Authentication Works in the Reference Implementation

To perform authentication, the http_auth_request module makes an HTTP subrequest to the ldap‑auth daemon, which acts as intermediary and interprets the subrequest for the LDAP server – it uses HTTP for communication with NGINX Plus and the appropriate API for communication with the LDAP server.

We assume that if you’re interested in the reference implementation, you already have an application or other resources you want to protect by requiring authentication. To make it easier to test the reference implementation, however, we’re providing a sample backend daemon, also written in Python, which listens on port 9000. It can stand in for an actual HTTP application during testing, by prompting for user credentials and creating a cookie based on them.

Here’s a step‑by‑step description of the authentication process in the reference implementation. The details are determined by settings in the nginx-ldap-auth.conf configuration file; see below. The flowchart below the steps summarizes the process.

  1. A client sends an HTTP request for a protected resource hosted on a server for which NGINX Plus is acting as reverse proxy.

  2. NGINX Plus (specifically, the http_auth_request module) forwards the request to the ldap‑auth daemon, which responds with HTTP code  because no credentials were provided.

  3. NGINX Plus forwards the request to http://backend/login, which corresponds to the backend daemon. It writes the original request URI to the header of the forwarded request.

  4. The backend daemon sends the client a login form (the form is defined in the Python code for the daemon). As configured by the directive, NGINX sets the HTTP code on the login form to .

  5. The user fills in the Username and Password fields on the form and clicks the Login button. Per the code in the form, the client generates an HTTP request directed to /login, which NGINX Plus forwards to the backend daemon.

  6. The backend daemon constructs a string of the format , applies Base64 encoding, generates a cookie called nginxauth with its value set to the encoded string, and sends the cookie to the client. It sets the flag to prevent use of JavaScript to read or manipulate the cookie (protecting against the cross‑site scripting vulnerability).

  7. The client retransmits its original request (from Step 1), this time including the cookie in the field of the HTTP header. NGINX Plus forwards the request to the ldap‑auth daemon (as in Step 2).

  8. The ldap‑auth daemon decodes the cookie, and sends the username and password to the LDAP server in an authentication request.

  9. The next action depends on whether the LDAP server successfully authenticates the user:

    • If authentication succeeds, the ldap‑auth daemon sends HTTP code to NGINX Plus. NGINX Plus requests the resource from the backend daemon. In the reference implementation, the backend daemon returns the following text:

      The nginx-ldap-auth.conf file includes directives for caching the results of the authentication attempt; to disable caching, see below.

    • If authentication fails, the ldap‑auth daemon sends HTTP code to NGINX Plus. NGINX Plus forwards the request to the backend daemon again (as in Step 3), and the process repeats.

Область применения

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

  • Элемент маркированного списка
  • Идентификация компьютеров
  • Аутентификация пользователей
  • Группировка пользователей (в том числе системные группы)
  • Адресные книги
  • Представление штатно-кадровой структуры организации
  • Учет закрепления имущества организации за сотрудниками
  • Телефонные справочники
  • Управление пользовательскими ресурсами
  • Справочники адресов электронной почты
  • Хранение конфигурации приложений

Хранение конфигурации АТС

Параметры, существующие с Windows Server 2008 R2

Параметр Query Policy – MaxResultSetsPerConn

Что делает

Устанавливает максимальное число хранимых со стороны сервера результатов поисковых запросов клиента. Модифицируем в случае, если у нас очень много параллельных запросов. Фактически, в хостинговых сценариях (например, хостинг Exchange). Кстати, в случае, если Ваш домен был установлен не сразу как Windows 2008 R2, параметр будет равен нулю (что по факту опять-таки превратит его на поддерживающих этот параметр контроллерах в 10).

Что делает

Задаёт минимальное число параллельных запросов для включения режима оптимизации paged-запросов, доступного в NT 6.1. Модифицируем просто – если поставить единицу, тогда режим оптимизации будет инициироваться всегда, и отработка запросов ускорится.

Настройка

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

Возможно потребуется установить как минимум следующие опции:

 <?php
  // общие настройки DokuWiki
  $conf'useacl'         = 1;
  $conf'disableactions' = 'register';
  $conf'authtype'       = 'ad';
 
  // настройки Active Directory
  $conf'auth''ad''account_suffix'     = '@my.domain.org';
  $conf'auth''ad''base_dn'            = 'DC=my,DC=domain,DC=org';
  $conf'auth''ad''domain_controllers' = 'srv1.domain.org, srv2.domain.org'; //через запятую можно перечислить 
                                                                                  //несколько контроллеров домена

Можно указать дополнительные параметры:

  $conf'auth''ad''ad_username'        = 'root';
  $conf'auth''ad''ad_password'        = 'pass';
  $conf'auth''ad''sso'                = 1;
  $conf'auth''ad''real_primarygroup'  = 1;
  $conf'auth''ad''use_ssl'            = 1;
  $conf'auth''ad''use_tls'            = 1;
  $conf'auth''ad''debug'              = 1;
  $conf'auth''ad''recursive_groups'   = 1; // Если в AD содержится много групп, переключение этого параметра 
                                                 // в 0 улучшит скорость работы, но неявное членство в группах перестанет работать

и необходимы для реализации подписки на изменения. Этот аккаунт используется для запроса информации о пользователе из AD.

Для установки прав суперпользователя можно использовать следующую конструкцию:

$conf'manager'   = '@LDAPGROUPNAME';
$conf'superuser' = '@LDAPGROUPNAME';

Любые другие настройки, указанные в $conf, напрямую передаются в библиотеку adldap. Детальное описание этих настроек можно получить в документации по adLDAP.

В комбинации с аутентификацией Single-Sign-On также можно добавить настройки домена Windows. То есть проводить аутентификацию на разных AD в зависимости от домена NTLM или Kerberos конкретного пользователя. Для этого надо использовать название домена (в нижнем регистре) как подключ в . Т.е. для того, чтобы идентифицировать всех пользователей, пришедших из домена Windows через сервер AD, отличный от сервера по умолчанию, нужно добавить следующие строчки в конфигурационный файл:

$conf'auth''ad''foobar''account_suffix'     = '@foobar.domain.org';
$conf'auth''ad''foobar''base_dn'            = 'DC=foobar,DC=domain,DC=org';
$conf'auth''ad''foobar''domain_controllers' = 'otherad.domain.org';
$conf'auth''ad''foobar''ad_username'        = 'otherroot';
$conf'auth''ad''foobar''ad_password'        = 'otherpass';

Если в организации используется система из нескольких контроллеров домена с единым родительским контроллером, может потребоваться указать порт 3268, вместо порта по умолчанию 389. В противном случае DokuWiki может не получить информации о группах пользователей дочернего домена. Самый простой способ сделать это — исправить исходники adLDAP.php, так как все вызовы к ldap_connect содержат порт в качестве отдельного аргумента функции.
5

Вводим CentOS 7 в домен с помощью winbind

Если у вас виртуальная машина, проще установить ее с нуля. Если не хочется по какой-то причине, можно просто удалить все установленные ранее пакеты через команду yum remove. Я поступил именно так.

Устанавливаем недостающие пакеты:

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

Формируем конфиг для kerberos.

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

xs.local название домена
10.1.3.4 ip адрес контроллера домена
xs-winsrv.xs.local полное имя контроллера домена
xs-design имя сервера centos, который вводим в домен
admin51 учетная запись администратора домена

Вывод после работы команды у меня такой:

Это не страшно, продолжаем настройку. Заводим сервер с CentOS в домен:

На выходе получил:

В принципе, ничего страшного. Нам придется самим создать A запись на DNS сервере. Я не понимаю, почему иногда она не создается автоматически. Во время написания статьи, я использовал один сервер, у него не было этой ошибки при вводе в домен. Когда проверял статью на втором сервере, получил эту ошибку. Проверяем на контроллере домена в списке компьютеров наш сервер и создаем руками А запись, соответствующую имени сервера и его IP адресу.

Теперь рисуем конфиг для самбы примерно такой.

У меня русский язык на контроллере домена, поэтому и имена групп на русском. Проблем с этим не возникает. Не забудьте создать директорию /mnt/shara.

Запускаем samba и winbind и добавляем в автозагрузку.

Выполняем ряд проверок, чтобы убедиться, что все в порядке, winbind работает и samba будет получать актуальную информацию о пользователях и группах домена.

Последние две команды должны вывести список всех пользователей и групп домена.

Проверим теперь авторизацию в домене.

В данном случае control — имя пользователя домена, pass — его пароль. Успешная проверка выглядит так, как у меня. В завершении проверок посмотрим, корректно ли система сопоставляет доменные учетные записи локальным.

Все в порядке. Теперь все готово для корректной работы файлового сервера на основе Samba с доменными учетными записями. В завершении настроек, сделаем администратора домена владельцем нашей шары.

Проверяем, что получилось.

Уберем доступ на чтение у всех остальных, оставим полные права для пользователя admin51 и на чтение у пользователей домена.

Идем на любую виндовую машину и пробуем зайти на шару по адресу \\ip-адрес-сервера. Попадаем на нашу шару.Если не получилось зайти, проверьте настройки iptables. На время отладки можно их отключить. Так же убедитесь, что у вас запущена служба smb.service.

Смотрим расширенные параметры безопасности:

Получилось то, что хотели. Управлять правами доступа можно через windows acl с любой машины windows, где учетная запись пользователя домена будет обладать необходимыми правами. Если по какой-то причине это не получится (а я с такими ситуациями сталкивался достаточно часто), на помощь придут консольные утилиты getfacl для проверки прав и setfacl для изменения прав. Документация по этим командам есть в сети и легко ищется. Я рекомендую всегда использовать эти команды, когда вы выполняете изменение прав по большому дереву каталогов. Через консоль выставление прав будет выполнено раз в 5-10 быстрее, чем через windows acl. На больших файловых архивах разница может быть в десятки минут или даже часы.

ldapsearch

ldapsearch is a handy tool that is part of open ldap. You can query some handy information out of our ldap servers as follows if you have an account to bind with:

You may need to set LDAPTLS_REQCERT=allow before those commands.

 #list laser cutter certified:
 ldapsearch -v -x -H ldaps://bob.ad.pumpingstationone.org -b "DC=ad,DC=pumpingstationone,DC=org" -D "PS1\myuser" -W "CN=Laser Engraver Certified"
 #list domain Admins
 ldapsearch -v -x -H ldaps://bob.ad.pumpingstationone.org -b "CN=Users,DC=ad,DC=pumpingstationone,DC=org" -D "PS1\myuser" -W "CN=Domain Admins"

Remember you can use space.pumpingstationone.org if it is outside PS1 network.

Аутентификация в общем случае

Как показано в статьях, аутентификация производится по следующей схеме:

  • Клиент обращается к сервису.
  • Обратный прокси делает перенаправление, если установлен cookie.
  • Если cookie нет, делается запрос к сервису аутентификации.
  • Сервис аутентификации запрашивает логин и пароль, которые проверяет через обращение к LDAP серверу.
  • Если проверка успешна, он устанавливает cookie и выполняет перенаправление на сервис.

Альтернативным вариантом может являться использование компилируемого модуля для nginx, но я данный вариант здесь не рассматриваю с силу некоторых проблем с данным модулем и меньшей его гибкости.

Доработанный образ для OpenLDAP сервера есть здесь.

Настройка Linux для интеграции с AD

Для инте­гра­ции Linux с нашим LDAP (в дан­ном при­ме­ре, на осно­ве Active Directory) уста­но­вим необ­хо­ди­мые паке­ты и настро­им Kerberos.

Установка пакетов

Необ­хо­ди­мые паке­ты ста­вим из репозиториев.

а) на Ubuntu/Debian:

apt-get install heimdal-clients

б) на Centos:

yum install krb5-workstation

Проверка файла

Пере­хо­дим в ката­лог с фай­лом keytab и выпол­ня­ем команду:

kinit -kt spnego.keytab HTTP/[email protected]

* напом­ним, что spnego.keytab — имя наше­го фай­ла; HTTP/[email protected] — прин­ци­пал, для кото­ро­го сге­не­ри­ро­ван файл.

Коман­да нам ниче­го не долж­на вер­нуть. Это зна­чит, что она выпол­не­на корректно.

Теперь выпол­ним:

klist

Использование LDAP

  • Какой тип информации может храниться в директориях? Информационная модель LDAP основана на записях (entry). Запись — это коллекция атрибутов (attribute), обладающая уникальным именем (Distinguished Name, DN). DN глобально-уникально для всего каталога и служит для однозначного указания на запись. Каждый атрибут записи имеет свой тип (type) и одно или несколько значений (value). Обычно типы — это мнемонические строки, в которых отражено назначение атрибута, например «cn» — для общепринятого имени (common name), или «mail» — для адреса электронной почты. Синтаксис значений зависит от типа атрибута. Например, атрибут cn может содержать значение Babs Jensen. Атрибут mail может содержать значение «[email protected]». Атрибут jpegPhoto будет содержать фотографию в бинарном формате JPEG.
  • Как информация храниться в LDAP? Записи каталога LDAP выстраиваются в виде иерархической древовидной структуры. Традиционно, такая структура отражает географические и организационные границы. Записи, обозначающие страны, находятся наверху дерева. Чуть ниже располагаются записи о регионах и организациях. Еще ниже — информация об отделах, людях, принтерах, документах или о том, о чем вы подумаете. Дерево может быть создано, основываясь на доменных именах интернета такое именование позволяет узнать расположение службы директорий, используя Что такое DNS.
  • Как можно обратиться к информации? К записи обращаются по ее уникальному имени, которое состоит из собственно имени записи (так называемое относительное уникальное имя (Relative Distinguished Name, RDN) с прибавлением к нему имён записей-предков. Так, запись, описывающая Barbara Jensen в приведенном выше примере с Internet-именованием, имеет RDN uid=babs, и DN — uid=babs,ou=People,dc=example,dc=com.
  • Что такое slapd и что он может сделать? slapd (Stand-alone LDAP демон) это сервер директорий LDAP. Вы можете использовать его для обеспечения собственного сервера директорий. Ваша директория может содержать любую информацию, которую вы захотите. Вы так же можете подключить свою директорию к глобальной службе директорий LDAP или запустить службу директорий самостоятельно. Некоторые возможности slapd: пункт 1.9., например SASL, TLS (или SSL), поддерживает Unicode и языковые теги.
  • Что такое slurpd и что он может делать? slurpd(8) — демон, который, с помощью slapd(8), обеспечивает работу службы репликаций. Он отвечает за распространение изменений, сделанных в главной БД slapd, на другие БД slapd. Slurpd освобождает slapd от необходимости беспокоится, если другие БД slapd выключены или недоступны, когда произошли изменения в главной БД. Slurpd автоматически повторяет запросы на обновление. Slapd и Slurpd связаны через простой текстовый файл, который используется для записи изменений.

Авторизация на основе групп AD

Ранее, мы предоставили доступ к сети Интернет любому пользователю Active Directory. Теперь ограничим доступ с помощью групп AD DS.

Для начала, создаем 2 группы пользователей, например:

  1. squidusers. Пользователи squid, которым будет предоставлен доступ к сети Интернет с ограничениями.
  2. squidsuperusers. Этим пользователям будет предоставлен неограниченный доступ.

Теперь на прокси-сервере открываем конфигурационный файл squid:

vi /etc/squid/squid.conf

Добавляем после настройки аутентификации:

external_acl_type squid_users_from_ad_krb ttl=300 negative_ttl=60 %LOGIN /usr/lib64/squid/ext_kerberos_ldap_group_acl -g [email protected]
external_acl_type squid_superusers_from_ad_krb ttl=300 negative_ttl=60 %LOGIN /usr/lib64/squid/ext_kerberos_ldap_group_acl -g [email protected]
external_acl_type squid_users_from_ad_ntlm %LOGIN /usr/lib64/squid/ext_wbinfo_group_acl -d

* где 

  • squid_users_from_ad_krb — произвольное название acl, авторизованных пользователей в AD через kerberos, принадлежащих группе squidusers в домене DOMAIN.LOCAL.
  • squid_superusers_from_ad_krb — произвольное название acl, авторизованных пользователей в AD через kerberos, принадлежащих группе squidsuperusers в домене DOMAIN.LOCAL.
  • squid_users_from_ad_ntlm — произвольное название acl, авторизованных пользователей в AD через NTLM.

В секции acl:

#acl auth proxy_auth REQUIRED
acl squid_users_acl_krb external squid_users_from_ad_krb
acl squid_superusers_acl_krb external squid_superusers_from_ad_krb
acl squid_users_acl_ntlm external squid_users_from_ad_ntlm squidusers
acl squid_superusers_acl_ntlm external squid_superusers_from_ad_ntlm squidsuperusers

*  где 

  • squid_users_acl_krb — произвольное название acl для всех, кто входит в squid_users_from_ad_krb; 
  • squid_superusers_acl_krb — произвольное название acl для всех, кто входит в squid_superusers_from_ad_krb; 
  • squid_users_acl_ntlm — произвольное название acl для всех, кто входит в squid_users_from_ad_ntlm;
  • squid_superusers_acl_ntlm — произвольное название acl для всех, кто входит в squid_superusers_from_ad_ntlm;

* предыдущую acl для общей аутентификации комментируем.

В секции allow:

#http_access allow auth
http_access allow squid_superusers_acl_krb
http_access allow squid_superusers_acl_ntlm
http_access allow squid_users_acl_krb
http_access allow squid_users_acl_ntlm

* разрешаем доступ для созданных ранее acl; предыдущее разрешение для всех пользователей AD запрещаем. На данном этапе разницы между пользователями групп squidusers и squidsuperusers нет — позже мы настроим ограничение доступа к сайтам, где будем применять разные группы для предоставления различных прав.

Перечитываем конфигурацию прокси-сервера:

squid -k reconfigure

Example 4: LDAP name attributes

The LDAP name attributes setting can be used to specify the “name” attributes of each record which are to be returned in the LDAP search results.

When you type in this field for example:cn sn displayNamethis requires to specify “cn”—>commonName means Full name of the user, “sn”—>Surname, last name or family name and “displayName” fields for each LDAP record.

See the following screenshot example of an Active Directory:

Further Examples:

  • cn sn displayNameRequires “cn”, “sn” and “displayName” fields for each LDAP record.
  • givenName Requires “givenName” field for each LDAP record.

vorName nachNameRequires “vorName” and “nachName” fields for each LDAP record.

Настройка Kerberos

Установка пакетов для поддержки аутентификации Kerberos:

1 apt-get install krb5-user libsasl2-modules-gssapi-mit

В ходе установки может появится запрос указать область по-умолчанию для Kerberos, область необходимо его указать в заглавном виде (прим. JAKONDA.LOCAL)

Файл конфигурации Kerberos (/etc/krb5.conf), приводим к виду:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
 

default_realm = JAKONDA.LOCAL
default_keytab_name = /etc/squid/squid.keytab
dns_lookup_kdc = false
dns_lookup_realm = false
forwardable = true
ticket_lifetime = 24h
 

JAKONDA.LOCAL = {
kdc = dc1.jakonda.local
default_domain = JAKONDA.LOCAL
admin_server = dc1.jakonda.local
}
 

.jakonda.local = JAKONDA.LOCAL
jakonda.local = JAKONDA.LOCAL

Соответственно подставляем название своего домена вместо jakonda.local/JAKONDA.LOCAL

Проверка работы Kerberos, выполним авторизацию в Active Directory:

1
2
3
4
5

kinit -kV -p HTTP/squid.jakonda.local
 
Using default cache: /tmp/krb5cc_0
Using principal: HTTP/
Authenticated to Kerberos v5

Удаляем полученный билет:

1 kdestroy

AuthLDAPCompareAsUser Directive

Use the authenticated user’s credentials to perform authorization comparisons
directory, .htaccess
AuthConfig
Extension
mod_authnz_ldap
Available in version 2.3.6 and later

When set, and has authenticated the
user, LDAP comparisons for authorization use the queried distinguished name (DN)
and HTTP basic authentication password of the authenticated user instead of
the servers configured credentials.

The ldap-attribute, ldap-user, and ldap-group (single-level only)
authorization checks use comparisons.

This directive only has effect on the comparisons performed during
nested group processing when is also enabled.

This directive should only be used when your LDAP server doesn’t
accept anonymous comparisons and you cannot use a dedicated
.

Запуск в Docker

На гитхабе представлен Dockerfile для сборки Docker-образа nginx-ldap-auth. Я немного его изменил, добавив:

  • non-root пользователя для запуска приложения в контейнере
  • временную зону Europe/Moscow
  • 3 версию питона по умолчанию в entrypoint
  • аргументы CMD

Таким образом, можно выполнять запуск командой ниже:

А при необходимости запуска на порту, отличном от дефолтного 8888, можно изменить аргументы CMD при старте:

Используемые заголовки

Демон nginx-ldap-auth успешно запущен, но перед дальнейшей настройкой непосредственно самого Nginx, необходимо убедиться, что запросы корректно приходят в Active Directory от nginx-ldap-auth. Для этого понадобится curl и специальные HTTP-заголовки, в которых будет передаваться вся необходимая информация для подключения к LDAP.

Параметры LDAP HTTP Header Описание
База поиска. В большинстве случаев соответствует суффиксу каталога. Если необходимо просто авторизовать пользователя, то не нужно указывать дополнительные группы, в которые этот пользователь входит (для этого используется template). Например, 
Для выполнения операции поиска в каталоге используется BIND DN, в данном параметре указывается непосредственно уникальное имя пользователя каталога. Например, 
Пароль пользователя 
Авторизация на основе файлов кук, необязательный параметр. При использовании basic auth игнорируется.
Имя realm, необязательный параметр, используется по умолчанию значение Restricted.
Шаблон, по которому будет происходить выборка. Можно настраивать различные конфигурации. Например, для OpenLDAP подойдет такой шаблон: (cn=%(username)s), а для AD – (SAMAccountName=%(username)s) – это базовый шаблон, который просто выполняет поиск пользователя по каталогу.
Адрес подключения к LDAP-серверу. Например, ldap://10.10.4.30:389 или ldaps://10.10.4.30:636

Проверка работы

Определившись с заголовками, можно выполнить проверку через curl, передав минимальные параметры: адрес AD, наименование домена, логин\пароль и простой шаблон:

В ответ должен поступить 200 код, т.е. подключение успешно устанавливается от имени созданного пользователя:

Настраиваем RBAC-авторизацию

  1. Для примера привяжем статического пользователя к системной роли cluster-admin, а пользователей группы developers – к роли view, позволяющей только просматривать ресурсы. Тогда содержимое файла crb.yml должно быть таким:

    apiVersion: rbac.authorization.k8s.io/v1beta1

    kind: ClusterRoleBinding

    metadata:

      name: dex-admin

      namespace: kube-system

    roleRef:

      apiGroup: rbac.authorization.k8s.io

      kind: ClusterRole

      name: cluster-admin

    subjects:

    — kind: User

      name: «[email protected]»

    apiVersion: rbac.authorization.k8s.io/v1beta1

    kind: ClusterRoleBinding

    metadata:

      name: dex-developers

      namespace: kube-system

    roleRef:

      apiGroup: rbac.authorization.k8s.io

      kind: ClusterRole

      name: view

    subjects:

    — kind: Group

      name: «developers»

  2. Переключаемся на основной контекст и применяем созданный yaml-файл на кластер:

    kubectl config set-context default

    kubectl apply -f crb.yml

  3. Смотрим доступные контексты и переключаемся обратно на нашего пользователя:

    kubectl config get-contexts

    kubectl config set-context johndoe-ash.dtln.cloud

На этом настройка Dex в связке с OpenLDAP закончена.

Пара советов напоследок:

Статистика пользователей

Остался последний этап — отображать красивую статистику посещений сайтов пользователями. Самый простой и красивый инструмент для этого — LightSquid.

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

Приводим файл /etc/apache2/conf-available/lightsquid.conf в такой вид (доступ на просмотр даем всем):

Alias   /lightsquid/    /usr/lib/cgi-bin/lightsquid/

<Location "/lightsquid/">
        Options +ExecCGI
        Require local
        Require ip 192.168.1.0/24
</Location>

Раскомментируем строку 219 в файле /etc/apache2/mods-enabled/mime.conf

AddHandler cgi-script .cgi .pl

Запускаем все это дело:

# a2enmod cgi
# a2enconf lightsquid
# service apache2 restart

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

Необходимо поставить пакет libnet-ldap-perl:

# apt-get install libnet-ldap-perl

Очень хочется чтобы в отчете фигурировало полное ФИО пользователя, а не доменное имя или IP-адрес. Для этого нужно заменить оригинальный файл /usr/share/lightsquid/ip2name/ip2name.squidauth следующим:

#contributor: esl
#specialy for squid with turned on user authentication
#simple version
 
use strict;
use warnings;
use Net::LDAP;
use Encode;
 
my $ldap;
my $message;
my %hDisplayName;
 
sub StartIp2Name() {
        my $server = "ldap://dc.mydomain.ru";
        $ldap = Net::LDAP->new( $server );
        return if(!defined $ldap);
        $message = $ldap->bind(q(mydomain.ru\lightsquid), password => "my_password");
}
 
sub Ip2Name($$$) {
  # $Lhost,$user,$Ltimestamp
  my $Lhost=shift;
  my $user =shift;
  $user    =URLDecode($user); #decode user name
  $user = substr($user, , index($user, "\@mydomain.ru"));
  return $Lhost if ($user eq "-");
  return $user if (!defined $ldap);
  return $user if ($message->code());
 
  if (!defined $hDisplayName{$user})
  {
 
    my $result = $ldap->search(
    base        => "dc=mydomain,dc=ru",
    filter      => "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" . $user . "))",
    );
 
my $first_entry = $result->entry();
if (!defined $first_entry)
  {
    return $Lhost;
  }
 
my $pure_displayName = $first_entry->get_value("displayName");
$pure_displayName =~ s/ /_/g;
Encode::from_to($pure_displayName, 'utf-8', 'windows-1251');
 
  $hDisplayName{$user}=$pure_displayName;
  }
 
  return $hDisplayName{$user};
}
 
 
sub StopIp2Name() {
        return if (!defined $ldap);
        $message = $ldap->unbind;
}
 
#warning !!!
1;

В этом файле исправляем нижеуказанные строки на свои:

...
        my $server = "ldap://dc.mydomain.ru";
...
        $message = $ldap->bind(q(MYDOMAIN.RU\LightSquid), password => "PASSWORD");
...
    base        => "dc=MYDOMAIN,dc=RU",
...

Теперь в /etc/lightsquid/lightsquid.cfg включаем преобразование логина в ФИО:

$ip2name="squidauth"

Запускаем /usr/share/lightsquid/check-setup.pl и если все хорошо, можно запускать /usr/share/lightsquid/lightparser.pl

В папке /var/lib/lightsquid/report должны появиться отчеты, которые можно поглядеть по адресу: http://192.168.1.1/lightsquid/

Заключение

По сути вся настройка сводится к тому, что команда Nginx предоставила готовое решение и описала общие принципы настройки, что очень удобно. К тому же, для большего удобства предоставлены Dockerfile для сборки образов и запуска nginx-ldap-auth в контейнере.

Из минусов мне видится два и причём весьма существенных:

  • если пропадёт сетевая связанность до сервера с AD или сам сервер падёт смертью храбрых, то клиент на Nginx не сможет авторизоваться и в ответ получит 500 код. Для серьезных решений это может быть критичным моментом и стоит это учитывать. Но в теории Nginx сейчас крайне функционален и наверняка можно обыграть этот нюанс с использованием модуля njs или хитрых конструкций из директив.
  • аутентификация в AD происходит по протоколу LDAP, а это по сути большая дыра. В идеале использовать хотя бы NTLM или Kerberos.

Также есть форк, в котором есть возможность использования нескольких LDAP-серверов, что в теории должно нивелировать описанный выше минус. Но на практике не проверял.

Заключение

В целом, решение уже длительное время работает и обеспечивает не только аутентификацию, но и авторизацию.
Что позволяет использовать в NAS любые сервисы в контейнерах, независимо от того поддерживают ли они аутентификацию через LDAP.

Хотя имеются некоторые проблемы:

  • Безопаснее и удобнее для пользователя производить аутентификации через HTML страницу, включив переменную . Но этот вариант у меня не заработал. Будет время — разберусь.
  • Неудобно задавать список групп. Я вынужден был делать LDAP фильтр, а не список, поскольку ограничения docker-gen не позволяют мне сформировать нужную строку.
  • Сервисы независимы, каждый сервис является отдельным поддоменом. И приходится вводить логин и пароль каждый раз, когда производится доступ на сервис, в котором ещё не была произведена аутентификация, что раздражает. В будущем возможно сделаю единый центр аутентификации.

Конфигурацию NAS вы можете найти в репозитории.

Понравилась статья? Поделиться с друзьями:
Быть в курсе нового
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: