8 июн. 2015 г.

Squid + Samba4 AD Kerberos Authentication

Краткая заметка о том, как задружить Squid 3 и Active Directory (на базе Samba 4) с помощью Kerberos. При правильной настройке пользователь будет авторизовываться на прокси-сервере прозрачно для себя с учетной записью пользователя домена (то бишь с той же учеткой, под которой он авторизовался в ОС).
Дано: 
 - домен EXAMPLE.ORG (samba4-ad-dc 4.1, level=2008_R2)
 - контроллер dc0.example.com
 - шлюз gw0.example.com (squid 3.4)
Также обязательно должен быть настроен DNS: имена контроллера, шлюза должы корректно разрешаться как прямо, так и обратно.

Чтобы не возиться с установкой и настройкой samba на шлюзе, используем keytab-файл. Для этого создаем пользователя в AD:
root@dc0:~#samba-tool user add proxy_auth
Отключаем срок действия пароля:
samba-tool user setexpiry proxy_auth --noexpiry
Создаем service principal для этого пользователя (создадим пару для fqdn и имени хоста)
samba-tool spn add HTTP/gw0 proxy_auth
samba-tool spn add HTTP/gw0.example.com proxy_auth
Экспортируем полученные значения в файл (также для полного и короткого имени хоста):
samba-tool domain exportkeytab gw0.keytab \
--principal=HTTP/gw0.example.com@EXAMPLE.COM
samba-tool domain exportkeytab gw0.keytab --principal=HTTP/gw0@EXAMPLE.COM
Проверяем работоспособность:
root@dc0:~# klist -ke ./gw0.keytab
Keytab name: FILE:./gw0.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   1 HTTP/gw0.example.com@EXAMPLE.COM (des-cbc-crc)
   1 HTTP/gw0.example.com@EXAMPLE.COM (des-cbc-md5)
   1 HTTP/gw0.example.com@EXAMPLE.COM (arcfour-hmac)
   1 HTTP/gw0@EXAMPLE.COM (des-cbc-crc)
   1 HTTP/gw0@EXAMPLE.COM (des-cbc-md5)
   1 HTTP/gw0@EXAMPLE.COM (arcfour-hmac) 
Далее переносим keytab-файл на шлюз и кладем в директорию squid-а с соответствующими правами:
root@gw0:~# ls -l /etc/squid3/gw0.keytab
-rw------- 1 proxy proxy 372 июн  8 09:45 /etc/squid3/gw0.keytab
Корректируем конфигурацию клиента kerberos на шлюзе (должен быть установлен пакет krb5-user):
root@gw0:~# cat /etc/krb5.conf
[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_kdc = no
    dns_lookup_realm = no
    ticket_lifetime = 24h
    default_keytab_name = /etc/squid3/gw0.keytab
; for Windows 2008 with AES
    default_tgs_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
    default_tkt_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
    permitted_enctypes = aes256-cts-hmac-sha1-96 rc4-hmac des-cbc-crc des-cbc-md5
[realms]
    EXAMPLE.COM = {
        kdc = dc0.example.com
;        kdc = dc2.example.com
        admin_server = dc0.example.com
        default_domain = dc0.example.com
    }
[domain_realm]
    .example.com = EXAMPLE.COM
    example.com = EXAMPLE.COM
Авторизуемся на контроллере домена через kerberos:
root@gw0:~# kinit administrator
Password for administrator@EXAMPLE.COM:
Warning: Your password will expire in 39 days on Пт 17 июл 2015 21:43:57
Проверяем наличие тикета:
root@gw0:~# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@EXAMPLE.COM
Valid starting       Expires              Service principal
08.06.2015 15:17:05  09.06.2015 01:17:05  krbtgt/EXAMPLE.COM@EXAMPLE.COM
        renew until 09.06.2015 15:17:02
Проверяем аутентификацию в домене с помощью keytab-файла по имени principal:
root@gw0:~# kinit -V -k -t /etc/squid3/gw0.keytab HTTP/gw0.example.com@EXAMPLE.COM
Using default cache: /tmp/krb5cc_0
Using principal: HTTP/gw0.example.com@EXAMPLE.COM
Using keytab: /etc/squid3/gw0.keytab
Authenticated to Kerberos v5
Была тут проблема, с которой долго бился: аутентификация не проходила с ошибкой:
kinit: Client not found in Kerberos database while getting initial credentials
Оказалось, что при создании spn samba-tool не обновляет в учетной записи пользователя, к которому этот spn привязывается, поле userPrincipalName. А именно по этому полю ищется совпадение. Решение (найдено тут) - вручную поправить соответствующее поле userPrincipalName на HTTP/gw0.example.com@EXAMPLE.COM.
Сделать это можно с виндовой рабочей станции (или сервера) с установленным пакетом RSAT. Нужное поле находится во вкладке Учетная запись и называется Имя входа пользователя. Так как @example.com автозаполняется, то в поле следует внести HTTP/gw0.example.com .

Отлично, теперь squid. Получаем тестовый токен для хелпера negotiate_kerberos_auth:
root@gw0:~# /usr/lib/squid3/negotiate_kerberos_auth_test gw0.example.com
Token: YIIFFwYGKwYBBQUCoIIFCzCCBQegJzAlBgkqhkiG9xIBAgIGBSsFAQUCBgkqhkiC9xIBAgIGBisGAQUCBaKCBNoEggTWYIIE0gYJKoZIhvcSAQICAQBuggTBMIIEvaADAgEFoQMCAQ6iBwMFAAAAAACjggPlYYID4TCCA92gAwIBBaEJGwdLRUxMLlJVoh4wHKADAgEDoRUwExsESFRUUBsLZ3cwLmtlbGwucnWjggOpMIIDpaADAgEXoQMCAQGiggOXBIIDk1VCfz8xbDhCazPRbG86+t0vQIAR69XdCcHCFBgakA2fFlcBvIiW3JUFiJdcJMPX17yHPpVzPzNeDe3nF61pqZ0nXQHGn+MHJuXy13IHY5B4/GNeHXwbOTOFFX0m1Q4zVUWGzqL6yxXEGHHSjNWbLxwBxBgNFSKCVkkFWBZg3j9qD9SdsatZ/MVSxAwjF2Q4VhX/gB6WI6Ah/UN3K5JtDYWHBv8rJjpjfuvk9nSVryZykSJc0fi4YWnrobCFs7jpnuZhpLjQhQBFeEmTq4DJEnGMAfx4K+UnAR9M74SPUNOF9W1Wiyqp/BYBwGgw/Q5txye5up0ELksclI1SvfxU0ojsqcdPPHuv9bz7O+KAWc+K8F9bHVHYTbax6DCpCsS+nss97ywZkP5gHuEYDAmSu2kOpD4AlF2BgBTe6OIo42z0GHq7UMyBlhGf615PR73WlkEoVt08qSVaJGzYGGXS4pvqEzZWJwau7wG43FXDiwA7nNTFcW8MkwjkrsWeoxa/CSVAl1Y2La3CJSrFBa/yFyLYCIyPHTN5stq03eKLBBGVqI83v7ey7gJrtKaQO0+a2IllOOYPbdsIYoEAhjv4oOpIvnqyLhFWvceSAbgjX/+wXa6B2hHvgzTsf2ZZlC+2FBWgRyPTfxNrZ+gb2Q2mKJXUH4rpR2KfSVwsjTZMP1C2/skWZjfiXHX4GuPE+NB2UeMTVW2BVgbk3lATJho2hHJTrNwQ0YkHL0ZMTxpfvGsVID6we9wchrgF9axYZY9e9oBG9Y5DH9sX9BNTK/lMnAnPoZ698dUudlOzXHsO2MUVpYXQzY6YIWihZrJzM6ivaqZMFHOFi3oHdjGfEyyqiEzqQvKnFKU1pQCVzP4WRzZQ4WFiZ87yTH+7Bwk5QjGTeVXcChRC2MvxlDQIoAg7I1Up6EKtmjKY1gp6HzV4A9xMoGiPjyjmcYfjgmxLha4yLmqBA+33vtYL2N6/1+er5I/2oTOIH00BeenFn7qBqX7qF/OqBUrfRWlErQvlUkqheMwrenYASfY72YjLBBFyvUSqlSU/s9DhJ9wLY+WoBcGe0ng0eB1yZu595ZeIXU9grltJZOnXT+R8FFU3LT8MeJdXY/ToUz6roqIsUWTuIPu5bKgbM9vcaxPHun5HMlzFEe9nG1fufjObx05+mBE/lvkt2AnVL5zApYNB9ClmhvlvBjQCtyaT1dHBCratzm2dUiEStaSBvjCBu6ADAgEXooGzBIGwr4Mz/FJAstS7OW4Ir3U1PMDDyS1qWXwb/QHJiEcnKNMAnCjoYuotnR9kHHTYicHOoex+DQADiRC718D0uXHPYzmHcBz7a15jSO1uYQxT2IQEZ+xXLBttpi2ZzItyEBBkkIjQy3kPgdxKEnFdpcxmjDKUUtEI2PtxS5w5syOZvfbyTI8CW3YM7pUsxPLkfB40xC8wn5S1tFpjVHBPBmZc3LL4kxto94F0/yGTsMrojuM=
Теперь запускаем проверку хелпера. Для этого в примере ниже следует написать YR и после пробела вставить всю последовательность после ":" в выводе negotiate_kerberos_auth_test:
root@gw0:~# /usr/lib/squid3/negotiate_kerberos_auth -d -s GSS_C_NO_NAME
negotiate_kerberos_auth.cc(212): pid=5609 :2015/06/08 14:20:25| negotiate_kerberos_auth: INFO: Starting version 3.0.4sq
YR <вставить токен>
AF oRQwEqADCgEAoQsGCSqGSIb3EgECAg== administrator@EXAMPLE.COM
Если в выводе получаем строчку, начинающуюся с AF, значит, хелпер работает корректно.
Ключ -d у хелпера дает нехилый такой дебаг, котороый попадает в cache.log, поэтому если все работает как нужно, лучше его убрать.
Уничтожаем все полученные тикеты:
kdestroy
Вот это место мне не нравится, но более изящного решения я не нашел. Передаем squid расположение keytab-файла через переменную окружения:
/etc/init.d/squid:
##for Kerberos Auth
KRB5_KTNAME=/etc/squid3/gw0.keytab
export KRB5_KTNAME
Это действие стоит держать в памяти, так как при обновлении приложения файл может затереться. К тому же после правки init-файла на него начинает ругаться systemd и требовать обновления:
systemctl daemon-reload
Кое-где встречал предложения создать файлик /etc/default/squid и прописать переменную там. Хоть такая передача параметров и соответствует философии Debian, конкретный squid3 при запуске этот файл не ищет, а значит, и параметры оттуда получать не будет.
Наконец, настраиваем сам squid:
squid.conf:
auth_param negotiate program /usr/lib/squid3/negotiate_kerberos_auth -s GSS_C_NO_NAME
auth_param negotiate children 20
auth_param negotiate keep_alive on
acl testauth proxy_auth REQUIRED
http_access allow testauth localnet
Таким образом, любой пользователь, пришедщий на прокси-сервер, попадает под proxy_auth REQUIRED, берет тикет для аутентификации у контроллера домена, передает его прокси-серверу и получает доступ в интернет через acl testauth. Вот тут в конце статьи довольно внятное описание процесса.