Михаил Кондрин
Как только ваша подконтрольная локальная сеть начнет развиваться и
расширяться, возникнут новые задачи: Как синхронизировать системные учетные
записи растущего числа пользователей? Как управлять доступом пользователей к
сетевым сервисам внутри локальной сети? При этом сервисы могут работать на
разных компьютерах, а определенные службы держат собственные учетные записи для
авторизованных пользователей. Решением послужит введение единой системы
регистрации в локальной сети с помощью протокола Kerberos.
Чтобы подробнее разобраться с возникающими задачами, рассмотрим ситуацию с
организацией распределенной вычислительной системы. Разумеется, чем больше
компьютеров входят в кластер, тем выше его вычислительная мощность. Наиболее распространненные
системы кластерных вычислений на сегодня – Parallel Virtual Machine и Message Passing
Interface. Обе позволяют пользователю, в данном случае разработчику программ,
пересылать куски данных, нуждающихся в обработке, между узлами кластера и
синхронизировать получение результатов с разных узлов. Это фасад системы. За
кулисами происходит обращение к удаленному командному интерпретатору и вызов
определенных программ в нем. То есть администратору такой системы необходимо
добиться, чтобы пользователи кластера имели доступ к командному интерпретатору
на узлах кластера и, более того, этот доступ должен быть беспарольным для
каждой пары компьютеров в кластере. Не очень-то удобна система, где запуск
нескольких параллельных копий программы требует от пользователя регистрации на
каждом из узлов кластера.
Таким образом, во-первых, информация о
пользователях должна совпадать на всех этих компьютерах. Один из вариантов
решения – иметь одинаковые копии /etc/passwd и /etc/shadow на каждом из узлов с
их последующим обновлением с помощью скриптов при добавлении нового
пользователя. Во-вторых, если в качестве удаленного командного интерпретатора
используется rsh, то добиться беспарольного входа с помощью внесения всех
компьютеров, входящих в этот кластер, в файл /etc/hosts.equiv (этот файл также
должен совпадать на всех узлах кластера). Однако использование rsh гарантирует
вам проблемы с безопасностью, если предположить возможность доступа к кластеру
извне локальной сети, который, как вы помните, должен быть беспарольным. Можно
сконфигурировать доступ по адресу компьютера (с помощью tcp-wrappers) и
бороться с ip-spoofing внешними средствами или настраивать openssh в качестве
удаленного командного интерпретатора. В последнем случае вам придется мириться
с тем, что процессорные циклы будут расходоваться не на расчет, а на
кодирование/раскодирование блоков данных. Тем не менее ни одно из этих решений
нельзя считать удачным.
Далеко не каждому из вас приходится сталкиваться
с настройками вычислительных кластеров. Но именно эта проблема построения
распределенной вычислительной системы Athena заставила в начале 80-х годов
программистов из Массачусетского технологического института разработать и
внедрить протокол удаленной аутентификации пользователей. Комбинирование
специальных криптографических средств позволяло, с одной стороны, свести на нет
вероятность перехвата паролей и иметь шифрованный канал для передачи данных
между компьютерами (эта возможность могла отключаться по желанию пользователя).
А с другой – иметь систему с единой регистрацией (single sign-on), что дает
возможность пользователю регистрироваться один раз при входе в систему и в
дальнейшем иметь свободный доступ к сетевым ресурсам на основе этой
регистрации.
Понятно, что число пользователей, которым такая
функциональность была бы удобна, значительно превышает число нуждающихся в
распределенных системах, и в дальнейшем этот протокол, получивший название Kerberos
(по имени трехголового пса из древнегреческих мифов, стерегущего вход в царство
мертвых), стал широко применяться независимо от Athena как система регистрации
в крупных финансовых и академических учреждениях.
Kerberos с точки зрения
пользователя
На пользовательском уровне все реализации Kerberos выглядят однотипно,
поэтому рассмотрим, как это происходит в моем случае. Регистрация в Kerberos
осуществляется командой kinit, которая автоматически вызывается при моем входе
на рабочую станцию под управлением Windows XP. В результате мне выдается
основной документ, удостоверяющий мою личность в Kerberos, – «супербилет»,
билет, гарантирующий получение доступа к сетевым службам (или TGT – ticket
granting ticket). При этом у меня всегда есть возможность зарегистрироваться в Kerberos
под другим именем с помощью все той же команды kinit, что приводит к обновлению
начального билета. Теперь предположим, что я хочу посмотреть логи на своем router/firewall
под управлением Linux. Я открываю терминал cygwin. Первое, что можно сделать, –
просмотреть имеющиеся билетики:
mike@alex ~\$ klist
Credentials cache:
FILE:/tmp/krb5cc_1017
Principal:
mike@HPPI.TROITSK.RU
Issued
Expires Principal
May 29
22:18:22 May 30 22:18:22 krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
В списке, как вы видите, имеется только один билет
– тот самый TGT. Credential Cache – это файл, в котором хранятся полученные
мной сертификаты. По умолчанию его название – это комбинация /tmp/krb5cc_ и id
пользователя. Срок действия любого билетика ограничен по времени – это снижает
интерес к его перехвату со стороны злоумышленника. Теперь я запускаю командный
интерпретатор на удаленном компьютере:
\$ telnet -F relay
Trying
192.168.1.254...
Connected to relay.hppi.troitsk.ru.
Escape character
is '^]'.
Waiting for encryption
to be negotiated...
[ Trying mutual
KERBEROS5 (host/relay.hppi.troitsk.ru@HPPI.TROITSK.RU)... ]
[ Kerberos V5 accepts
you as ``mike@HPPI.TROITSK.RU'' ]
[ Kerberos V5 accepted
forwarded credentials ]
Encryption negotiated.
\$klist
Credentials cache:
FILE:/tmp/krb5cc_1000
Principal:
mike@HPPI.TROITSK.RU
Issued
Expires Principal
May 29
22:21:16 May 30 22:18:22 krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
Вот пример магии Kerberos в действии –
воспользовавшись моим супербилетом, Kerberos прозрачно для пользователя
организует доступ к сетевому ресурсу (в данном случае он фигурирует под именем host/relay.hppi.troitsk.ru@HPPI.TROITSK.RU)
и более того – telnet при помощи Kerberos автоматически шифрует весь сетевой
трафик между клиентом и сервером. Список билетов при этом не меняется – ключ -F
позволяет перемещать имеющиеся у меня билетики с компьютера на компьютер.
Закрытие telnet-сессии автоматически очищает кэш на удаленном компьютере с
помощью вызова команды kdestroy, так что вы можете не опасаться, что ваш кэш
может быть использован кем-то еще. Так как супербилет по-прежнему со мной, то
это позволяет мне получить доступ к другому компьютеру, серверу Kerberos.
\$telnet -F kenga
Trying
192.168.1.253...
Connected to kenga.hppi.troitsk.ru.
Escape character
is '^]'.
Waiting for encryption
to be negotiated...
[ Trying mutual
KERBEROS5 (host/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU)... ]
[ Kerberos V5 accepts
you as ``mike@HPPI.TROITSK.RU'' ]
[ Kerberos V5 accepted
forwarded credentials ]
Encryption negotiated.
mike@kenga:~\$
Точно так же я могу получить доступ к любому
сетевому сервису – например, к локальному ftp-серверу.
mike@kenga:~\$ ftp
kenga
Connected to kenga.hppi.troitsk.ru.
220 kenga FTP server
(Version 6.00+Heimdal 0.6.3) ready.
Trying
GSSAPI...
Authenticated to
<host/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU>
Authentication successful.
Name (kenga:mike):
S:232-Linux
2.4.25.
S:232 User mike
logged in.
S:230 Password not
necessary
Remote system type
is UNIX.
Using binary mode
to transfer files.
ftp> bye
S:221 Goodbye.
Заметьте, что во всех случаях мне не потребовался
ввод пароля. Доступ ко всем компьютерам мне предоставлялся на основании моего
TGT. Все операции c Kerberos (выдача билетов, добавление/удаление пользователей
и т. д.) фиксируются в его логах, и можете убедиться, что вся моя активность с
перемещениями от компьютера к компьютеру зафиксирована в файле /var/log/krb5kdc.log.
Для удобства я разделил кусок log-файла на 4 части, соответствующие процессам
получения доступа к моей рабочей станции, удаленного доступа к двум серверам и
серверу ftp.
2005-05-29T22:18:22
AS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.45 for krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
2005-05-29T22:18:22
Using des-cbc-crc/des-cbc-md5
2005-05-29T22:18:22
Requested flags: renewable_ok, renewable, forwardable
2005-05-29T22:18:23
sending 574 bytes to IPv4:192.168.1.45
2005-05-29T22:18:23
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.45 for krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
[renewable, forwardable]
2005-05-29T22:18:23
sending 593 bytes to IPv4:192.168.1.45
......
2005-05-29T22:21:15
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.45 for host/relay.hppi.troitsk.ru@HPPI.TROITSK.RU
2005-05-29T22:21:16
sending 546 bytes to IPv4:192.168.1.45
2005-05-29T22:21:16
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.45 for krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
[forwarded, forwardable]
2005-05-29T22:21:16
sending 589 bytes to IPv4:192.168.1.45
......
2005-05-29T22:21:43
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.254 for host/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU
2005-05-29T22:21:44
sending 550 bytes to IPv4:192.168.1.254
2005-05-29T22:21:44
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.254 for krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
[forwarded, forwardable]
2005-05-29T22:21:44
sending 593 bytes to IPv4:192.168.1.254
......
2005-05-29T22:22:27
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.253 for ftp/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU
2005-05-29T22:22:27
Server not found in database: ftp/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU: No such
entry in the database
2005-05-29T22:22:27
sending 145 bytes to IPv4:192.168.1.253
2005-05-29T22:22:27
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.253 for host/kenga.hppi.troitsk.ru@HPPI.TROITSK.RU
2005-05-29T22:22:27
sending 550 bytes to IPv4:192.168.1.253
2005-05-29T22:22:28
TGS-REQ mike@HPPI.TROITSK.RU from IPv4:192.168.1.253 for krbtgt/HPPI.TROITSK.RU@HPPI.TROITSK.RU
[forwarded, forwardable]
2005-05-29T22:22:28
sending 546 bytes to IPv4:192.168.1.253
Вы можете сказать: «Как же так – протоколы telnet
и ftp небезопасны и правильнее использовать openssh. И ничего удивительного в
беспарольной аутентификации нет – ту же самую функциональность обеспечивает ssh,
предоставляя возможность регистрироваться по парам публичных/секретных ключей».
Все правильно. Только для того, чтобы в сети из N компьютеров обеспечить доступ
по ssh с любого из этих компьютеров на любой другой, вам придется в общем
случае проделать 2N*{число пользователей} перемещений публичных ключей (каждая
пара компьютеров в сети обменивается публичными ключами пользователей), что в
случае больших сетей трудноосуществимо. В то же время с помощью Kerberos вам
нужно только зарегистрировать каждый из компьютеров на сервере Kerberos и иметь
один ключ на каждом из хостов (в отличие от ssh в Kerberos используется симметричное
шифрование) – итого 2N операций. Что же касается первой части вопроса, то я
использую специальный «керберизованный» вариант telnet, что защищает соединения
между хостами не хуже, чем ssh. Главный недостаток стандартного telnet (и не
только его) состоит в том, что при аутентификации на удаленном компьютере telnet
пересылает пароль пользователя по сети в виде открытого текста, что позволяет
злоумышленнику перехватить его. Ssh обходит эту опасность с помощью
несимметричного шифрования пароля. А каким же образом Kerberos удается избегать
брешей в защите связанных с удаленной аутентификацией?
Удаленная аутентификация в Kerberos
Делается это с помощью уже упоминавшихся ранее билетиков/сертификатов (tickets/credentials
– оба слова используются как синонимы) – специальным образом изготовленных и
упакованных шифровальных ключей. В Kerberos как пользователь, так и сетевая
служба не различаются между собой и именуются principal (принципал –
юридический термин, означающий лицо, поручающее агенту совершить сделку от его
имени), что весьма точно описывает функции принципалов в Kerberos. Принципалы
определяются своим именем и паролем, причем в случае сетевой службы в качестве
этого пароля выступает ключ, хранящийся на том же компьютере, где работает
защищаемый сервис. База данных принципалов хранится на сервере Kerberos, и при
необходимости проверить аутентичность пользователя или сервиса, компьютеры, объединенные
в сектора (realms), соединяются с этим сервером. По поводу терминологии: точный
перевод «realm» («царство») применительно к Kerberos не прижился, а иногда
используемый термин «домен» не кажется мне удачным, поскольку слово и так
перегружено. Так же, как и в случае с DNS, главный контроллер сектора Kerberos
(Key Distribution Center, KDC, центр выдачи ключей) может иметь как
дополнительные, slave, контроллеры (что позволяет обеспечить бесперебойную
работу при выходе из строя основного контроллера), так и в одиночку держать
несколько секторов. Типичное имя принципала, например, сервиса удаленного
доступа к командному интерпретатору компьютера, выглядит таким вот образом: host/kdc.myrealm.ru@MYREALM.RU,
что обозначает сервис с основным именем (primary name) host и характеристикой (instance)
kdc.myrealm.ru, принадлежащий сектору MYREALM.RU. Разделение имен принципалов на
несколько частей позволяет различать, с одной стороны, разные службы,
работающие на одном хосте (с помощью primary name, host в нашем случае). А с
другой – среди нескольких однотипных служб, работающих в сети, выбирать конкретную,
запущенную на определенном сервере (с помощью поля instance, которая в нашем
случае совпадает с именем компьютера). Название секторa не обязано повторять
доменное имя сети, но именно такое правило наименований считается устоявшейся
практикой.
Теперь посмотрим, что происходит, если
пользователь joeuser (а точнее, принципал joeuser@MYREALM.RU – поле instance
для «живых» пользователей обычно не используется) пытается получить доступ к
этому серверу. Предполагается, что как клиентская программа telnet, так и telnetd
демон собраны с поддержкой Kerberos (обе эти программы входят в дистрибутив Heimdal).
Разумеется, как сам сервер, так и пользователь должны быть зарегистрированы в
одном и том же секторе Kerberos. Как обычно, сеанс подключения к серверу
начинается с того, что пользователь запускает telnet со своим регистрационным
именем и именем удаленного компьютера telnet -l joeuser kdc.myrealm.ru.
Клиентская программа после этого обращается к KDC с просьбой предоставить для joeuser
доступ к хосту kdc.myrealm.ru. Kerberos генерирует по определенным правилам
шифровальный ключ (session key) и разыскивает по своей базе данных принципалов joeuser
и host/kdc.myrealm.ru, а также их пароли (ключи). Если пароли найдены (в
противном случае сеанс заканчивается аварийно – т.к. кто-то из этих двух
принципалов не зарегистрирован в секторе Kerberos), Kerberos приступает к
генерированию сессионного ключа (session key). С помощью ключа принципала host/kdc.myrealm.ru
он шифрует сгенерированный session key вместе с именем пользователя joeuser,
потом прилагает к зашифрованному блоку вторую копию того же session key и снова
шифрует получившийся билетик с помощью пароля пользователя. После этого пакет
отсылается клиентской программе. Если к этому времени пользователь набрал свой пароль
и он совпадает с паролем, использованным Kerberos при шифровке, то клиентская
программа сумеет расшифровать билетик. Далее, половина билетика (с session key)
остается пользователю, а вторая, которая не может быть расшифрована клиентом,
поскольку ключ сервера ей неизвестен, пересылается на сервер. Сервер
расшифровывает ее с помощью своего ключа и таким образом узнает как session key,
так и имя пользователя, что позволяет серверу авторизовать его своими
собственными средствами. Заметим, что помимо регистрации в этом случае имеется
возможность использовать полученный session key, поскольку в итоге он известен
как клиенту, так и серверу, для шифрования сетевого трафика в рамках данной
сессии, чем многие приложения и пользуются. Схематически процесс обмена
сертификатами показан на рис. 1.

Рисунок 1. Процесс обмена
сертификатами
Что еще интересного в используемом Kerberos
механизме аутентификации? Дело в том, что Kerberos оказывается еще более параноидальным,
чем мы предполагали вначале, т.е. считает ненадежными не только сетевые
соединения (ни один из паролей, как вы могли заметить, не передается в открытую
по сети), но и клиентский, и даже серверный компьютер. Для каждого из них
ключ/пароль партнера так и остается неизвестным – только session key, который
для потенциального взломщика интереса не представляет, поскольку используется
только в данной сессии. Как известно, безопасность и удобство пользователей
вещи взаимоисключающие. Но ученым из МТИ удалось найти удачный компромисс,
придумав еще одну замечательную вещь – ticket granting ticket (TGT). Если
пытаться переводить этот термин на русский – «билет для выдачи других билетов»,
что-то вроде единого проездного. Смысл его в том, что пользователь сети
проходит полностью процедуру регистрации (с вводом имени и пароля) в своем
секторе только один раз, а сертификат, полученный в результате, затем
используется клиентскими приложениями как эквивалент пользовательского пароля для
получения доступа к сетевым сервисам. Процесс выдачи ТGT ничем не отличается от
описанного выше, только в качестве службы, к которой пользователь получает
доступ, выступает сам Kerberos – его Ticket Granting Service. После
получения TGT записывается в кэш-файл на диске клиентского компьютера и затем
по мере надобности извлекается оттуда. В схеме, описанной выше, session-key, закодированный
в TGT используется вместо пароля пользователя при шифровании сертификата,
предоставляемого для доступа к сетевому ресурсу. И хотя TGT хранится в кэше на
диске рабочей станции пользователя, угроза, связанная с его перехватом, не
столь уж серьезна, поскольку его действенность ограничена по времени. TGT
позволяет организовать в корпоративной сети single sign-on (система единой
регистрации) систему. Например, с помощью замены системного login на керберизованный
аналог (программа с тем же именем входит в состав Heimdal Kerberos) при входе
на рабочую станцию пользователь получает TGT, который затем используется для
генерирования билетиков, специфичных для какой-нибудь из сетевых служб.
Таким образом, следует помнить, что при любой
аутентификации в Kerberos всегда участвуют два принципала – один соответствует
пользователю, пытающемуся получить доступ к сервису, а второй – самому этому
сервису. Мы не будем рассматривать более сложный механизм аутентификации, так
называемый user-to-user, когда сетевой сервис не имеет собственной записи в
базе данных Kerberos, а использует сертификаты пользователя, запустившего
сервис. Аутентификация user-to-user могла бы быть полезна, например, для
X-серверов, но и для них эта методика не получила большого распространения.
Так в общих чертах выглядит принцип работы Kerberos.
Многие детали реализации протокола Kerberos при этом пришлось опустить. В частности,
формат сертификата в действительности более сложен, чем описано здесь. В него
входит время выдачи и срок годности сертификата, адрес компьютера, на который
отсылается сертификат, и флажки, позволяющие контролировать использование
сертификатов и тем самым настраивать политику безопасности внутри сектора Kerberos.
Скажем, с помощью снятия флажка forwardable можно «привязать» сертификат к
одному компьютеру и запретить его перемещение на другие хосты. Пример,
рассмотренный в начале статьи, был бы невозможен в этом случае – после
получения удаленного доступа мне каждый раз потребовалось бы вводить пароль для
запроса нового TGT.
В следующем номере журнала мы перейдем к
практической части и развернём инфраструктуру Kerberos в локальной сети.
Приложение
История создания Kerberos
В 1983 году была начата работа по созданию системы Athena. Работу
финансировали компании IBM и DEC, и в 1987 году была выпущена первая версия
протокола Kerberos (Kerberos 4). Дальнейшая эксплуатация выявила
недостатки протокола, и обновленный вариант Kerberos 5 вышел в свет в 1993
году. В настоящее время 4 версия практически не используется, но в реализациях
протокола от МТИ совместимость с предыдущей версией продолжает сохраняться. К
1993 году протокол Kerberos уже завоевал популярность, и многие компании,
разработчики программного обеспечения стремились использовать его в своих
программных продуктах. Но тут имел место юридический казус – дело в том,
что в то время в США еще действовали законы, введенные еще во время холодной войны,
запрещающие экспорт военных технологий. Поскольку криптографическая защита,
использованная в Kerberos, классифицировалась как военная технология, это
создавало препятствия для использования его в программных продуктах сторонних
фирм и распространения его за пределами США. Для решения этой проблемы была
выпущена версия протокола Kerberos 4, из которого была изъята вся сильная
криптография. Эта реализация Kerberos получила название Bones (кости), и
ограничения на ее экспорт уже не действовали. В 1997 году группа программистов
из Стокгольмского Королевского университета, взяв за основу Bones, проделала
обратную работу и вставила недостающую криптографическую функциональность. Вот
так экспортные ограничения Соединенных Штатов способствовали развитию
европейского hi-tech. Впоследствии ими же была выпущена реализация протокола Kerberos
5, получившая название Heimdal. Heimdal (Хеймдалль) – это божество из
скандинавского пантеона, чьи функции состояли в охране стратегических
коммуникаций, а именно – моста, разделяющего Асгард и Мидгард. Так же, как и в
случае с древнегреческим прототипом Kerberos, здесь эксплуатируется образ
неподкупного стража. Интересно отметить, что мотивом для программистов из
Стокгольмского университета, так же как и для их коллег из МТИ, являлась задача
обеспечения публичного доступа к вычислительному кластеру. Последним эпизодом
из истории Kerberos стало объявление компанией Microsoft в 1999 году о
поддержке Kerberos в своей будущей операционной системе NT 5.0 (впоследствии
названной Windows 2000), что действительно было реализовано в качестве
компонента Active Directory. В настоящее время Kerberos является промышленным
стандартом удаленной аутентификации пользователей.
Литература,
ссылки:
1. Гребенников
Р. Танцуем Самбу. – Журнал «Системный администратор», №11, ноябрь 2004 г. –
32-38 с.
2. Фундаментальное
обсуждение протокола Kerberos (на англ.) можно найти в ссылках на сайте
Массачусетского технологического института: http://web.mit.edu/kerberos/www/papers.html.