24 июн. 2015 г.

Samba 4 AD rfc2307 + login shell

Есть проблема: при вводе в samba4-домен linux-машины winbind подгружает список пользователей с шеллом /bin/false. Это вызывает ожидаемые проблемы при логине в систему.
administrator:*:2000:2000:Administrator:/home/EXAMPLE/administrator:/bin/false
И вроде бы такое должно случаться только в случае контроллеров домена и только с winbind. Однако у меня случилось и на обычном "членском" сервере. Проблема в том, что winbind не считывает атрибут (который должен по rfc2307,  см. соответствующую опцию в smb.conf) LoginShell из свойств пользователя в Active Directory. Текущее обходное решение - добавить в smb.conf глобальный параметр:
[global]
   template shell = /bin/bash

9 июн. 2015 г.

Squid + Samba4 AD Kerberos Authorization

В продолжение предыдущей заметки пара слов об авторизации доменных пользователей в Squid посредством того же Kerberos. Вообще все должно быть легко, ибо все уже украдено до нас есть готовый хелпер в комплекте /usr/lib/squid3/ext_kerberos_ldap_group_acl (по крайней мере, в Debian), который умеет ходить в AD, авторизовываться текущим keytab-ом, получать необходимые тикеты и понимать, находится ли поданная ему на вход учетная запись пользователя в заданной группе. Для тестовых целей, как и ранее, запускаем прямо из консоли:
/usr/lib/squid3/ext_kerberos_ldap_group_acl -a -g FastInet@EXAMPLE.COM
Для дебага можно добавить опции -i или -d. Опция -h покажет встроенный хелп. 
Нормальная работа хелпера выглядит так:
root@gw0:~# /usr/lib/squid3/ext_kerberos_ldap_group_acl -a -g FastInet@EXAMPLE.COM
inettest01@example.com
OK
inettest02@example.com
ERR 
Соответственно, пользователь inettest01 является членом группы FastInet в домене EXAMPLE.COM, а пользователь inettest02 - нет.
Если ERR имеем всегда, а -d показывает ошибки вида:
kerberos_ldap_group: DEBUG: Bind to ldap server with SASL/GSSAPI
kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Unknown authentication method
то, возможно, не хватает модулей gssapi к библиотеке libsasl2, через которую реализуется подключение хелпера к домену по LDAP: libsasl2-modules-gssapi-mit. После установки этого пакета у меня такая ошибка более не появлялась:
kerberos_ldap_group: DEBUG: Bind to ldap server with SASL/GSSAPI
kerberos_ldap_group: DEBUG: Successfully initialised connection to ldap server dc0.example.com:389
В самом Squid конструкция описывается следующим образом:
external_acl_type fastgroup_krb children=10 cache=10 grace=15 %LOGIN /usr/lib/squid3/ext_kerberos_ldap_group_acl -a -g FastInet@EXAMPLE.COM
acl fastinet external fastgroup_krb
http_access allow fastinet
Запись external_acl_type должна быть записана в одну строку. Переменная %LOGIN передает учетную запись пользователя от negotiate хелпера (см. предыдущую заметку). Конечно, групп может быть несколько, и количество определений external_acl_type не ограничивается.
Вроде бы все просто, однако на работе хелпера я сидел не один день. Судя по дебагу вида:
support_ldap.cc(856): pid=1593 :2015/06/09 15:50:55| kerberos_ldap_group: DEBUG: Bind to ldap server with SASL/GSSAPI
support_sasl.cc(268): pid=1593 :2015/06/09 15:50:55| kerberos_ldap_group: ERROR: ldap_sasl_interactive_bind_s error: Local error
support_ldap.cc(860): pid=1593 :2015/06/09 15:50:55| kerberos_ldap_group: ERROR: Error while binding to ldap server with SASL/GSSAPI: Local error
хелпер не мог соединиться с контроллером домена по ldap и запросить требуемые данные. Причем keytab-файл заведомо использовался, имена разрешались и вообще до момента означенной ошибки все логи были хорошими.
В разборках сильно помогла заметка пользователя Timp, который указал отсутствующие на PTR-записи контроллеров домена в своей очень похожей ситуации. Беда в том, что nslookup на gw0 корректно разрешался в обе стороны для dc0.
По прошествии времени я снова вернулся к этой заметке и решил последовать примеру товарища - вооружиться tcpdump-ом. И каково же было моё удивление, когда я обнаружил ответа dc0 с содержимым NXDOMAIN! И да, появлялись они в моменты работы хелпера. И дважды да, предваряли эти сообщения запросы PTR для адреса контроллера домена!!!
Точки над i расставил dig (вывод я порезал):
root@gw0:~# dig -x 192.168.0.241
;; QUESTION SECTION:
;241.0.168.192.in-addr.arpa.   IN      PTR
Секции ANSWER нет! То есть, действительно, обратной записи для контроллера домена в DNS нет. Идем в соответствующую оснастку (или samba-tool в консоли dc0, что ближе) и добавляем недостающий пойнтер. Смотрим:
root@gw0:~# dig -x 192.168.0.241
;; QUESTION SECTION:
;241.0.168.192.in-addr.arpa.   IN      PTR
;; ANSWER SECTION:
241.0.168.192.in-addr.arpa. 3600 IN    PTR     dc0.example.com.
После этих действий хелпер начал работать.

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. Вот тут в конце статьи довольно внятное описание процесса.


3 июн. 2015 г.

Postgresql issue during Debian Wheezy to Jessie upgrade

Проблема, собственно, в чем: при обычном dist-upgrade сабжевая СУБД нормально обновилась с 9.1 до 9.4 (минорные циферки опустим, неважно). Однако сам процесс обновления оказался забавным: инсталлятор снес 9.1 (оставив конфиги в /etc/ и базы в /var/lib), установил 9.4, создал дефолтный кластер, запустил всю эту балалайку - и доволен. 
Таким образом, в итоге имеем корректно функционирующий постгрес, но с умолчальным конфигом и без баз =).
Вообще, у postgresl имеется встроенный механизм обновления - pg_upgrade, который сам проверяет совместимость баз в старом и новом релизах и перебрасывает их из папки в папку (полагаю, что и вносит при этом необходимые изменения). Но дебиановские мейнтейнеры как-то этот момент похоже упустили. 
А делать надо следующее (актуализированные команды, чтобы не переписывать, взяты отсюда, а документация по этому вопросу - тут):
sudo -H -u postgres /usr/lib/postgresql/9.4/bin/pg_upgrade \
-b /usr/lib/postgresql/9.1/bin \
-B /usr/lib/postgresql/9.4/bin \
-d /var/lib/postgresql/9.1/main \
-D /var/lib/postgresql/9.4/main \
-o ' -c config_file=/etc/postgresql/9.1/main/postgresql.conf' \
-O ' -c config_file=/etc/postgresql/9.4/main/postgresql.conf'
Конечно, писать все можно и в одну строчку, забыв про "\". Строчные буквы относятся к файлам старой версии, прописные - к новой. 
В моем случае беда была в том, что при обновлении все бинарные файлы старого релиза оказались удалены, а в репозиториях jessie версии 9.1 уже нет. Поэтому пришлось искать старый .deb (благо кэш apt-а никто не чистил), и подсовывать файлики оттуда (установить deb-пакеты - плохая идея, ибо он начнет делать downgrade текущей инсталляции).
При первом запуске рекомендую добавить еще опцию --check,  чтобы без внесения каких-либо изменений провести проверку всего и вся. В случае ошибок инфомация записывается в лог-файл, создаваемый в текущей рабочей директории.