Aутентификация Squid+Kerberos c LDAP авторизацией в Active Directory
Сразу оговорюсь, пост не мой, его попросила разместить одна скромная девушка
.
Опробовав схему Squid и LDAP-аутентификация из Active Directory обнаружила некоторые неудобства. (см. комментарии от Аnna)
Вариант с NTLM мне не подходит т.к. для него нужно членство в домене и использование Samba, что меня не устраивает.
Т.о. приходим к идее проверять пользователя через Kerberos.
Преимущество в том, что пользователь даже не знает что его credentials проверяют, ему не нужно вводить логин пароль. Все берется из его текущей Windows сессии.
Если есть желание подковаться в теории, то читаем вот это
.
До манипуляций рабочая машина у меня:
Debian Etch 2.6.5-6etch1
Squid Cache: Version 2.6.STABLE5
в стабильной версии —
libkrb53 1.4.4-7etch5
krb5-user 1.4.4-7etch4
ldap сервер не нужен.
Для аутентификации пользователя в Kerberos необходима схема auth_param negotiate с хелпером squid_auth_kerb.
В стандартной сборке сквида этой схемы нет (см. squid -v).
Данная схема появилась только начиная с версии сквида 2.6.14
Судя по списку файлов squid3
Поэтому — смотрим на source файлы для следующей сборки Debian — Lenny, где в версии 2.7 керберос уже поддерживается, а сам сквид уже в стадии Stable. Lenny обещают в сентябре, думаю там уже не придется что то подкручивать.
Маленькое отступление — тестировалось все на виртуальной машине с Ubuntu Server 8.04, т.к. она основана на debian packages и версии нужных пакетов в ней выше чем в Etch. Как сделать это на Etch Debian расскажу ниже.
Версии пакетов на убунту:
krb5-config — 1.17
krb5-user — 1.6.dfsg.3~beta1-2ubuntu1
libkrb5-dev — 1.6.dfsg.3~beta1-2ubuntu1
libkrb53 — 1.6.dfsg.3~beta1-2ubuntu1
squid — 2.6.18
1. Сборка сквида с необходимыми параметрами
Отступление: по началу я пробовала собрать пакеты из src для текущей версии 2.6.18, но там нужно было править файл rules, потому что по умолчанию не собиралась схема negotiate, и делать какие то ручные компиляции.
dpkg-source -x squid_2.7.STABLE3-1.dsc
В файле debian/rules который dpkg использует для сборки пакета, видно, что собираться сквид будет с нужными нам параметрами, а именно
--enable-auth="basic,digest,ntlm,negotiate" \ --enable-negotiate-auth-helpers=squid_kerb_auth \ --enable-external-acl-helpers="ldap_group" \
Поскольку digest,ntlm не нужны — их можно не собирать. Естественно, в системе должны быть установлены все пакеты необходимы для сборки .deb из src. (dpkg-dev, debconf-utils, dpatch, build-essential, libdb-dev, libgss-dev, libgss0, libldap2-dev, libpam0g-dev, sharutils, po-debconf, libkrb5-dev, libgssglue-dev, и пр.)
На самом деле, при попытке собрать командой dpkg-buildpackage-rfakeroot -b (если вы хотите собрать пакет не будучи рутом, это можно сделать с использованием -rfakeroot.
Пакет fakeroot должен быть установлен) система скажет каких пакетов ей не хватает для сборки, поэтому заранее ставить все подряд не обязательно.
Если у вас что то не получится с таким способом сборки, то
debian/rules build debian/rules binary
После сборки пакета имеем 3 файла
squid_2.7.STABLE3-1_i386.deb squid-common_2.7.STABLE3-1_all.deb squid-cgi_2.7.STABLE3-1_i386.deb
Ставим squid-common и squid.
Теперь надо собрать хелпер. Дело в том, что в исходниках дебиана предусмотрена возможность использования как MIT kerberos так и Heimdal, поэтому сам хелпер собрался под нечто неопределенное(без поддержки SPNEGO), и при тестировании полностью сконфигурированных(пп 1-4) squid+kerb давал ошибку.
2008/08/04 18:33:48| squid_kerb_auth: parseNegTokenInit failed with rc=101 2008/08/04 18:33:48| squid_kerb_auth: received type 1 NTLM token (squid_kerb_auth): ../../../../src/lib/gssapi/generic/util_validate.c:162: g_validate:Assertion `(&(&_m->os)->n)->initialized == K5_MUTEX_DEBUG_INITIALIZED' failed.
Поэтому в исходниках из файла ./helpers/negotiate_auth/squid_kerb_auth/readme.txt копируем кусок
#!/bin/sh DEFINE_SPNEGO=-DHAVE_SPNEGO #MIT DEFINE="$DEFINE_SPNEGO -D__LITTLE_ENDIAN__" INCLUDE=-Ispnegohelp LIBS="-lgssapi_krb5 -lkrb5 -lcom_err" # SPNEGO="spnegohelp/derparse.c spnegohelp/spnego.c spnegohelp/spnegohelp.c spnegohelp/spnegoparse.c" SOURCE="squid_kerb_auth.c base64.c" gcc -o squid_kerb_auth $DEFINE $INCLUDE $SOURCE $SPNEGO $LIBS
В файл и запускаем его. Полученный после перекомпиляции файл squid_kerb_auth кладем в /usr/lib/squid (или ту директорию куда ваш сквид сложил все хелперы).
2. Windows AD DC
Теперь надо создать на АД тикет(кейтаб) для пользователя, под которым будет проверяться валидность win-пользователя собравшегося в интернет.
В АД создаем пользователя у которого будет никогда не кончающийся пароль и никогда не блокирующийся аккаунт(напр. AD=mydomain.lan;user=krbldap; пароль=krbldappassword; )
В AD DNS вносим записи про наш squid сервер напр. vm-ubuntu.mydomain.lan(A) & (PTR) (если у вас самба, и линукс введен(join) в домен, то эти записи там есть)
C:\Program Files\Support Tools>ktpass -princ HTTP/vm-ubuntu.mydomain.lan@MYDOMAIN.LAN -mapuser krbldap -crypto des-cbc-md5 -pass "krbldappassword" -ptype KRB5_NT_SRV_HST -out krbldap.mydomain.lan.keytab
Важно указать принципалом именно hostname (в данном примере — vm-ubuntu) потому что, в свойствах ФФ и ИЕ прописываем vm-ubuntu.mydomain.lan а не IP. Если все таки необходимо указывать иное имя , а не то, что отдает дебиан по hostname -a, его нужно указать сквиду в параметре visible_hostname conf файла.
Копируем созданный файл krbldap.mydomain.lan.keytab в /etc/squid .
3. Kerberos. Настройка krb5.conf
[libdefaults] default_realm = MYDOMAIN.LAN dns_lookup_realm = true dns_lookup_kdc = true kdc_timesync = 1 ccache_type = 4 forwardable = true proxiable = true [realms] MYDOMAIN.LAN = { kdc = ad_server.mydomain.lan:88 admin_server = ad_server.mydomain.lan default_domain = mydomain.lan } [domain_realm] .mydomain.lan = ad_server.mydomain.lan mydomain.lan = ad_server.mydomain.lan
Проверяем, сможет ли сквид зарузить созданный тикет.
!!! NB разница во времени между линуксом и АД должна быть не больше 5 минут.
kinit -V -k -t /etc/squid/krbldap.mydomain.lan.keytab HTTP/vm-ubuntu.mydomain.lan
Если все удачно, вы получите ответ «Authenticated to Kerberos v5»
Проверить список тикетов в кэше можно командой klist.
На сам тикет ставим права
chmod 400 /etc/squid/krbldap.mydomain.lan.keytab сhown nobody /etc/squid/krbldap.mydomain.lan.keytab
4. Настройка сквида
В файл /etc/init.d/squid добавляем строки
KRB5_KTNAME=/etc/squi/krbldap.mydomain.lan.keytab export KRB5_KTNAME
Для того чтобы аутентифицировать пользователя, в файл squd.conf добавляем схему negotiate и хелпер squid_kerb_auth (никакой другой схемы у меня не указано, т.к. я раздаю инет только пользователям членам домена АД. Для других пользователей можно включить basic (см. статью Dormestmass'a про аутентификацию через LDAP))
(здесь, и далее все добавления делаются в соответствии с контекстным хелпом squid.conf файла, не забывайте что порядок появления строк в файле имеет значение)
auth_param negotiate program /usr/lib/squid/squid_kerb_auth -d -s HTTP/vm-debian.mydomain.lan@MYDOMAIN.LAN auth_param negotiate children 5 auth_param negotiate keep_alive on
Опция -d (debug) позволит в протоколе видеть ошибки — потом можно отключить. Без нее на этапе тестирования может просто тихо не работать, не сообщая даже ошибки.
Теперь нужно авторизовать аутентифицированного пользователя. И делаем мы это с помощью squid_ldap_group.
Привожу пример просто для группы пользователей, которым можно ходить в интернет. если нужно разбивать на группы с урезанием ширины пропускания — настройки аналогичные. Настройки групп см. опять же в статье Dormestmass'a .
В примере:
группа INTERNET_ALLOWED создана в OU spb.mydomain.lan — туда добавлены пользователи которым разрешено ходить в интернет.(напр any_ad_user)
IP.OF.AD.DC = IP адрес AD сервера указанного в
krb5.conf (хотя можно писать и имя).
Проверяем в sh сможет ли сквид проверить права пользователя
#/usr/lib/squid/squid_ldap_group -R -b "dc=mydomain,dc=lan" -f "(&(objectclass=user)(sAMAccountName=%v)(memberof=cn=%a,ou=spb,dc=mydomain,dc=lan))" -D "krbldap@mydomain.lan" -w "krbldappassword" -K -d IP.OF.AD.DC any_ad_user INTERNET_ALLOWED OK other_user INTERNET_ALLOWED ERR
Если вводя данные в формате «ADuser ADgroup» вы получаете ожидаемое — значит работает. проверять можно и на любых других группах АД, не обязательно связанных со сквидом.
Если проверка работает , добавляем в squid.conf
external_acl_type ldap_check ttl=1200 %LOGIN /usr/lib/squid/squid_ldap_group -R -b "dc=mydomain,dc=lan" -f "(&(objectclass=user)(sAMAccountName=%v (memberof=cn=%a,ou=spb,dc=mydomain,dc=lan))" -D "krbldap@mydomain.lan" -w "krbldappassword" -K -d IP.OF.AD.DC acl inet_access external ldap_check INTERNET_ALLOWED http_access allow inet_access http_access deny all
ttl в данном случае — время в секундах проверки выданных пользователям credentials т.е. если вы выведете пользователя any_ad_user из AD группы «INTERNET_ALLOWED» то его права на хождение в веб проверятся в течении 20 минут. по умолчанию ttl=3600s.
Хотя здесь опция -d это --debug, без нее мне запустить не удалось.
А вот самая интересная здесь как раз опция -K которая отвечает за parse username. Грубо говоря, она отделяет имя пользователя от @REALM получая на входе %LOGIN.
Перезапускаем сквид и вуаля!
Кстати, по истечении времени keytab, команда klist ничего не показывает, но видно что тикет получает renew в кэше
Kerberos 4 ticket cache: /tmp/tkt0
Видимо действительно после загрузки в кеш его можно сразу kdestroy.
5. Проверка. Особенности работы пользовательского браузера.
Сразу говорю в IE версии < 7 не работает. Это связанно с отсутствием поддержки proxy_auth в более ранних версиях IE.
Почитать можно здесь
У меня в сети IE 6.0; в IE7 все сделанное не проверяла — т.к. у меня ее нет, и IE 7 не имеет дистрибутивов под 2000, дистриб от ХП — не ставится, ему не хватает cryptography service который в вин2000 отсутствует. никакие махинации (пол дня) не помогли.
Оперу тоже не проверяла.
(Если протестируете — не поленитесь — отпишите результаты в комментарии).
В ФФ работает без проблем. (тестировалось на версии 3.0.0.)
В моем случае пришлось поступить так:
т.к. пара сервисов, используемых в работе сотрудников требуют работы ActiveX с проверкой CA, что работает только в IE, то я через iptables открыла доступ к этому сайту на порты 80, 443 мимо сквида. (остальные обращения на 80,443 напрямую — закрыть).
В Group Policy на AD выставила всем пользователям No proxy в настройках IE.
Поскольку авторизующий сквид не может быть быть transparent, то всем пользователям в FF Выставлен прокси руками. (наверно мой следующий исследовательский шаг — это WPAD)
Т.о. мимо сквида будет работать только этот сайт через IE (вне зависимости от версии). Все остальное заработает только в ФФ.
Более того, чтобы у пользователей была полная иллюзия работы только в FireFox туда поставлен IE Tab add-on, с занесением в фильтр адреса того самого сайта. И набирая в ФФ адресной строке адрес или открывая из bookmarks — ФФ автоматически открывает iexplore.exe внутри своего таба.
6. debian. «пока не пришел Lenny»
Проблема дебиана в том, что все пакеты, затрагиваемые данной схемой работы у него староваты. В частности, даже собранный образом сквид не может обработать ответ АД на запрос об аутентификации, потому что krb5 его выдает неправильно(староват — шепелявит
).
И тем, кто не боится брать пакеты testing- можно делать следующее...
В /etc/apt/source.list прописать взятие как stable так и testing.
Сделать apt-update
Мой apt, будучи не в силах обработать такой огромный список пакетов выпадал с ошибкой.
E: Dynamic MMap ran out of room
Для решения проблемы, цитирую
Put this in /etc/apt/apt.conf and the problem goes away, at least it did for me today: APT::Cache-Limit 12582912;
И после апдейта обновляйте пакет
apt-get -t testing install krb5-user
Он потянет за собой кучу libc и прочих. Но после этого — все заработает.
rem: для Etch собирать сквид пришлось не через dpkg-buildpackage, а через запуск debian/rules (build \ binary)
Желаю всем успехов во внедрении решения.
Спасибо Роману Шрамко (Dormestmass) за предоставленное место для размещения этого howto и
Популярность: 100%
Похожие заметки
Squid и LDAP-аутентификация из Active DirectorySquid: привязка имени пользователя к IP
Аутентификация в Apache из LDAP
Netscape Messaging Server. Перенос Directory
Фильтры для поиска в LDAP
Roman Shramko
2 Июн, 2010
А будет ли возможно например дать доступ для компьютеров в определенном OU??
Джон
20 Июл, 2010
в опере тоже фиг работает
Ross
9 Фев, 2011
kinit -V -k -t /etc/squid/krbldap.mydomain.lan.keytab HTTP/vm-ubuntu.mydomain.lan
НУ не работает у меня ЭТО. Два дня бьюсь.
kinit: Key table entry not found while getting initial credentials
Может подскажет сообщество как побороть это.
Сенкс
9 Фев, 2011
Попробуйте написать непосредственно автору статьи на адрес anna.skorokhodova[at]gmail.com. Я, к сожалению, Вам не смогу помочь в этом вопросе, поскольку связка с АД у меня уже давно не используется.
Ross
9 Фев, 2011
Спасибо.
Voffka
14 Мар, 2011
да мануал на первый взгляд нормальный, но присмотревшись понимаешь что он со сплошными недочетами и недосказанностями. ТРОЕЧКА с натяжной.
фразы типа
«rem: для Etch собирать сквид пришлось не через dpkg-buildpackage, а через запуск debian/rules (build \ binary)»
лучше бы расшифровать. моменты со сборкой хелпера- ПОЧЕМУ бы не расписать, что файл надо сделать исполняемым и т.д.
Кстати, да. После всего проделанного — не заработало. в кэш.лог ругня что нету /etc/krb5.keytab и прочего.
Voffka
14 Мар, 2011
Допущена ошибка при формировании кейтаб. У меня заработало вот так:
ktpass -princ HTTP/squid.domain@REALM -mapuser squid.domain@domain.local -crypto rc4-hmac-nt pass squid-pass -ptype KRB5_NT_SRV_HST -out squid.domain.keytab
тут надо заметить что мапюзер указывается именно с @домен, иначе венда ругается. тут крипто другой, но с ним зато потом проходит нормально все проверки.
Voffka
14 Мар, 2011
вот еще 1 момент
вот как тут сказано «Please note that there is no direct communication between KDC ulmo and webserver beren when using SPNEGO!».
вообщем после пересборки того файла утентиФИКАЦИИ кинит больше не сможет работать с кейтабом.
14 Мар, 2011
Спасибо за комментарии по работоспособности описанной в посте схемы!
К сожалению, статью писал не я, да и не занимаюсь я подобными вещами уже давно.
Так что пока возможности переписать её чтобы получился 100% рабочий вариант с учетом всех изменений пока не получается.
Ross
15 Мар, 2011
У меня всё заработало, ~ 1 месяц уже работает, полёт нормальный. Статью буду писать.
К стати хочу сделать подобные вещи и для почты.
Postfix+Cyrus-Imap (or Dovecot). Застрял ...
Кому интересно поделюсь, может вместе решим...
Спасибо.
Voffka
16 Мар, 2011
Очень бы хотел уточнить момент с кейтабом. У меня kinit проходит для юзера нормально, все ок. Но кейтаб когда проверить хочу — Client not found in Kerberos database while getting initial credentials и хоть ты тресни ... Данна запись говорит о том что оно может нормально достучатся до реалма, но не может резолвить юзера. Юзер такой есть и кинит проходит нормально
Ross
16 Мар, 2011
Киньте полностью вывод kinit -V -k -t etc...
KsAdmin
8 Апр, 2011
Долго мучался, но теперь заработало. Проблема еще была в фильтре поика группы пользователя. У меня только так заработало. external_acl_type ldap_check ttl=1200 %LOGIN /usr/lib/squid/squid_ldap_group -R -b «dc=domain,dc=lan» -f «(&(objectclass=user)(sAMAccountName=%v)(memberof=cn=%a,CN=Builtin,DC=domain,DC=lan))» -D «testuser@domain.lan» -w «userpassword» -K -d -h 192.168.1.2 То есть вместо OU=Builtin заработало с CN=Builtin. Собрать Squid предлагаемый по ссылке не получилось зато собрал из source (apt-get source squid3) Работает на squid3, но helper squid_ldap_group из squid2-7. Так как в хелпере от 3-го нет ключа -K чтобы отделить от имени пользователя часть «@domain.lan». От контроллера домена и DNS тоже много чего зависит. Чтобы все заработало домен разварачивал шесть раз))).
ветеран WoW
13 мая, 2011
да потому что не нужно там рестриктить тип криптования. может сложиться ситуация когда машина со сквидом будет искать там тикет с другим типом.
Fr0sT
4 Ноя, 2011
Но теперь не проходит авторизация в cache.log
2011/11/03 09:26:32| squid_kerb_auth: Got 'YR TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAHIXAAAADw==' from squid (length: 59).
2011/11/03 09:26:32| squid_kerb_auth: parseNegTokenInit failed with rc=101
2011/11/03 09:26:32| squid_kerb_auth: received type 1 NTLM token
2011/11/03 09:26:32| squid_kerb_auth: Got 'YR TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAHIXAAAADw==' from squid (length: 59).
2011/11/03 09:26:32| squid_kerb_auth: parseNegTokenInit failed with rc=101
2011/11/03 09:26:32| squid_kerb_auth: received type 1 NTLM token
C этим как бороться
?