SSO (Single Sing-on) – это механизм используемый в Microsoft Windows и позволяющий пользователям вошедшим в систему не вводить многократно пароль при авторизации на доменных сетевых ресурсах. Этот же механизм можно запросто прикрепить к Apache, что бы позволить доменным пользователям проходить аутентификацию, например на внутреннем сайте компании, не вводя имя пользователя и пароль.

В статье используется домен Active Directory – MYDOMAIN.LOCAL.
Контроллер домена на Windows Server 2008 R2, DNS: adsrv.mydomain.local, IP: 192.168.10.10.
Веб-сервер, CentOS 6.3 i386, DNS: web7.mydomain.local, IP: 192.168.40.10.

1. Немого теории

Для того что бы клиенты и сервисы могли между собой проходить аутентификацию, есть общий программный интерфейс сервисов безопасности GSSAPI (Generic Security Services API), он позволяет через единый интерфейс использовать разные реализации проверки подлинности. Одна из таких реализаций SPNEGO (Simple and Protected GSS-API Negotiation Mechanism), этот механизм позволяет через протокол HTTP согласовать и провести аутентификацию по Kerberos или NTLM в зависимости от того что умеют клиент и сервер. В нашем случает будет работать связка Kerberos/SPNEGO.

Чтобы лучше понять как это работает, рассмотрим что делает клиент открывая сайт web7.mydomain.local.
1. Отправляет HTTP запрос веб-серверу
2. Получает от веб-сервера ответ 401 – нужна авторизация
3. Запрашивает и получает от KDC, так называемый тикет на выдачу тикетов – TGT (Ticket Granting Ticket). Обычно TGT получается ранее при входе в систему и этот пункт пропускается.
4. Запрашивает и получает от KDC тикет на доступ к службе – TGS (Tecket Granting Service). Здесь важно заметить, что в запросе используется тип и DNS-имя сервиса, поэтому если например мы подключаемся к серверу по IP или CNAME, то соответствующий тикет получен не будет.
5. Отправляет повторный HTTP запрос веб-серверу, содержащий упакованный и зашифрованный тикет на доступ к службе (TGS) и свой идентификатор. Этот запрос является частью согласования SPNEGO.
6. Веб-сервер при помощи файла keytab проверяет полученный тикет и достает от туда идентификатор пользователя, а затем в случае удачной аутентификации отправляет в ответ запрошенные данные.

2. Настройка времени

Каждый тикет (билет) Kerberos сопровождается меткой времени, и если время между клиентом и сервером расходится более чем на 10 минут процесс обмена тикетами прерывается. Что бы этого не происходило нужно настроить синхронизацию времени между нашим веб-сервером и контроллером домена.
Устанавливаем клиент NTP и планировщик задач, если он еще не установлен.

[root@web7 ~]# yum install ntpdate cronie

Делаем первоначальную синхронизацию времени, добавляем запуск синхронизации времени в планировщик и запускаем его.

[root@web7 ~]# ntpdate mydomain.local
[root@web7 ~]# echo "0 0 * * * root /usr/sbin/ntpdate mydomain.local" >> /etc/crontab
[root@web7 ~]# service crond start

3. Настройка Kerberos

Ставим пакет krb5-workstation

[root@web7 ~]# yum install krb5-workstation

И переходим к редактировнию /etc/krb5.conf, по-умолчанию в CentOS он уже неплохо отконфигурирован, и для ситуации с единственным доменом в нем достаточно поменять имена доменов и серверов.

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log
 
[libdefaults]
 default_realm = MYDOMAIN.LOCAL
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 
[realms]
 MYDOMAIN.LOCAL = {
  kdc = adsrv.mydomain.local
  admin_server = adsrv.mydomain.local
 }
 
[domain_realm]
 .mydomain.local = MYDOMAIN.LOCAL
 mydomain.local = MYDOMAIN.LOCAL

Завершив редактирование, желательно сделать небольшую проверку – получить TGT тикет для одного из пользователей, kinit – получаем тикет, klist – просматриваем.

[root@web7 ~]# kinit administrator
Password for administrator@MYDOMAIN.LOCAL:
[root@web7 ~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@MYDOMAIN.LOCAL
 
Valid starting Expires Service principal
11/25/12 19:15:42 11/26/12 05:15:50 krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL
renew until 12/02/12 19:15:42

4. Создаем Keytab

Файл Keytab нужен нам для того что бы Apache мог шифровать и расшифровывать сообщения Kerberos, и если в обычной ситуации пользователь заходит в систему вводя свой логин и пароль, а затем на основании их получает свой тикет c ключами шифрования, то в случае с keytab необходимости ввода пароля нет и ключи шифрования храняться непосредственно в нем.
Создаем в ActiveDirectory пользователя с именем web7-http и паролем P@assw0rd, у этого пользователя делаем бесконечным срок действия пароля «Password never expires». Переходим к коммандной строке и создаем при помощи утилиты ktpass файл krb5.keytab.

PS C:\Users\Administrator> ktpass -princ HTTP/web7.mydomain.local@MYDOMAIN.LOCAL -mapuser web7-http@mydomain.local -crypto RC4-HMAC-NT -ptype KRB5_NT_PRINCIPAL -pass P@ssw0rd -out c:\krb5.keytab

Теперь keytab нужно скопировать на web-сервер, для этого забираем с сайта PuTTY утилиту PSCP для копирования файлов по SSH и запускаем ее со следующими параметрами.

PS C:\Users\Administrator> pscp c:\krb5.keytab root@web7.mydomain.local:/etc/
Store key in cache? (y/n) y
root@web7.mydomain.local's password:
krb5.keytab | 0 kB | 0.1 kB/s | ETA: 00:00:00 | 100%

Возвращаемся обратно к серверу web7.mydomain.local, и для верности проверяем получившийся keytab. Просматриваем содержимое.

[root@web7 ~]# klist -kte /etc/krb5.keytab
Keytab name: WRFILE:/etc/krb5.keytab
KVNO Timestamp Principal
---- ----------------- --------------------------------------------------------
3 01/01/70 03:00:00 HTTP/web7.mydomain.local@MYDOMAIN.LOCAL (arcfour-hmac)

Проверяем может ли система получить тикет по файлу keytab.

[root@web7 ~]# kinit -k -t /etc/krb5.keytab -p HTTP/web7.mydomain.local@MYDOMAIN.LOCAL
[root@web7 ~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/web7.mydomain.local@MYDOMAIN.LOCAL
 
Valid starting Expires Service principal
11/25/12 19:40:32 11/26/12 05:40:32 krbtgt/MYDOMAIN.LOCAL@MYDOMAIN.LOCAL
renew until 12/02/12 19:40:32

5. Настройка Apache

Устанавливаем Apache и mod_auth_kerb.

[root@web7 ~]# yum install httpd mod_auth_kerb

Переходим к редактированию конфигурационного файла Apache /etc/httpd/conf/httpd.conf, раскоментируем строчку “NameVirtualHost *:80″ и добавим в конец файла описание виртуального хоста. Подробнее настройка именованных виртуальных хостов описана в статье “Настройка NameVirtualHost на Apache”.

<VirtualHost *:80>
    ServerAdmin admin@mydomain.local
    DocumentRoot /var/www/web7.mydomain.local
    ServerName web7.mydomain.local
    <Location "/">
        AuthType Kerberos
        KrbAuthRealms MYDOMAIN.LOCAL # Имя домена
                                     # Имя сервиса, точно такое же как в файле keytab
        KrbServiceName HTTP/web7.mydomain.local@MYDOMAIN.LOCAL
        Krb5Keytab /etc/krb5.keytab  # Наш keytab-файл
        KrbMethodNegotiate on        # использовать согласование по SPNEGO
        KrbMethodK5Passwd on         # разрешить не доменным пользователям аутенти-
                                     # фикацию при помощи логина и пароля
        require valid-user           # Для доступа подходит любой пользователь проше-
                                     # дший аутентификацию
        # Можно также ограничить доступ по имени пользователя
        # require user petrov@MYDOMAIN.LOCAL smirnov@MYDOMAIN.LOCAL
    </Location>
    ErrorLog logs/web7.mydomain.local-error_log
    CustomLog logs/web7.mydomain.local-access_log common
</VirtualHost>

Перезапускаем Apache

[root@web7 ~]# service httpd restart

Теперь можно открывать с доменного компьютера браузером сайт web7.mydomain.local и проверять как аутентифицируются пользователи. Единственное хочется заметить, для того что бы Windows передавала идентификационный параметры пользователя на веб-сервер, адрес этого веб-сервера должен быть добавлен в зону местной интрасети. Либо в праметрах безопасности должно быть разрешен “Автоматический вход с текущим именем пользователя”.

6. Заключение

В этой статье описывается алгоритм настройки прозрачной аутентификации пользователей на веб-сервере Apache, максимум что может эта реализация – проверить валидность пользователя или ограничить доступ по именам. Для того что бы сделать полноценную авторизацию пользователей по группе или по еще каким-то дополнительным параметрам нужно добавить авторизацию в LDAP. Об этом я постараюсь рассказать в следующей статье.

Один комментарий : “Настройка Single Sign-on на Apache”

  1. Alexey пишет:

    Спасибо (за отличную статью, помогла быстро разобраться в отношениях между АД, клиентом и апачем. Большая просьба, очень жду продолжения про LDAP. Желательно так же с теорией. А то есть проблема с ССО каждые 7 дней отваливается. И приходится перезагонять сервер в домен и перегенерировать кейтаб. Хочу побольше узнать, что б “до болтов” разобрать уже. Спасибо еще раз за статью, очень полезная.

Оставить комментарий