Установка авторизации по Active Directory

В Системе предусмотрена возможность авторизации в web-приложении NetDB через авторизацию Active Directory в Windows. Эту задачу решает mod_auth_kerb.

Установка тестового Active Directory сервера

Необходимо следовать инструкции http://stef.thewalter.net/2012/08/how-to-create-active-directory-domain.html до шага 7 включительно. Используемое название домена - ad.chtd.lan, все остальное без изменений.

Перед созданием виртуальной машины (шаг 3) необходимо остановить «default» сеть и запустить «ad» сеть (виртуальную сеть, созданную ранее). В противном случае, при попытке запустить сеть при создании виртуальной машины появится ошибка про мост. Рекомендуется в принципе отключить автозапуск сети «default» и оставить только автозапуск сети «ad».

После установки необходимо перезагрузить Windows и просмотреть логи DNS и Active Directory - проверить корректность запуска (Server Manager => раздел Roles).

Должна работать команда:

host ad.chtd.lan 192.168.12.10

После этого нужно запустить редактор сетевых подключений (nm-connection-editor) и у текущего подключения (например, к wi-fi chtd-net) на вкладке настроек IPv4 задать:

  • Automatic (DHCP) addresses only,
  • 192.168.12.10 как DNS-сервер.

После этого нужно переподключиться к сети (интернет может работать медленнее из-за DNS) и проверить работу:

host ad.chtd.lan

Далее необходимо проверить что работает kerberos на сервере. Сначала проверить авторизацию под администратором:

kinit Administrator@AD.CHTD.LAN
klist

А затем добавить в Active Directory тестового пользователя (testuser) и авторизоваться от него:

kinit testuser@AD.CHTD.LAN
klist

Далее в /etc/krb5.conf (в секцию [libdefaults]) добавить:

default_realm = AD.CHTD.LAN
dns_lookup_realm = true
dns_lookup_kdc = true

Проверить, что работает получение тикета авторизации без указания домена:

kinit testuser
klist

Если при выполнения kinit происходит ошибка:

kinit: Clock skew too great while getting initial credentials

то необходимо синхронизировать время с погрешностью менее 5 минут (необходимо также внести поправку на часовой пояс).

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

Инструкция написана для Fedora 18, но в других Linux-дистрибутивах настройка происходит аналогично (за вычетом путей к конфигам Apache и т.п. деталей).

В текущем примере настройки сервер называется netdb.local (если это тестовый локальный сервер, его необходимо добавить в /etc/hosts).

Для проверки авторизации через Active Directory для сервера нужно завести пользователя (без администраторских привилегий), например, «apache», и проверить что он может авторизоваться (kinit apache).

Затем для него нужно сгенерировать keytab - на сервере с Active Directory исполняется (AD\apache - это ДОМЕН\пользователь):

C:\>ktpass -princ HTTP/netdb.local@AD.CHTD.LAN
 -mapuser apache@AD.CHTD.LAN -crypto rc4-hmac-nt
 -ptype KRB5_NT_SRV_HST -pass SECRET_PASSWORD_GOES_HERE
 -out c:\apache.keytab

Получившийся keytab необходимо передать на сервер с Apache, поместить в /etc/httpd/conf/apache.keytab и проверить:

kinit -k -t /etc/httpd/conf/apache.keytab HTTP/netdb.local
klist
Ticket cache: DIR::/run/user/1000/krb5cc_a68850848026c34d37838eac51ef99e6/tktdmsNwC
Default principal: HTTP/netdb.local@AD.CHTD.LAN

Valid starting     Expires            Service principal
07/24/13 20:33:17  07/25/13 06:33:16  krbtgt/AD.CHTD.LAN@AD.CHTD.LAN
                renew until 07/31/13 20:33:17

Далее установить модуль Apache mod_auth_kerb (из пакетов) и убедиться, что он активирован. Конфиг для Apache _conf/httpd.ad.conf. Для отладки полезно включить полное логирование, добавив в основной конфиг:

LogLevel debug

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

Trying to verify authenticity of KDC using principal HTTP/netdb.local@

Если вместо этого он пишет имя сервера localhost.localdomain - это ошибка, имя сервера должно в точности совпадать. При локальной установке эту проблему можно решить тем, что в /etc/hosts сначала написать правило для netdb.local, а уже потом для localhost.localdomain.

Важный параметр в конфиге сервера это:

KrbMethodK5Passwd on

Если этот параметр стоит в on, то при первой авторизации будет показан тот же диалог, как и при basic auth, и будет проверен логин/пароль Active Directory. Но для корректной работы (когда браузер проверяет, авторизован ли пользователь и использует negotiation (см. далее пример с curl)) этот параметр стоять в off.

Настройка различных браузеров описана по ссылке: http://www.roguelynn.com/words/apache-kerberos-for-django/.

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

Еще один вариант проверки авторизации - при помощи curl (http://www.roguelynn.com/words/apache-kerberos-for-django/):

[chtd@localhost netdb_demo]$ kdestroy

[chtd@localhost netdb_demo]$ curl -I --negotiate -u : http://netdb.local
HTTP/1.1 401 Unauthorized
Date: Thu, 25 Jul 2013 14:23:29 GMT
Server: Apache/2.4.4 (Fedora) mod_auth_kerb/5.4
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="
Content-Type: text/html; charset=iso-8859-1

[chtd@localhost netdb_demo]$ kinit testuser
Password for testuser@AD.CHTD.LAN:

[chtd@localhost netdb_demo]$ curl -I --negotiate -u : http://netdb.local
HTTP/1.1 401 Unauthorized
Date: Thu, 25 Jul 2013 14:23:51 GMT
Server: Apache/2.4.4 (Fedora) mod_auth_kerb/5.4
WWW-Authenticate: Negotiate
WWW-Authenticate: Basic realm="
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 302 FOUND
Date: Thu, 25 Jul 2013 14:23:51 GMT
Server: WSGIServer/0.1 Python/2.7.3
WWW-Authenticate: Negotiate YIGVBgkqhkiG9xIBAgICAG+BhTCBgqADAgEFoQMCAQ+idjB0oAMCAReibQRr+Rm5bVkcymeaJHR2qTVZG8mcuotB9mEDNU8ipzUs84FUVDARA3TMGju6weJi94qER//tRet6CAOkbpwM4x3gRzYG/u/Nd3Xby6aB62HZgawFhyOINFlrMbA3lBTjy9zmvenb8DnFVqimVoQ=
Vary: Accept-Language,Cookie
Content-Type: text/html; charset=utf-8
Location: http://netdb.local/login/?next=/
Content-Language: ru

Авторизованный пользователь будет доступен в переменной request.META:

request.META['REMOTE_USER'] -> 'testuser@AD.CHTD.LAN'

Далее авторизация происходит аналогично https://docs.djangoproject.com/en/1.4/howto/auth-remote-user/.

Настройка проекта

Если в netdb_demo.settings.common задана переменная REMOTE_USER_AUTH = True, то подключается возможность авторизации по REMOTE_USER.

Если там же задана переменная REMOTE_USER_AUTOCREATE = True, то если пользователь не найден, создается новый пользователь, если получается найти для него домен. Название домена берется из полного имени пользователя (все, что после «@»). Сам домен ищется среди всех доменов, и берется домен, у которого задан показатель ldap_domain_name (-902, «Название домена LDAP»), равный названию домена пользователя.