Jabber + GSSAPI + LDAP
Monday, March 15, 2010 1:52:00 PM
Openfire
Ejabberd
Jabberd
Оговорюсь сразу, пока удалось настроить только связку Ejabberd + Pidgin, о ней и пойдет речь...
Первое что нужно сделать скачать ejabberd и патч для него с официального сайта, там есть краткое руководство по установке, но с первого взгляда все равно не все учтено...
I. Повторять все не буду, скачиваем, патчим, ставим.
Я предлагаю уже скачать готовый пакеты, которые я собрал и просто поставить.
Сборка для Debian Lenny x86.
Ejabberd + GSSAPI for ejabberd 2.1.0 final + mod_shared_roster_ldap
ejabberd_2.1.0-3_i386.deb
esasl_0.1-1_i386.deb
Так же рекомендую проверить чтобы стояли библиотеки
libkrb5-25-heimdal libkrb5-dev libkrb53 libpam-krb5
II.После установки необходимо поправить конфиг /etc/ejabberd/ejabberd.cfg
Это реально работающий конфиг, где убрано все лишнее, важные моменты прокомментированы
override_global.
override_local.
override_acls.
%% ACL администратора сервера
{acl, admin, {user, "admin", "domain.org"}}.
%% Имя сервера
{hosts, ["domain.org"]}.
%% Лог уровень debug
{loglevel, 5}.
{route_subdomains, s2s}.
%% Настройки портов
{listen,
[
{5222, ejabberd_c2s, [
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536}
]},
{5223, ejabberd_c2s, [
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536},
starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}
]},
{5269, ejabberd_s2s_in, [
{shaper, s2s_shaper},
{max_stanza_size, 131072}
]},
%%Авторизоваться в web у меня так и не получилось.
{5280, ejabberd_http, [
http_poll,
web_admin
]}
]}.
%% Настройки SSL
{s2s_use_starttls, true}.
{s2s_certfile, "/etc/ejabberd/ejabberd.pem"}.
%% ВАЖНО! Realm вашего kerberos
{sasl_realm, "DOMAIN.ORG"}.
{sasl_fqdn, "jabberd-host.domain.org"}.
%% Настройки авторизации в ldap (в данном примере анонимная)
{host_config, "domain.org", [
{auth_method, ldap},
{ldap_servers, ["ldap.domain.org"]},
{ldap_port, 389},
{ldap_base, "ou=People,dc=domain,dc=org"}
]}.
{shaper, normal, {maxrate, 1000}}.
{shaper, fast, {maxrate, 50000}}.
%% АCL для входа через веб-интерфейс
{acl, admins, {user, "admin@domain.org", "domain.org"}}.
{host_config, "domain.org", [{acl, admins, {user, "admin@domain.org", "domain.org"}}]}.
{access, configure, [{allow, admins}]}.
{acl, local, {user_regexp, ""}}.
{access, max_user_sessions, [{10, all}]}.
{access, local, [{allow, local}]}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
{access, s2s_shaper, [{fast, all}]}.
{access, announce, [{allow, admin}]}.
{access, configure, [{allow, admin}]}.
{access, muc_admin, [{allow, admin}]}.
{access, muc, [{allow, all}]}.
{access, register, [{deny, all}]}.
{access, pubsub_createnode, [{allow, all}]}.
{language, "en"}.
{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % requires mod_adhoc
{mod_caps, []},
{mod_configure,[]}, % requires mod_adhoc
{mod_ctlextra, []},
{mod_disco, []},
%%{mod_echo, [{host, "echo.localhost"}]},
{mod_irc, []},
{mod_last, []},
{mod_muc, [
%%{host, "conference.@HOST@"},
{access, muc},
{access_create, muc},
{access_persistent, muc},
{access_admin, muc_admin},
{max_users, 500}
]},
%%{mod_muc_log,[]},
{mod_offline, []},
{mod_privacy, []},
{mod_private, []},
{mod_proxy65, [
{access, local},
{shaper, c2s_shaper}
]},
{mod_pubsub, [ % requires mod_caps
{access_createnode, pubsub_createnode},
{plugins, ["default", "pep"]}
]},
{mod_register, [
{access, register}
]},
{mod_roster, []},
%%{mod_service_log,[]},
%%{mod_shared_roster,[]},
{mod_stats, []},
{mod_time, []},
%%Брать информацию о пользователях из ldap
{mod_vcard_ldap, [
{ldap_rootdn, ""},
{ldap_password, ""},
{ldap_servers, ["ldap.domain.org", "ldaps.domain.org"]}, % List of LDAP servers
{ldap_port, 389},
{ldap_base, "ou=People,dc=domain,dc=org"}, % Search base of LDAP directory
{ldap_uidattr, "uid"},
{ldap_uidattr_format, "%u"},
{ldap_filter, ""},
{ldap_vcard_map, [
{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
{"FN", "%s", ["cn"]},
{"FAMILY", "%s", ["sn"]},
{"GIVEN", "%s", ["givenName"]},
{"MIDDLE", "%s", ["initials"]},
{"ORGNAME", "%s", ["o"]},
{"ORGUNIT", "%s", ["ou"]},
{"CTRY", "%s", ["c"]},
{"LOCALITY", "%s", ["l"]},
{"STREET", "%s", ["street"]},
{"REGION", "%s", ["st"]},
{"PCODE", "%s", ["postalCode"]},
{"TITLE", "%s", ["title"]},
{"URL", "%s", ["labeleduri"]},
{"DESC", "%s", ["description"]},
{"TEL", "%s", ["telephoneNumber"]},
{"EMAIL", "%s", ["mail"]},
{"BDAY", "%s", ["birthDate"]},
{"PHOTO", "%s", ["jpegPhoto"]}
]},
%% Поиск в ldap
{ldap_search_fields, [
{"User", "%u"},
{"Full Name", "cn"},
{"Given Name", "givenName"},
{"Middle Name", "initials"},
{"Family Name", "sn"},
{"Nickname", "%u"},
{"Birthday", "birthDate"},
{"Country", "c"},
{"City", "l"},
{"Email", "mail"},
{"Organization Name", "o"},
{"Organization Unit", "ou"}
]}
]},
{mod_version, []}
]}.
Для того чтобы при логине в jabber у нас отображалась группа пользователей взятая из Ldap, необходимо доставить модуль mod_shared_roaster_ldap
Добавить настройки в конфиг в раздел modules.
%%mod_shared_roster
{mod_shared_roster_ldap,[
{ldap_base, "dc=domain,dc=org"},
{ldap_uidattr, "uid"},
{ldap_groupattr,"o"},
{ldap_groupdesc,""},
{ldap_rfilter,"(o=Jabber Group)"},
{ldap_filter,"(ObjectClass=*)"},
{ldap_memberattr,"uid"},
{ldap_userdesc,"gecos"}
]},
Возможно в вашей ldap схеме придется заменить "o" на "cn".
Сделаем еще сертификат для ssl
openssl req -new -x509 -newkey rsa:1024 -days 60 -keyout privkey.pem -out key.pem openssl rsa -in privkey.pem -out privkey.pem cat privkey.pem >> /etc/ejabberd/ejabberd.pem
III. Теперь нужно добавить строчку чтобы демон знал где брать keytab от xmpp
/etc/default/ejabberd
export KRB5_KTNAME="/etc/ejabberd/xmpp.keytab"
IV. Теперь как делать keytab.
Заходим в kadmin как админ, создаем принципла для нашего сервера и его кейтаб.
addprinc -randkey xmpp/jabberd-host.domain.org@DOMAIN.ORG ktadd -k /etc/ejabberd/xmpp.keytab -e des3-hmac-sha1:normal xmpp/jabberd-host.domain.org@DOMAIN.ORG chown ejabberd:ejabberd /etc/ejabberd/xmpp.keytab chmod 600 /etc/ejabberd/xmpp.keytab
Должны получить файл по указанному нами выше пути /etc/ejabberd/xmpp.keytab, файл этот должен находится конечно же на сервере где запущен jabberd.
Одно замечание, почему нужно использовать это шифрование, потому что с des-cbc-crc:normal у меня не заработало.
Так же очень важно проверить права на keytab, пользователь от которого запускается jabber должен иметь право на чтение keytab, ибо по умолчание читать может его только рут.
V.Теперь нужно сделать записи в DNS. Не уверен что нужны именно все записи, но по разным источникам часть из них нужна точно.
zone: domain.org
; records for jabber _kerberos._udp IN SRV 0 0 88 kdc _kerberos._udp IN SRV 1 0 88 kdcs _kerberos IN TXT "DOMAIN.ORG" _jabber._tcp IN SRV 5 0 5269 jabberd-host _xmpp-server._tcp IN SRV 5 0 5269 jabberd-host _xmpp-client._tcp IN SRV 5 0 5222 jabberd-host _xmpp-client._tcp IN SRV 5 0 5223 jabberd-host
- kdc и kdcs это наши primary и secondary kerberos domain server.
- "DOMAIN.ORG" наш REALM который должен совпадать с realm в конфиге ejabberd.cfg
- jabberd-host это имя нашего сервера, на котором запущен Ejabberd, естественно у каждого оно будет свое, и A и PTR запись jabberd-host.domain.org соотвественно тоже должны быть.
VI. Если все готово, то теперь необходимо запустить сервер и посмотреть что все заработало
/etc/init.d/ejabberd start netstat -nlp --tcp |grep 52
Вывод
tcp 0 0 0.0.0.0:5280 0.0.0.0:* LISTEN 11608/beam.smp tcp 0 0 0.0.0.0:56352 0.0.0.0:* LISTEN 11608/beam.smp tcp 0 0 0.0.0.0:5222 0.0.0.0:* LISTEN 11608/beam.smp tcp 0 0 0.0.0.0:5223 0.0.0.0:* LISTEN 11608/beam.smp tcp 0 0 0.0.0.0:5269 0.0.0.0:* LISTEN 11608/beam.smp
Смотрим так же в /var/log/ejabberd/esasl.log
ищем там =PROGRESS REPORT==== если видим ====CRASH REPORT==== то гдето проблемы.
Смотрим в /var/log/ejabberd/ejabberd.log и ищем там
=INFO REPORT==== 2009-06-05 19:27:14 ===
D(<0.268.0>:eldap:745) : {'LDAPMessage',1,
{bindResponse,
{'BindResponse',success,[],[],asn1_NOVALUE,
asn1_NOVALUE}},
asn1_NOVALUE}
что озночает что с ldap у нас все срослось...
VII. Пробуем Pidgin с клиентской машины где настроен kerberos и установлен pidgin
Проверяем
dpkg -l |grep pidgin ii pidgin 2.4.3-4lenny2 graphical multi-protocol instant messaging client for X ii pidgin-data 2.4.3-4lenny2 multi-protocol instant messaging client - data files
Запускаем...
pidgin -d
Настройки соединения в клиенте.
User admin (тот на которого у вас есть тикет)
Domain domain.org
Port 5222 (Если включить SSL то порт 5223)
Server jabberd-host.domain.org
Внимательно смотрим в debug коносоль
Ищем строчки
Первое: что сервер нам отвечает и говорит какие способы авторизации он поддерживает, то что наш клиент отправляет ему запрос на авторизацию по GSSAPI.
(14:41:07) sasl: Mechs found: GSSAPI PLAIN
(14:41:07) jabber: Sending: <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='GSSAPI'>YIICRwYJKoZIhvcSAQICAQBuggI2MIICMqADAgEFoQMCAQ6iBwMFACAAAACjggEVYYIBETCCAQ2gAwIBBaEOGwxPS1RFVExBQlMuUlWiJDAioAMCAQGhGzAZGwR4bXBwGxFkaW9yLm9rdGV0bGFicy5ydaOBzzCBzKADAgEQoQMCAQeigb8EgbyuqR9Hwk0IPrzohvBMYEOQxiEnvKfgYwXg/+QewkrXGCPIZisdfsdfXb2s03TNkC1x6hkErerty3zChLvYIhFhbnqjhjh8wCNAbsVoqA7sw/NyIqOV/tB19H34NJBj767IfKWtyteyercvnukk78oinoJbwfJx8rrf4YNKv7+n3LqE5ezM+eygA4ziWDv6JMPCBsdffgsfsgjkuy5ou963GZesYrdwFkDsYwSoO73xkn9fgJbWjjt92ZEIYr7Jw4Ekr9tjI3SU4G7PK2W9K+IF8/6n2364WC3tgyh9ycpBPHCpamdf534Enhcbnu54r60fVUbct8IPzGmkCOSpQFz5A3ix0Gk=</auth>
Второе: мы получаем ответ от сервера, что мы авторизированы
(14:41:07) jabber: Recv (268): <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>YIGWBgkqhk78siGasd9xghgIBaAsdfAgICAG+BhjCBg6ADAgEFoQMCAQ+idzLJKDFnmsdhjgsd73kmKJSHDNLKC094jmtrnbmzBDStnyJrDpwa6csho+ZpE6h+RrXtP7UIL9u5J1KJLSWXNBV91423n2CJSdfo45tJHGSDQJ5</challenge>
(14:41:07) jabber: Sending: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl%27/>
(14:41:07) jabber: Recv (152): <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>YD8GCSJLKJLOM487NBA3EgECAgIBBAD/////M0SdnAsOdnQdba5Lw+CBpzASTRP/iL+AoiAGfJSNANCVBZOPXAf///wQEBSJWA=</challenge>
(14:41:07) jabber: Sending: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>YD8DFHSJSAOOWBAD/////4dSKJncUJUSJALlSieDFh3947263D4qV1VhvKc56AILIASJS=</response>
(14:41:07) jabber: Recv (51): <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl%27/>
Неправильно если видим строчку
jabber: Recv (ssl)(77): <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
Так же необходимо проверить у клиента что он получает тикет от сервера для xmpp
Вот так должен выглядеть вывод если все правильно.
#klist Ticket cache: FILE:/tmp/krb5cc_1065_UJnRu3 Default principal: user@DOMAIN.ORG Valid starting Expires Service principal 06/09/09 14:35:39 06/10/09 06:35:39 krbtgt/DOMAIN.ORG@DOMAIN.ORG 06/09/09 14:41:07 06/10/09 06:35:39 xmpp/jabberd-host.domain.org@DOMAIN.ORG
Пока все.
Updated 2010/03/15
Ссылки по теме:
Ejabberd2 Guide
GSSAPI Patch
mod_shared_roster_ldap (original)
mod_shared_roster_ldap (правленый)








Виталийh2005 # Friday, February 19, 2010 9:55:16 AM
а если не сростается с лдап
=INFO REPORT==== 2010-02-19 11:44:33 === D(<0.679.0>:eldap:695) : {bindResponse, {'BindResponse',invalidCredentials,[],[], asn1_NOVALUE,asn1_NOVALUE}}таким вот образом, куда дальше идти?
Zl0 # Saturday, February 27, 2010 10:35:10 AM
Unregistered user # Saturday, May 8, 2010 1:04:37 AM
Zl0 # Saturday, May 8, 2010 7:15:48 AM
Особых проблем с ним не возникало, хотя да, я не смог нормально сделать там shared roster из ldap групп, видимо схема у нас в ldap не совсем обычная.