Aдминистраторы во всем мире пользуются proxy-сервером Squid для регулирования доступа пользователей к ресурсам Internet. Squid позволяет проводить авторизацию пользователей и принимать решение о предоставлении доступа к тому или иному ресурсу на основе полученных данных. Для Squid доступно множество схем авторизации: с помощью системных модулей PAM, по IP-адресу и т. п. — все это благодаря наличию возможности подключения внешних программ для проведения соответствующих операций. Кроме того, Squid имеет развернутую систему протоколирования, а ведущиеся журналы доступа дают богатую пищу для анализа.
В крупных организациях неудобно вести несколько баз пользователей для отдельной авторизации на том или ином сервере, поэтому администраторы стараются унифицировать формат хранения соответствующих данных и сделать их доступными для различных серверов. В перспективе такое решение может быть использовано как «первый шаг» на пути к организации единого хранилища. Оно, конечно, не будет однократной регистрацией (Single Sign-On, SSO) в полном смысле, так как SSO подразумевает однократное введение пользовательских данных, после чего доступ к ресурсам осуществляется автоматически. Но этот вариант весьма интересен с точки зрения унификации данных при минимальных начальных инвестициях (в данном случае придется приобрести только продукт Novell, поскольку Squid распространяется бесплатно) без учета конечной стоимости владения. Кроме того, в принципе может быть разработана аналогичная схема по переводу учетных данных пользователей систем UNIX в Novell NDS, без необходимости локального определения пользователя.
Одним из возможных хранилищ является, как уже было сказано, Novell NDS, где можно размещать учетные данные и предоставлять их как по протоколу IPX, так и по протоколу LDAP. Каталог — это база данных, оптимизированная для чтения, поскольку изначально предполагается, что операции чтения производятся намного чаще операций записи, в противном случае быстрее и удобнее было бы пользоваться обычной СУБД, например MySQL. Данные в каталогах хранятся в соответствии со своими атрибутами и классами, что значительно ускоряет поиск. Упрощенным протокол LDAP называется потому, что стандартный сервер каталогов не поддерживает транзакции и другие функции, присущие серверу баз данных. Таким образом, каталоги предназначены для иерархического хранения в них простых данных, например имя пользователя, его электронный адрес и т. п. Более подробное описание LDAP опубликовано в документе RFC 2251 «The Lightweight Directory Access Protocol (v3)» (см. также статью В. Шабата «Каталоги LDAP и их применение» в этом номере).
В последние версии NDS включена поддержка LDAP. Многие же крупные организации хранят пользовательские данные именно в NDS (LDAP), поэтому схему авторизации в Squid стоит выполнить таким образом, чтобы авторизация проводилась непосредственно в NDS, поскольку это исключает необходимость вести отдельную базу данных по пользователям Squid. Еще интереснее было бы иметь возможность предоставления прав доступа к пользовательским ресурсам на основе учетных данных NDS. Собственно, эти две задачи мы и попробуем решить.
Итак, проблема следующая: пользователь, желающий получить доступ к ресурсам Internet, должен подтвердить свое право на обращение к ресурсам вообще, а затем proxy-сервер, опираясь на его учетные данные, примет решение о допуске пользователя к ресурсу. Графически эта схема выглядит примерно так, как показано на Рисунке 1.
Нам потребуется загрузить и установить proxy-сервер Squid. Исходные коды программ лучше загружать и компилировать самостоятельно, так как в двоичных пакетах могут отсутствовать нужные опции. Итак, после загрузки из Internet файл Squid-2.5.STABLE1.tar.gz распаковывается в каталоге, где будет проводиться его компиляция. Обратите внимание, что поддержка внешних списков доступа, на которые опирается предлагаемая схема, появилась в Squid, начиная с версии 2.5. Следовательно, использование Squid в нашем случае ограничено версиями 2.5 и выше. Из каталога, куда распакован Squid, запускается сценарий configure со следующей командной строкой: ./configure --enable-external-acl-helpers=ldap_group. Ключевой для понимания является комбинация --enable-external-acl-helpers=ldap_group, поэтому мы остановимся на ней подробнее. Указанный параметр активизирует поддержку групп LDAP. Squid поддерживает так называемые «внешние списки доступа» (external acl), благодаря которым списки можно реализовать путем вызова внешних программ и анализа их данных. Сама программа ldap_group размещена в каталоге дистрибутива Squid, подкаталоге helpers/external_acl/ ldap_group. Она отвечает не за авторизацию, а только за определение права обращения пользователя к ресурсу, исходя из его членства в той или иной группе NDS. Выбранная программа для авторизации не входит в дистрибутив Squid, ее настройка описана ниже. Для компиляции необходимы библиотеки и заголовки сервера OpenLDAP, поэтому нужно либо установить пакет с соответствующими библиотеками и заголовками, либо скомпилировать и установить сам сервер OpenLDAP.
Итак, после завершения выполнения сценария configure компиляция производится командой make all, а установка proxy-сервера — командой make install. Теперь можно перейти непосредственно к программе авторизации пользователя в NDS. Программа ldap_auth, автором которой является Алан Спаркс, была выбрана потому, что она оказалась наиболее простой и прозрачной для внесения изменений. Нам потребовалось только добавить поддержку протоколирования в демон syslogd, в остальном же все осталось в первозданном виде. Схема авторизации Squid через внешние программы крайне проста. Программа авторизации возвращает строку ОК в случае правильной авторизации или ERR, если авторизация не была успешной. Данные в программу передаются через stdin. Для компиляции ldap_auth также необходимы заголовки и библиотеки OpenLDAP. После завершения компиляции двоичный файл ldap_auth следует скопировать в каталог libexec в том каталоге, где установлен Squid. Там же должен находиться файл squid_ldap_ group, ответственный за определение принадлежности пользователя к группе NDS. Далее обратимся непосредственно к конфигурации proxy-сервера Squid. В нашем случае она выглядит примерно так (ниже приводится только тот блок, где описываются схема авторизации и списки доступа):
auth_param basic program /opt/squid/libexec/ldap_auth 10.0.0.2 389 o=OURORG cn |
auth_param basic realm Big Organization Proxy |
auth_param basic children 5 |
auth_param basic credentialsttl 4 hours |
external_acl_type nds_all %LOGIN /opt/squid/libexec/squid_ ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v)(groupmembership=cn=%a,,o=OURORG))" |
external_acl_type nds_ftp %LOGIN /opt/squid/libexec/squid_ ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v)(groupmembership=cn=%a, o=OURORG))" |
external_acl_type nds_mail %LOGIN /opt/squid/libexec/squid_ ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v)(groupmembership=cn=%a, o=OURORG))" |
external_acl_type nds_funny %LOGIN /opt/squid/libexec/squid_ ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v)(groupmembership=cn=%a, o=OURORG))" |
external_acl_type nds_porno %LOGIN /opt/squid/libexec/squid_ ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v)(groupmembership=cn=%a, o=OURORG))" |
external_acl_type nds_banners %LOGIN /opt/squid/libexec/ squid_ldap_group -h 10.0.0.2 -b "o=OURORG" -f "(&(cn=%v) (groupmembership=cn=%a, o=OURORG))" |
acl all src 0.0.0.0/0.0.0.0 |
acl users external nds_all proxy_all |
acl users_ftp external nds_ftp proxy_ftp |
acl users_mail external nds_mail proxy_mail |
acl users_funny external nds_funny proxy_funny |
acl users_porno external nds_porno proxy_porno |
acl users_banners external nds_banners proxy_banners |
acl funny dstdomain "/opt/squid/etc/funny.domains" |
acl funmail_allow dstdomain "/opt/squid/etc/funmail.allow" |
acl mail dstdomain "/opt/squid/etc/mail.domains" |
acl porno dstdomain "/opt/squid/etc/porno.domains" |
acl porno_ip dst "/opt/squid/etc/porno.ip" |
acl banners url_regex -i "/opt/squid/etc/banners.exp" |
acl manager proto cache_object |
acl localhost src 127.0.0.1/255.255.255.255 |
acl ftp proto FTP |
acl CONNECT method CONNECT |
http_access allow manager |
http_access allow users_ftp ftp !funny |
http_access allow users_ftp ftp !porno |
http_access allow users_mail mail |
http_access allow users_porno porno |
http_access allow users_funny funny |
http_access allow users_banners banners |
http_access deny banners |
http_access deny porno |
http_access deny ftp |
http_access allow users |
http_access deny all |
Не вдаваясь в подробности общих параметров конфигурации, отметим, что /opt/squid, корневой каталог proxy-сервера, был указан при компиляции Squid в качестве параметра --prefix=/opt/squid к сценарию configure наравне с другими опциями. При самостоятельной компиляции программных пакетов именно каталог /opt следует указывать в качестве корневого, так как в результате пакет не разбрасывается по файловой системе (например, в каталоги /usr или /usr/local), а хранится в одном месте, что значительно упрощает конфигурацию и не создает беспорядка. Кстати, возможность использования опции -prefix — еще один довод в пользу самостоятельной компиляции программы. Далее мы будем исходить из того, что конфигурация Squid записана в каталог /opt/squid/etc, внешние программы — в каталог /opt/squid/libexec, файлы протокола находятся в каталоге /opt/squid/var/logs, а сам демон Squid помещен в каталог /opt/squid/sbin.
При конфигурации Squid очень важно четко задать права запуска и работы сервера. Общепринятым является запуск сервера с правами пользователя nobody и группы nogroup, что и указано в параметрах cache_effective_user и cache_effective_group.
В блоке конфигурации, где параметры начинаются со строки auth_param, описана процедура авторизации пользователя на proxy-сервере. Ниже приводятся комментарии к каждой строке.
auth_param basic program /opt/squid/libexec/ldap_auth 10.0.0.2 389 o=OURORG cnДанная строка сообщает proxy-серверу, что авторизацию надо проводить по базовому методу через вызов внешней программы /opt/squid/libexec/ldap_auth. В качестве ключей к ней передаются соответственно IP-адрес сервера NDS (10.0.0.2) и порт TCP (в нашем случае защищенное соединение с сервером не используется, поэтому порт всегда будет 389 (LDAP), если вы, конечно, не настроили изначально NDS на другой порт — тогда укажите порт, на котором находится сервер LDAP NDS). Затем серверу LDAP передается исходная точка поиска. Синтаксис LDAP подробно описан в RFC 2251, и мы на нем останавливаться не будем. Этот параметр указывает на ту запись в каталоге, от которой будет вестись поиск. Следовательно, если действительный корень вашей организации, к примеру, o=OURORG, c=ru и под записью c=ru также есть какие-то записи, то они не будут найдены. Последним параметром (cn) передается атрибут LDAP, под ним подразумевается уникальный идентификатор пользователя. Именно он служит именем пользователя. По умолчанию таким атрибутом считается uid, но его может и не быть на сервере каталогов, а вот cn присутствует всегда. Атрибутом, содержащим пароль пользователя, де-факто признан userPassword, поэтому он не упоминается в настройках вообще. Хотя при желании его можно изменить в исходном коде программы ldap_auth.
auth_param basic realm Big Organization ProxyЭтой строкой задается текст, отображаемый в окне авторизации пользователя.
auth_param basic children 5
Так регулируется количество дочерних процессов внешней авторизации, которые можно запустить одновременно. Их число зависит от размеров вашей организации: к примеру, для организации, где доступ в Internet имеют 100 человек, пяти дочерних процессов не хватит. В то же время количество процессов не должно быть чрезмерно завышенным в целях экономии ресурсов сервера.
auth_param basic credentialsttl 10 hoursСтрока определяет время, в течение которого пользовательские данные будут храниться в кэше сервера; его безопасности следует уделить особое внимание, так как учетные данные хранятся в памяти сервера в открытом виде. При перезапуске сервера данное значение сбрасывается. Кроме того, в случае перезапуска обозревателя Internet авторизоваться придется повторно. Рекомендуемое время, 10 ч, немногим больше стандартного рабочего дня.
Следующий блок конфигурации со строками, начинающимися с external_acl_type, является основополагающим в нашей схеме, так как именно в нем описывается разграничение доступа к ресурсам Internet в зависимости от учетных данных пользователя.
Рисунок 2. Дерево NDS (LDAP) |
Вызов внешнего обработчика списков доступа (ACL) начинается с параметра external_acl_type, а в следующем аргументе передается имя списка доступа. Параметр %LOGIN указывает, что для начала работы необходимо, чтобы пользователь был авторизован. Далее идет собственно вызов обработчика списка доступа, в нашем случае это /opt/squid/libexec/ squid_ldap_group. Обработчику в командной строке передаются последовательно IP-адрес сервера LDAP через ключ -h, затем исходная точка поиска через ключ -b и наконец фильтр поиска. Синтаксис фильтров LDAP описан в том же RFC 2251 и в общем случае представляет собой условия поиска в каталоге на основании указанных атрибутов или классов LDAP. На Рисунке 2 графически представлено дерево, в рамках которого будут производиться авторизация и распределение прав.
Как видно на Рисунке 2, в дереве OURORG зарегистрированы пользователь User и пять групп: proxy_mail, proxy_ftp, proxy_all, proxy_porno, proxy_funny. К группе proxy_all относятся те, у кого есть доступ к Internet, но не доступны ресурсы остальных групп. В группу proxy_mail входят пользователи, имеющие доступ к почте Web. Членам группы proxy_ftp позволен доступ к серверам FTP. Группа proxy_funny может обращаться к развлекательным ресурсам. И, наконец, название группы proxy_porno говорит само за себя.
Допустим, пользователю User необходимо предоставить возможность работать с ресурсами Internet и с почтой Web. Для этого внесем его в группы proxy_all и proxy_mail, как показано на Рисунке 3.
В формате обмена данными LDAP (LDAP Data Interchange Format, LDIF) наше дерево примет следующий вид:
version: 1 dn: cn=User,o=OURORG sn: Novell NDS User securityEquals: cn=proxy_all,o=OURORG securityEquals: cn=proxy_mail,o=OURORG objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top objectClass: ndsLoginProperties groupMembership: cn=proxy_all,o=OURORG groupMembership: cn=proxy_mail,o=OURORG description: User has an Internet account cn: User
dn: cn=proxy_all,o=OURORG
dn: cn=proxy_banners,o=OURORG
dn: cn=proxy_ftp,o=OURORG
dn: cn=proxy_funny,o=OURORG
dn: cn=proxy_mail,o=OURORG
dn: cn=proxy_porno,o=OURORG | |
Рисунок 3. Принадлежность пользователя User группам NDS (LDAP). |
На самом деле в файле LDIF будут присутствовать и другие атрибуты пользователя и групп, но здесь они пропущены, так как не имеют прямого отношения к решаемой задаче.
При внимательном рассмотрении файла LDIF можно заметить, что после добавления пользователя в группу у него появляется новый атрибут — member. В нашем случае после добавления пользователя в группы proxy_all и proxy_mail у него появились атрибуты
securityEquals: cn=proxy_all,o=OURORGsecurityEquals: cn=proxy_mail,o=OURORG
groupMembership: cn=proxy_all,o=OURORG
groupMembership: cn=proxy_mail,o=OURORG
В соответствующих группам записях появились атрибуты
equivalentToMe: cn=User,o=OURORGmember: cn=User,o=OURORG
Основываясь на указанных атрибутах, можно построить схему распределения прав между пользователями, что мы и сделаем.
Итак, фильтр поиска LDAP, на который мы уже обращали внимание, на самом деле просто просматривает запись пользователя в NDS в поисках атрибута groupMembership, указывающего на принадлежность пользователя к группе, а также атрибута cn, содержащего уникальный идентификатор пользователя. Proxy-сервер Squid допускает использование шаблонов имени пользователя и имени группы: %v — для имени пользователя и %a — для имени группы. Естественно, Squid не будет угадывать имена групп, поэтому они описываются ниже.
Далее в конфигурации Squid следует раздел привязки групп пользователей Squid к группам NDS. Обратите внимание, что речь идет именно об описании групп пользователей Squid, которые отличаются от групп NDS. Мы создали шесть групп пользователей и поставили в соответствие им группы NDS. Формат списков доступа следующий:
acl <имя acl> external <имя acl-external-type> <имя группы>Параметр «имя группы» передается в external_acl_ type для размещения в шаблоне %a.
Строка конфигурации acl all src 0.0.0.0/0.0.0.0 описывает абсолютно всех пользователей, в том числе и тех, кто не указан в конфигурации Squid напрямую.
Далее нам необходимо описать, собственно говоря, те ресурсы, к которым будет определен доступ:
acl funny dstdomain «/opt/squid/etc/funny.domains»
acl mail dstdomain «/opt/squid/etc/mail.domains»
acl porno dstdomain «/opt/squid/etc/porno.domains»
Перечисленные файлы имеют формат «.доменное_имя», а записи разделяются построчно.
Например, в funny.domains будут содержаться записи наподобие
.games.rin.ru.photosight.ru
.narod.ru
и т. п. Естественно, файлы могут дополняться и изменяться по вашему желанию.
Наконец, опишем раздел конфигурации, где определяется соответствие между пользователями и ресурсами. Он, в общем-то, не нуждается в дополнительных пояснениях, и, скорее всего, вы его измените.
http_access allow users_ftp ftp !funnyhttp_access allow users_ftp ftp !porno
http_access allow users_ftp ftp !mail
http_access allow users_mail mail
http_access allow users_porno porno
http_access allow users_funny funny
http_access allow users_banners banners
http_access deny banners
http_access deny porno
http_access deny porno_ip
http_access deny ftp
http_access allow users
http_access deny all
После создания этих списков конфигурацию можно считать завершенной. Правильность синтаксиса можно проверить командой /opt/squid/sbin/squid -k parse. В целях обеспечения безопасности для файлов конфигурации лучше определить режим доступа -rw-r-r, а владельцем файлов пользователя root сделать группу root.
Итак, после всех настроек у нас (теоретически) реализована следующая схема.
1) Пользователь User запускает обозреватель и обращается к ресурсу.2) Proxy-сервер отправляет обозревателю Internet пользователя запрос "401: Authorization required".
3) Обозреватель Internet запускает процедуру авторизации и отображает окно, где просит ввести имя пользователя и пароль.
4) Пользователь User вводит свое имя и пароль (те же, что вводились им при входе в сеть Novell).
5) Proxy-сервер Squid запускает внешнюю процедуру авторизации, которая отправляет учетные данные пользователя в NDS и возвращает OK или ERR.
6) В случае получения OK Squid разрешает доступ к ресурсу, при этом он предварительно "проконсультируется" у NDS с помощью модуля squid_ldap_ group относительно принадлежности пользователя к группе, имеющей право на доступ к данному ресурсу.
7) Если пользователь не прошел авторизацию или не принадлежит к запрашиваемой группе, Squid возвращает обозревателю Internet страницу HTML с описанием причин отказа в доступе.
Следует отметить, что при добавлении пользователя в группу Novell реально доступ к ресурсу он получит только после повторного запуска Squid командой squid -k reconfigure или из сценария запуска Squid командой /etc/init.d/squid restart.
Представленная схема удобна прежде всего самим администраторам, так как позволяет сократить количество учетных записей и применять удобный и унифицированный интерфейс (например, Novell ConsoleOne) для манипуляций правами и учетными записями пользователей NDS.
Павел Покровский — специалист по информационной безопасности. С ним можно связаться по адресу: underling@yandex.ru.
Ресурсы Internet
Proxy-сервер Squid: http://www.squid-cache.org/Novell NDS: http://www.novell.com/
OpenLDAP: http://www.openldap.org/
Auth_ldap: http://www.bayour.com/kerberos/squid-ldap_auth.tgz
RFC2251 (LDAP): http://www.faqs.org/rfcs/rfc2251.html.