среда, 12 марта 2014 г.

Squid. Аутентификация и авторизация в AD. Грабли.

Продолжение темы http://timp87.blogspot.ru/2014/02/squid-ad.html

Прошло некоторое время после внедрения озвученной схемы в промышленную эксплуатацию. Теперь можно озвучить пачку проблем, которые выявились в процессе запуска.

Так, поток сознания, может потом найду время и оформлю нормально.

1. Использование CNAME.

В интернетах пишут что с CNAME такое хозяйство не заработает. У меня в тестовой зоне и не только работает. Тут ситуация зависит от того, как этот CNAME используется. Всё работает, если keytab сделан для proxy.example.org, прокси-сервер имеет DNS имя server1.example.org, затем сделан CNAME proxy.example.org -> server1.example.org, и в браузере у пользователя в качестве прокси-сервера прописано proxy.example.org.

2. Обратная зона DNS.

Еще пишут, что для kerberos нужна рабочая обратная DNS зона (PTR). И вот это справедливо. Не было возможности проверить, касается ли это самого прокси сервера (у меня в обратной зоне для него прописано неправильное имя, и ничего, работает), но точно должны резолвиться в обратке контроллеры домена. У меня с этим проблем не было.
Они появились с пользователями из филиальских поддоменов, которые запрашивали доступ в интернет на нашей прокси. Например, NSK.EXAMPLE.ORG - Новосибирский филиал, или, KRAS.EXAMPLE.ORG - Красноярский филиал. В логе squid было видно, что такие пользователи проходят без проблем аутентификацию, но вот авторизация не шла.
В логе messages валились такие сообщения:
Mar 13 10:05:36 hostname (ext_kerberos_ldap_group_acl): GSSAPI Error:  Miscellaneous failure (see text)) unknown (Server (krbtgt/168.20.113@EXAMPLE.ORG) unknown)
Т.е. в имени тикета обрывок IP адреса контроллера филиальского домена вместо его (DC) полного имени.
В логе squid в это же время было такое:
kerberos_ldap_group.cc(437): pid=51536 :2014/03/13 06:22:09| kerberos_ldap_group: INFO: Got User: ipetrov Domain: NSK.EXAMPLE.ORG
support_sasl.cc(274): pid=51536 :2014/03/13 06:22:09| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(869): pid=51536 :2014/03/13 06:22:09| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
support_sasl.cc(274): pid=51536 :2014/03/13 06:22:09| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(869): pid=51536 :2014/03/13 06:22:09| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
support_sasl.cc(274): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(869): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
support_sasl.cc(274): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(869): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
support_sasl.cc(274): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(869): pid=51536 :2014/03/13 06:22:10| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
Судя по всему, прокси не удается подключиться по ldap через GSSAPI к контроллеру домена, ответственному за филиальскую зону NSK.EXAMPLE.ORG, где он будет проверять наличие пользователя в определенной группе.
Искал решение пару дней. Спрашивал у филиальского контроллера какие схемы аутентификации он поддерживает:
# ldapsearch -H ldap://dc1.nsk.example.ru -x -b "" -s base -LLL supportedSASLMechanisms
dn:
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: GSS-SPNEGO
supportedSASLMechanisms: EXTERNAL
supportedSASLMechanisms: DIGEST-MD5
Да, предлагает GSSAPI, тут все нормально. Еще можно посмотреть, а вообще у меня на прокси установлен GSSAPI SASL?
# pluginviewer | grep -i gssapi
  SCRAM-SHA-1 GSSAPI GSS-SPNEGO DIGEST-MD5 EXTERNAL OTP CRAM-MD5 NTLM LOGIN PLAIN ANONYMOUS
  SCRAM-SHA-1 GSSAPI GSS-SPNEGO DIGEST-MD5 OTP CRAM-MD5 NTLM LOGIN PLAIN ANONYMOUS
Plugin "gssapiv2" [loaded],     API version: 4
        SASL mechanism: GSSAPI, best SSF: 56, supports setpass: no
Plugin "gssapiv2" [loaded],     API version: 4
  SCRAM-SHA-1 GSSAPI GSS-SPNEGO DIGEST-MD5 EXTERNAL OTP CRAM-MD5 NTLM LOGIN PLAIN ANONYMOUS
  SCRAM-SHA-1 GSSAPI GSS-SPNEGO DIGEST-MD5 EXTERNAL OTP CRAM-MD5 NTLM LOGIN PLAIN ANONYMOUS
Plugin "gssapiv2" [loaded],     API version: 4
        SASL mechanism: GSSAPI, best SSF: 56
Plugin "gssapiv2" [loaded],     API version: 4
И тут все ок. Решил, что раз в тестовой зоне все работает, значит чем-то она отличается от промышленной. Не помню почему, но первым делом я взял в зубы tcpdump и стал смотреть, что происходит в сети между всеми контроллерами в тестовой и промышленной зонах. Тут я и нашел проблему. Все оказалось довольно просто: единственное отличие было в том, что тестовая прокся могла отрезолвить филиальский контроллер домена по IP, а вот промышленная - нет. Т.е. в промышленной зоне у меня не было филиальских контроллеров домена в обратной зоне!

Небольшое отступление: тут нужно понимать как это все работает (именно авторизация пользователя на прокси!). У меня не было четкого осознания, поэтому я довольно долго бился. Чтобы прокси получила доступ к инфе о свойствах пользователя, прокси надо спросить по LDAP у контроллера домена филиала этого пользователя о нем. Данный хелпер устроен так, что он аутентифицируется на контроллере тоже через kerberos. Т.е. для начала он должен получить тикет на доступ к службе ldap/dc1.nsk.example.org. Потом уже с помощью него аутентифицируется на dc1.nsk.example.org и запрашивает по ldap что хочет. Так что когда прокси спрашивал запись NSK.EXAMPLE.ORG типа A, ему сообщали IP адреса филиальских контроллеров. Затем он пытался получить имена филиальских контроллеров через эти IP адреса, чтобы знать, какой тикет ему получать. Вот на этом шаге все ломалось.

Вывод: все контроллеры доменов должны быть в обратной DNS зоне!

3. Всякий разный софт.

Огромное количество всякого софта (не браузеры), который хочет в интернет и при этом, что неудивительно, не умеет kerberos, или вообще никак не умеет аутентифицироваться на прокси.
Вообще это больше административный вопрос: каким ПО можно пользоваться в компании. Если все лояльно и пользователи могут ставить и пользоваться любым софтом, и при этом рассчитывать на то, что оно все будет работать, а если и не работает, то звонить ИТшникам и требовать починить, то вы огребете немеряно проблем. Поэтому всю эту штуку не стоит включать вообще для всех пользователей. Стоит включать только для части.
Для отладки нужно много смотреть в логи. Вот полезная ссылка с расшифровкой всех кодов, которые могут появиться в логах http://wiki.squid-cache.org/SquidFaq/SquidLogs

Дальше я немного окунулся в тот ад, который бы ждал меня, если аутентификация включена вообще для всех и список разрешенного софта в компании не определен, т.е. работать должно всё.
Тут есть несколько вариантов решения проблем с таким софтом:
a) пускать софт через другую прокси, где это можно. Например, поднять отдельный socks5 прокси;
b) выпускать в инет по user-agent до правила аутентификации. Смотреть acl типа browser.
c) выпускать в инет по IP до правила аутентификации. Тема озвучена в предыдущем посте.
d) выпускать сразу по порту до правила аутентификации? надо проверить.
e) выпускать по домену, на который обращается софт, до правила аутентификации.

В этот далеко неполный список проблемного софта попадают:

- прорва банк-клиентов совершенно разного типа. Тут все сложно. Нужен индивидуальный подход. Можно выпускать компы с банк-клиентами по IP;
- специфические софтины, например, конфигуратор телефонных станций Avaya. Не придумал что делать;
- Всякие задания от ERP системы, которым тоже зачем-то надо в интернет. Можно по IP;
- Google Drive не говорит User-Agent, из настроек прокси есть только "Автоматически определять" и "Прямое подключение". Никакой вообще аутентификации не умеет. (старый топик на тему + описание). Выпускать напрямую без прокси.
- Mail.ru Cloud и User-Agent сообщает, и настройки прокси имеет, где можно указать тип none/https/socks4/socks5 и базовую аутентификацию. Можно и через user-agent и через socks выпускать.
- MS SkyDrive (OneDrive) вообще заработал сам по себе, хотя user-agent не говорит и настроек прокси у него нет.
- Ammyy Admin не говорит User-Agent, имеет очень скудные настройки HTTP-прокси (socks нет). Выпускать напрямую.
- Skype заработал сам собой (выставлено "автом. обнаружение прокси"). Говорит много всяких User-Agent, имеет настройки прокси.
- Firefox заработал сам собой (выставлено "использовать системные настройки прокси"), есть куча настроек.
- всякие браузерные Java-аплеты для тех или иных целей, которые запускаются из браузера. Как правило, говорят нормальный User-agent. По нему можно выпускать в инет с прокси.
- iTunes говорит нормальный User-Agent! Но совершенно не имеет никаких настроек прокси, и тупо берет их из IE. Без вариантов. Выпускать по User-Agent.
- 1c приложения, которые хотят свежие курсы валют и т.д. Как правило, говорят нормальный User-agent. Выпускать по User-Agent.
- Valve Steam говорит user-agent. Настройки прокси тянет из системы. Но вот когда синхронизируется со своим облаком - не говорит User-Agent. Не знаю что делать.
- Старая Opera (версии <= 12). Да, есть еще люди, которые ей пользуются и в ус не дуют. Говорит User-Agent, но не всегда, из-за чего падает, если выпускать по user-agent . Имеет настройки прокси, но скудные. Пускать через socks. Но по-хорошему ее (<=12) надо запретить на административном уровне.
- DropBox не говорит User-Agent, но имеет настройки прокси, где можно указать тип none/https/socks4/socks5 и базовую аутентификацию. Выпускать через socks5.
- QIP (и прочие "аськи") не говорит нормального User-Agent, имеет настройки прокси, где можно указать тип none/https/socks4/socks5 и базовую аутентификацию. Выпускать через socks5.
- Mail.ru Agent, смотри предыдущее.
- Яндекс.Диск не говорит User-Agent, зато имеет настройки прокси, где можно указать тип none/https/socks4/socks5 и базовую аутентификацию. Выпускать через socks5.


Пока мой предполагаемый и не полностью проверенный список User-Agent'ов выглядит так:
+ проверял работоспособноть;
- не проверял;

# User-agent ACLs
# These software can't do kerberos
# + Apple iTunes
acl no_auth_ua browser ^iTunes/[0-9].*AppleWebKit/[0-9]
# - Various Java applets
acl no_auth_ua browser Java/[0-9]
# - Avaya telephony station configurator (Shalagin, Putalov, etc.). It has to be checked
acl no_auth_ua browser Avaya Solution Designer
# - 1C software
acl no_auth_ua browser 1C:Enterprise
# - Apple iCloud
acl no_auth_ua browser ^iCloud.*CFNetwork/[0-9]
acl no_auth_ua browser ^ApplePhoto.*CFNetwork/[0-9]
acl no_auth_ua browser ^Microsoft-CryptoAPI/[0-9]
# + Cloud Mail.ru
acl no_auth_ua browser ^CloudDesktopWindows.*[0-9]
# +/- Valve Steam
acl no_auth_ua browser Valve.*Steam.*Client.*[0-9]


Чуть ниже результат небольшого исследования при использовании какого софта какие User-Agent появляются в логах:

# Don't know what is it
Microsoft Office/14.0 (Windows NT 6.1; Microsoft Outlook 14.0.7106; Pro)
OutlookSocialConnector/1.0
Microsoft SettingsSync (6.3.9600.16500) Windows NT 6.3 (0603) Desktop IsNotAoAc
Microsoft-WNS/6.3
VCSoapClient
MSDW
Windows-Update-Agent
Microsoft BITS/7.5
Chrome WIN 33.0.1750.149 (255236) channel(stable)
# Related to Java applets
Mozilla/4.0 (Windows 7 6.1) Java/1.7.0_51
Java/1.7.0_51
# Mail.ru Cloud
CloudDesktopWindows 14.02.1200 beta (6.1)
# Skype
Microsoft-CryptoAPI/6.1
Skype▒ 6.14
WinINet HttpStack/11
# iTunes
Microsoft-CryptoAPI/6.1
GCSL GCSP 2.0
iTunes/11.1.5 (Windows; Microsoft Windows 7 x64 Business Edition Service Pack 1 (Build 7601)) AppleWebKit/537.60.15
# iCloud
Microsoft-CryptoAPI/6.3
ApplePhotoStreams.exe (unknown version) CFNetwork/520.3.4
ApplePhotoStreamsDownloader.exe (unknown version) CFNetwork/520.3.4
iCloud.exe (unknown version) CFNetwork/520.3.4
# uTorrent
uTorrent/3320(30486)
BTWebClient/3320(30486)
# Valve Steam
Valve/Steam HTTP Client 1.0
Breakpad/1.0 (Windows)
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; Valve Steam Client/1386799583; ) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
# Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1003.1 Safari/535.19 Awesomium/1.7.1
# Steam Cloud uses no UA, but do "CONNECT steamcloudams.blob.core.windows.net:443"

4. Итог

Я подумал, что каждый раз, когда что-то у пользователей не работает, ковыряться и разбираться почему и как сделать счастье, это трудозатратно и долго.  И в общем-то на уровне всей сети нам не нужно запрещать доступ в инет. Запрещать нужно только для некоторых пользователей, которые работают через наши терминальные серверы. Поэтому мы включили аутентификацию только для определенных IP.
Поскольку squid проверяет списки доступа сверху вниз и слева направо, то в строчку с вызовом аутентификации http_access нужно добавить acl с нужными IP, да только так, чтобы он стоял там раньше всех. Вот так оно вошло в конфиг:
+acl AuthIP src 192.168.2.22 192.168.2.23  
-http_access deny NoInetAD all
+http_access deny AuthIP NoInetAD all
http_access allow all
Т.е. сначала будет сравниваться IP адрес (AuthIP), а уже при совпадении вызываться аутентификация (NoInetAD).
Сейчас живем так, в ус не дуем.

З.Ы. некоторое развитие темы проксирования