Dormestmass: Админ — это состояние души

Aутентификация Squid+Kerberos c LDAP авторизацией в Active Directory


Сразу оговорюсь, пост не мой, его попросила разместить одна скромная девушка :) .


Опробовав схему Squid и LDAP-аутентификация из Active Directory обнаружила некоторые неудобства. (см. комментарии от Аnna)

Вариант с NTLM мне не подходит т.к. для него нужно членство в домене и использование Samba, что меня не устраивает.

Т.о. приходим к идее проверять пользователя через Kerberos.

Преимущество в том, что пользователь даже не знает что его credentials проверяют, ему не нужно вводить логин пароль. Все берется из его текущей Windows сессии.

Если есть желание подковаться в теории, то читаем вот это
http://technet.microsoft.com/ru-ru/library/bb742431 (en-us,printer).aspx.

До манипуляций рабочая машина у меня:

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 для дебиана, схемы negotiate здесь тоже нет.

Поэтому — смотрим на 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, и делать какие то ручные компиляции.

Скачиваем и распаковываем source (3 файла должны лежать в одной директории) из lenny репозитария.

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.

Почитать можно здесь http://support.microsoft.com/kb/321728/.

У меня в сети 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 и Станиславу В. за всякого рода подсказки.

anna.skorokhodova@gmail.com


Популярность: 100%

P.S.

Изготовление дисковых ножей
  • А будет ли возможно например дать доступ для компьютеров в определенном OU??

  • в опере тоже фиг работает

  • 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

    Может подскажет сообщество как побороть это.

    Сенкс

  • Попробуйте написать непосредственно автору статьи на адрес anna.skorokhodova[at]gmail.com. Я, к сожалению, Вам не смогу помочь в этом вопросе, поскольку связка с АД у меня уже давно не используется.

  • Спасибо.

  • да мануал на первый взгляд нормальный, но присмотревшись понимаешь что он со сплошными недочетами и недосказанностями. ТРОЕЧКА с натяжной.

    фразы типа

    «rem: для Etch собирать сквид пришлось не через dpkg-buildpackage, а через запуск debian/rules (build \ binary)»

    лучше бы расшифровать. моменты со сборкой хелпера- ПОЧЕМУ бы не расписать, что файл надо сделать исполняемым и т.д.

    Кстати, да. После всего проделанного — не заработало. в кэш.лог ругня что нету /etc/krb5.keytab и прочего.

  • Допущена ошибка при формировании кейтаб. У меня заработало вот так:

    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

    тут надо заметить что мапюзер указывается именно с @домен, иначе венда ругается. тут крипто другой, но с ним зато потом проходит нормально все проверки.

  • вот еще 1 момент

    www.grolmsnet.de/kerbtut/

    вот как тут сказано «Please note that there is no direct communication between KDC ulmo and webserver beren when using SPNEGO!».

    вообщем после пересборки того файла утентиФИКАЦИИ кинит больше не сможет работать с кейтабом.

  • Спасибо за комментарии по работоспособности описанной в посте схемы!

    К сожалению, статью писал не я, да и не занимаюсь я подобными вещами уже давно.

    Так что пока возможности переписать её чтобы получился 100% рабочий вариант с учетом всех изменений пока не получается.

  • У меня всё заработало, ~ 1 месяц уже работает, полёт нормальный. Статью буду писать.

    К стати хочу сделать подобные вещи и для почты.

    Postfix+Cyrus-Imap (or Dovecot). Застрял ...

    Кому интересно поделюсь, может вместе решим...

    Спасибо.

  • Очень бы хотел уточнить момент с кейтабом. У меня kinit проходит для юзера нормально, все ок. Но кейтаб когда проверить хочу — Client not found in Kerberos database while getting initial credentials и хоть ты тресни ... Данна запись говорит о том что оно может нормально достучатся до реалма, но не может резолвить юзера. Юзер такой есть и кинит проходит нормально

  • Киньте полностью вывод kinit -V -k -t etc...

  • Долго мучался, но теперь заработало. Проблема еще была в фильтре поика группы пользователя. У меня только так заработало. 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 тоже много чего зависит. Чтобы все заработало домен разварачивал шесть раз))).

  • да потому что не нужно там рестриктить тип криптования. может сложиться ситуация когда машина со сквидом будет искать там тикет с другим типом.

  • Но теперь не проходит авторизация в 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 этим как бороться :) ?

Вы можете следить за обсуждением с помощью RSS 2.0 ленты.