Ejabberd源码解析前奏--配置

时间:2021-06-02 21:48:06
一、基本配置
    配置文件将在你第一次启动ejabberd时加载,从该文件中获得的内容将被解析并存储到内部的ejabberd数据库中,以后的配置将从数据库加载,并且任何配置文件里的命令都会被添加到数据库里。

需要注意的是:ejabberd从不编辑配置文件,因此,使用Web管理修改的配置被存储在数据库中, 而不是反射到配置文件。如果你想那些修改在ejabberd重启后还有效,你可以同时也修改配置文件或删除它的所有内容。

配置文件包含一系列Erlang条款。以‘%’标志开始的行被忽略。每个条款是一个元组,其第一个元素是一个选项的名称,任何更多的元素则是该选项的值。如果配置文件不包含类似‘hosts’选项,则旧的存储在数据库的主机名(s)将被启用。

通过在配置文件的开始部分增加下面几行,可以重写存储在数据库中的值:

override_global.

override_local.

override_acls.

有了这些行,旧的全局选项(在一个集群内所有ejabberd节点之间共享的选项), 本地选项(个别ejabberd节点特有的选项) 以及 ACLs(Access Control Lists)将在新配置添加之前被移除。

1、主机名

选项hosts定义了包含一个或多个域名的列表,ejabberd将为这些域名提供服务。

语法是:

        {hosts, [HostName, ...]}.

示例:

(1)服务一个域:

{hosts, ["example.org"]}.

(2)服务多个域:

{hosts, ["example.net", "example.com", "jabber.somesite.org"]}.

2、虚拟主机

每个虚拟主机的选项可以被独立定义,使用host_config选项。

语法是:

        {host_config, HostName, [Option, ...]}

示例:

(1)域example.net使用内部验证方法,而域example.com使用运行在域localhost的LDAP服务器来进行验证:

{host_config, "example.net", [{auth_method, internal}]}.

{host_config, "example.com", [{auth_method, ldap}, {ldap_servers, ["localhost"]}, {ldap_uids, [{"uid"}]}, {ldap_rootdn, "dc=localdomain"},{ldap_rootdn, "dc=example,dc=com"}, {ldap_password, ""}]}.

(2)域example.net使用ODBC来进行验证,而域example.com使用运行在域localhost和otherhost的LDAP服务器:

{host_config, "example.net", [{auth_method, odbc}, {odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}]}.

{host_config, "example.com", [{auth_method, ldap}, {ldap_servers, ["localhost", "otherhost"]}, {ldap_uids, [{"uid"}]}, {ldap_rootdn,"dc=localdomain"}, {ldap_rootdn, "dc=example,dc=com"}, {ldap_password, ""}]}.

为了给一个虚拟主机指定特定的ejabberd模块,你可能先为常规模块定义全局模块选项,之后增加指定的模块给特定的虚拟主机. 为此, 把定义host_config的每个选项改成通用语法:

    {OptionName, OptionValue}

使用这个语法:

    {{add, OptionName}, OptionValue}

在这个例子里,三个虚拟主机有一些相同的模块,但是特定的虚拟主机也有不同的模块:

%% 这个ejabberd服务器有三个虚拟主机:

{hosts, ["one.example.org", "two.example.org", "three.example.org"]}.

%% 这些是所有主机通用模块的配置

{modules, [ {mod_roster, []}, {mod_configure, []}, {mod_disco, []}, {mod_private, []}, {mod_time, []}, {mod_last, []}, {mod_version, []} ]}.

%% 增加一些模块给 vhost one:

{host_config, "one.example.org", [{{add, modules}, [ {mod_echo, [{host, "echo-service.one.example.org"}]} {mod_http_bind, []}, {mod_logxml, []} ] }]}.

%% 只增加一个模块给 vhost two:

{host_config, "two.example.org", [{{add, modules}, [ {mod_echo, [{host, "mirror.two.example.org"}]} ] } ]}.

3、监听端口号

选项listen定义ejabberd将监听哪些端口、地址和网络协议,以及什么服务将运行在它们上面。这个列表的每个元素都是一个元组包括以下的元素:

(A)端口号,还有可选的IP地址和/或一个传输协议。

(B)监听这个端口的模块。

(C)TCP socket和监听模块的选项。

这个选项的语法是:

        {listen, [Listener, ...]}.

定义一个listener有很多语法:

        {PortNumber, Module, [Option, ...]}

        {{PortNumber, IPaddress}, Module, [Option, ...]}

        {{PortNumber, TransportProtocol}, Module, [Option, ...]}

        {{PortNumber, IPaddress, TransportProtocol}, Module, [Option, ...]}

(1)端口号、IP地址和传输协议

端口号定义哪个端口监听链入的连接,它可能是一个Jabber/XMPP标准端口(5222)或任何其它合法的端口号。

IP地址可能被表达为一个字符串或一个十进制或十六进制的Erlang元组。socket将只监听那个网络接口。也可能指定一个通用地址, 这样ejabberd将监听所有地址。取决于IP地址的类型(将使用IPv4或IPv6)。当没有指定IP地址时,它将监听所有IPv4网络地址。

一些IP地址的示例值:

(A)"0.0.0.0":监听所有IPv4网络接口. 这是当没有指定IP地址时的缺省值。

(B)"::" :监听所有IPv6网络接口。

(C)"10.11.12.13":监听IPv4地址10.11.12.13。

(D)"::FFFF:127.0.0.1":是IPv6地址::FFFF:127.0.0.1/128。

(E){10, 11, 12, 13}:是IPv4地址10.11.12.13。

(F){0, 0, 0, 0, 0, 65535, 32512, 1}:是IPv6地址 ::FFFF:127.0.0.1/128。

(G){16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}:是IPv6地址 FDCA:8AB6:A243:75EF::1/128。

传输协议可能是tcp或udp,缺省是tcp。

(2)监听模块

可用的模块,它们的目的以及允许使用哪些选项:

    ejabberd_c2s

处理c2s连接.     选项: access, certfile, max_fsm_queue, max_stanza_size, shaper, starttls, starttls_required, tls, zlib

    ejabberd_s2s_in

处理链入的s2s连接.     选项: max_stanza_size

    ejabberd_service

和一个外部组件交互(定义于Jabber组件协议(XEP-0114).     选项: access, hosts, max_fsm_queue, shaper, service_check_from

    ejabberd_stun

处理STUN绑定请求,定义于 RFC 5389.     选项: certfile

    ejabberd_http

处理链入的HTTP连接.

选项: captcha, certfile, http_bind, http_poll, request_handlers, tls, web_admin

(3)选项

这是监听模块允许使用选项的详细描述:

    {access, AccessName}

这个选项定义访问的端口,缺省值是all。

    {backlog, Value}

这个backlog值定义等待中的连接的队列可以达到的最大长度,如果服务器想处理很多新链入的连接,这个值需要增加。因为如果队列里没有足够的空间(ejabberd不能立刻接受它们),这些新连接可能被抛弃,缺省值是5。

    {certfile, Path}

包含缺省的SSL证书的文件的完整路径,为一个给定的域定义一个证书文件,使用全局选项domain_certfile。

    {service_check_from, true|false}

这个选项只能被用于ejabberd_service,它被用于禁止控制一个从外部组件发送的包的from字段。这个选项要么是true要么是false。缺省值是true,它遵循XEP-0114

    {hosts, [Hostname, ...], [HostOption, ...]}

连接到ejabberd_service的外部Jabber组件可能服务一个或多个hostnames。所以你可以为这个组件定义选项HostOption;目前允许的选项是当组件尝试连接到ejabberd时必需提供的密码:{password, Secret}。注意你不能在不同的服务里定义同一个ejabberd_service组件:为每个服务增加一个ejabberd_service。

    captcha

简单的web页面,允许一个用户填一个CAPTCHA。

    http_bind

这个选项允许支持HTTP绑定(XEP-0124XEP-0206)。HTTP绑定允许通过HTTP请求,从那些不允许从5222端口链出socket的防火墙后面访问ejabberd.     记住你也必须安装和激活mod_http_bind模块。     如果HTTP绑定激活了, 它将可以使用http://server:port/http-bind/.注意对HTTP绑定的支持也需要XMPP客户端,也要注意HTTP绑定对一个基于web的XMPP客户端的主机也是很有意义的,例如JWChat(根据教程为ejabberd安装JWChat,以及一个内嵌的本地web服务器Apache)。

    http_poll

这个选项允许支持HTTP轮询(XEP-0025). HTTP轮询允许通过HTTP请求,从那些不允许从5222端口链出socket的防火墙后面访问ejabberd.

如果激活了HTTP轮询, 它可以用 http://server:port/http-poll/. 注意对HTTP轮询的支持也需要XMPP客户端. 也要注意HTTP轮询对一个基于web的XMPP客户端的主机是很有意义的,例如JWChat.     在没有链入的POST请求时一个客户端会话保持激活状态的最大时间段,可以用全局选项 http_poll_timeout 配置. 缺省值为5分钟. 这个选项可在ejabberd.cfg文件里定义, 时间的单位为秒:{http_poll_timeout, 300}.

    {max_fsm_queue, Size}

这个选项指定在一个FSM(有限状态机)队列里元素的最大数量。大概来说,这些队列的每个消息展示一个准备发送到的外发流的XML stanza。如果队列大小达到限制(例如:由于stanzas的接收者太慢),这个FSM和相应的连接(如果有)将被终止并且记录一个出错信息。这个选项的合理值依赖于你的硬件配置。然而, 把这个大小设为1000个元素以上没有什么意义。这个选项可被指定给ejabberd_service和 ejabberd_c2s listeners,或也可以全局地指定给ejabberd_s2s_out。如果这个选项没有指定给ejabberd_service或 ejabberd_c2s listeners, 则使用全局配置的值. 允许的值为整数和 ’undefined’. 缺省值为: ’undefined’.

    {max_stanza_size, Size}

这个选项指定一个XML stanzas的近似最大字节数。近似的,是因为它计算的精度是以一个被读数据块来的,例如{max_stanza_size, 65536},缺省值是无穷大,推荐值对于c2s连接是65536,对于s2s连接是131072。s2s最大节数必须总是比c2s的限制更高,谨慎修改此值,因为如果设置得太小可能导致意料之外的断开连接。

    {request_handlers, [ {Path, Module}, ...]}

指定一个或多个handlers来伺服HTTP请求。Path是一个字符串列表,所以以那个Path启动的URIs将被Module伺服,例如:如果你想mod_foo伺服以/a/b/开头的URIs,同时你也想mod_http_bind伺服URIs /http-bind/,则使用这个选项:{request_handlers, [{["a", "b"], mod_foo}, {["http-bind"], mod_http_bind}]}

    {service_check_from, true|false}

这个选项只能被ejabberd_service使用。XEP-0114要求域必须和组件的主机名匹配。如果选项设置为false,ejabberd将允许组件发送'from'属性中的任意域的stanzas。只有你完全确认自己需要的情况下才应该激活这个选项。为了兼容XEP-0114,缺省值是:true.

    {shaper, none|ShaperName}

这个选项为端口定义一个shaper,缺省值是 none.

    starttls

这个选项定义STARTTLS加密可以用于连接某端口。你应该也设置certfile选项。你可以使用全局选项domain_certfile为一个特定的域定义一个证书文件。

    starttls_required

这个选项指定在连接到某端口时STARTTLS加密是必需的。不允许不加密的连接,你应该也设置certfile选项,你可以使用全局选项 domain_certfile为一个特定的域定义一个证书文件。

    tls

这个选项指定某端口的通讯在连接之后将立刻使用SSL加密。这是一个早期的Jabber软件使用的传统加密方法,通常是在端口5223,用于客户端到服务器通讯。但是这个方法今天已经不推荐了使用。可取的加密方法是在端口5222使用STARTTLS,定义于RFC 3920: XMPP核心,这个方法在ejabberd里可以使用starttls选项来激活。如果这个选项被设置了,你应该同时设置certfile选项。选项tls也可用于 ejabberd_http以支持HTTPS。

    web_admin

这个选项为ejabberd管理者激活Web Admin,可通过http://server:port/admin/访问,登录和密码就是某个你在‘configure’access rule里授权了的已注册用户的用户名和密码。

zlib

这个选项指定在某端口的连接可使用Zlib流压缩(定义于XEP-0138)。

有一些额外的全局选项(listen之外的)可以在ejabberd配置文件指定:

{s2s_use_starttls, true|false}

这个选项定义是否为s2s连接使用 STARTTLS .

{s2s_certfile, Path}    

一个包含SSL证书的文件的全路径.

{domain_certfile, Domain, Path}

包含一个特定域的SSL证书的文件的全路径.

    {outgoing_s2s_options, Methods, Timeout}

指定用哪个地址尝试连接, 以什么顺序, 以及连接超时时间(以毫秒计). 缺省第一次尝试连接使用IPv4地址, 如果失败它将尝试使用IPv6, 超时时间为 10000 毫秒.

    {s2s_dns_options, [ {Property, Value}, ...]}

指定用于DNS解析的 properties. 允许的 Properties 有: 以秒计的缺省值为10的 timeout 和缺省值为2的重试次数.

    {s2s_default_policy, allow|deny}

对于链入和链出到其他XMPP服务器的s2s连接的缺省策略. 缺省值是 allow.

    {{s2s_host, Host}, allow|deny}

指定是否允许一个特定远程主机的链入和链出s2s连接. 这允许限制 ejabberd 只和少数信任的服务器建立s2s连接, 或禁止一些特定的服务器.

    {s2s_max_retry_delay, Seconds}

连接失败后重试连接的最大允许延迟时间. 以秒计算. 这个缺省值是 300 秒 (5分钟).

    {route_subdomains, local|s2s}

定义 ejabberd 是必须直接把节从本地路由到子域 subdomains(兼容 RFC 3920: XMPP核心), 还是使用S2S到外部服务器 (兼容 RFC 3920 bis).     示例

例如, 以下简单配置定义:

(1)有三个域. 缺省证书文件是 server.pem. 然而, 连接到域example.com的c2s和s2s使用文件example_com.pem.

(2)端口 5222 使用 STARTTLS 监听 c2s 连接, 同时允许简单连接用于旧的客户端.

(3)端口 5223 使用旧的 SSL 监听 c2s 连接 .

(4)端口 5269 使用 STARTTLS 监听 s2s 连接. 这个socket设为IPv6而不是IPv4.

(5)端口 3478 监听通过 UDP 发出的 STUN 请求 .

(6)端口 5280 监听 HTTP 请求, 并伺服 HTTP 轮询服务.

(7)端口 5281 监听 HTTP 请求, 并使用 HTTPS 伺服 Web Admin. 这个socket只监听来自IP地址127.0.0.1的连接.

{hosts,

["example.com", "example.org", "example.net"]}.

{listen,

[

{5222, ejabberd_c2s, [

{access, c2s},

{shaper, c2s_shaper},

starttls, {certfile, "/etc/ejabberd/server.pem"},

{max_stanza_size, 65536}

]},

{5223, ejabberd_c2s, [

{access, c2s},

{shaper, c2s_shaper},

tls, {certfile, "/etc/ejabberd/server.pem"},

{max_stanza_size, 65536}

]},

{{5269, "::"}, ejabberd_s2s_in, [

{shaper, s2s_shaper},

{max_stanza_size, 131072} ]},

{{3478, udp}, ejabberd_stun, []},

{5280, ejabberd_http, [

http_poll

]},

{{5281, "127.0.0.1"}, ejabberd_http, [

web_admin,

tls, {certfile, "/etc/ejabberd/server.pem"},

]}

]

}.

{s2s_use_starttls, true}.

{s2s_certfile, "/etc/ejabberd/server.pem"}.

{domain_certfile, "example.com", "/etc/ejabberd/example_com.pem"}.

在这个例子, 定义了以下配置:

(1)端口 5222 (所有IPv4地址)和端口5223 (SSL, IP 192.168.0.1 和 fdca:8ab6:a243:75ef::1)监听c2s连接 ,并禁止名为 ‘bad’的用户.

(2)端口 5269 (所有IPv4地址)为了允许安全通讯而使用STARTTLS监听s2s连接. 远程XMPP服务器的链入和链出连接被禁止, 只有两个服务器可以连接: "jabber.example.org" 和 "example.com".

(3)端口 5280 在所有的IPv4地址伺服 Web Admin 和 HTTP Polling 服务. 注意它也可能在不同端口伺服它们.

(4)除了管理员,所有用户的通讯流量限制为 1,000 Bytes/second

(5)AIM 网关 aim.example.org 被连接到localhost IP 地址(127.0.0.1 and ::1)的 5233 端口 , 连接密码为‘aimsecret’.

(6)ICQ 网关 JIT (icq.example.org and sms.example.org) 被以密码‘jitsecret’连接到端口 5234 .

(7)MSN 网关 msn.example.org 被以密码‘msnsecret’连接到端口 5235 .

(8)Yahoo! 网关 yahoo.example.org 被以密码‘yahoosecret’连接到端口 5236 .

(9)Gadu-Gadu 网关 gg.example.org 被以密码‘ggsecret’连接到端口 5237 .

(10)Jabber Mail 组件 jmc.example.org 被以密码‘jmsecret’连接到端口 5238 .

(11)服务自定义允许特别的选项用来逃避对从这个组件发送的包里检查from属性. 这个组件可以从服务器以任何用户的身份发送包, 或者甚至以任何服务器的身份.

{acl, blocked, {user, "bad"}}.

{access, c2s, [{deny, blocked},

{allow, all}]}.

{shaper, normal, {maxrate, 1000}}.

{access, c2s_shaper, [{none, admin},

{normal, all}]}.

{listen,

[{5222, ejabberd_c2s, [

{access, c2s},

{shaper, c2s_shaper}

]},

{{5223, {192, 168, 0, 1}}, ejabberd_c2s, [

{access, c2s},

ssl, {certfile, "/path/to/ssl.pem"}

]},

{{5223, {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}},

ejabberd_c2s, [

{access, c2s},

ssl, {certfile, "/path/to/ssl.pem"}

]},

{5269, ejabberd_s2s_in, []},

{{5280, {0, 0, 0, 0}}, ejabberd_http, [

http_poll,

web_admin

]},

{{5233, {127, 0, 0, 1}}, ejabberd_service, [

{hosts, ["aim.example.org"],

[{password, "aimsecret"}]}

]},

{{5233, "::1"}, ejabberd_service, [

{hosts, ["aim.example.org"],

[{password, "aimsecret"}]}

]},

{5234, ejabberd_service, [

{hosts, ["icq.example.org", "sms.example.org"],

[{password, "jitsecret"}]}]},

{5235, ejabberd_service, [{hosts, ["msn.example.org"],

[{password, "msnsecret"}]}]},

{5236, ejabberd_service, [{hosts, ["yahoo.example.org"],

[{password, "yahoosecret"}]}]},

{5237, ejabberd_service, [{hosts, ["gg.example.org"],

[{password, "ggsecret"}]}]},

{5238, ejabberd_service, [{hosts, ["jmc.example.org"],

[{password, "jmcsecret"}]}]},

{5239, ejabberd_service, [{hosts, ["custom.example.org"],

[{password, "customsecret"}]},

{service_check_from, false}]}

]

}.

{s2s_use_starttls, true}.

{s2s_certfile, "/path/to/ssl.pem"}.

{s2s_default_policy, deny}.

{{s2s_host,"jabber.example.org"}, allow}.

{{s2s_host,"example.com"}, allow}.

注意, 对基于 jabberd14 或 WPJabber 的服务,你不得不做一个网关日志并通过它们本身做 XDB :

<!--

You have to add elogger and rlogger entries here when using ejabberd.

In this case the transport will do the logging.

-->

<log id='logger'> <host/>

<logtype/>

<format>%d: [%t] (%h): %s</format>

<file>/var/log/jabber/service.log</file>

</log>

<!--

Some XMPP server implementations do not provide

XDB services (for example, jabberd2 and ejabberd).

xdb_file.so is loaded in to handle all XDB requests.

-->

<xdb id="xdb">

<host/>

<load>

<!-- this is a lib of wpjabber or jabberd14 -->

<xdb_file>/usr/lib/jabber/xdb_file.so</xdb_file>

</load>

<xdb_file xmlns="jabber:config:xdb_file">

<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>

</xdb_file>

</xdb>

4、认证

选项 auth_method 定义了用于用户认证的认证方法. 语法是:

    {auth_method, [Method, ...]}.

ejabberd支持以下认证方法:

(1)internal (缺省)

(2)external

(3)ldap

(4)odbc

(5)anonymous

(6)pam

只有internal、external和odbc方法支持新建帐号.

当客户端尝试登录时,选项resource_conflict定义试已经连接了。选项的语法是:

    {resource_conflict, setresource|closenew|closeold}.

可能的精确匹配值在XMPP Core: section 7.7.2.2中可以查到。缺省值是closeold。如果客户端用旧的Jabber Non-SASL认证(XEP-0078),则这个选项不重要,且执行closeold动作。

选项fqdn允许你定义机器的完全域名,假设没有被自动检测到。FQDN用于使用DIGEST-MD5 SASL机制认证的客户端,语法如下:

    {fqdn, undefined|FqdnString}.

Internal

ejabberd使用它的内部数据库Mnesia作为缺省的认证方法. 这个值 internal 将允许内部认证方法.

选项{auth_password_format, plain|scram}定义用户密码存储格式:

    plain

密码以纯文形式存储在数据库中。如果数据库泄露会很危险,因为密码可读。这是缺省值。这种格式允许客户端使用这些来认证:旧Jabber Non-SASL (XEP-0078), SASL PLAIN, SASL DIGEST-MD5, and SASL SCRAM-SHA-1.

    scram

不存储密码,而仅仅存储HASH信息。不能从存储的信息获得原始文本密码,由于这个原因,这个值不能再转换为纯文本。这种格式允许客户端使用这些来认证:SASL PLAIN and SASL SCRAM-SHA-1.

例子:

(1)在example.org上使用internal认证, 在example.net上使用LDAP认证:

{host_config, "example.org", [{auth_method, [internal]}]}.

{host_config, "example.net", [{auth_method, [ldap]}]}.

(2)在所有虚拟主机上用密码hash来进行internal认证:

{auth_method, internal}.

External脚本     在ejabberd启动的时候,这种认证方法启动一个脚本,并且调用这个脚本来执行认证任务。

服务器管理员能用任何语言来写external认证脚本。ejabberd和脚本之间接口的描述参见ejabberd开发指南。这儿也有一些认证脚本的例子

这是是特定选项:

{extauth_program, PathToScript}

这个选项指示external认证脚本的全路径。该甲苯必须被ejabberd执行。

{extauth_instances, Integer}

指示在虚拟机上同时运行多少个脚本实例来为认证服务。最小数字的缺省值是1。

{extauth_cache, false|CacheTimeInteger}

缺省值为false,即禁用缓存功能。整数0启用静态缓存,但是不使用缓存信息来认证用户。如果设置为另一个整数值,则启用静态缓存和认证:CacheTimeInteger指示从用户最近断开连接依赖,ejabberd能重新使用认证信息的秒数,确保用户认证不再从扩展认证脚本查询。注意:如果internal认证启用了,则缓存不能再主机内启动。如果缓存启用了,在虚拟主机上mod_last或者mod_last_odbc必须被启用。

这个例子设置external认证,扩展认证脚本启用缓存为10分钟,并且为定义在ejabberd上的每个虚拟主机启动3个脚本实例:

{auth_method, [external]}.

{extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.

{extauth_cache, 600}.

{extauth_instances, 3}.

SASL匿名和匿名登录

这个值 anonymous 将允许internal认证方法.

匿名认证方法可以由以下选项配置. 记住你可以用 host_config 选项设置虚拟主机特有的选项. 注意关于SASL匿名和匿名登录配置也有一个详细的教程 .

    {allow_multiple_connections, false|true}

这个选项只用于匿名模式已经被允许的时候. 设置它为 true 意味着在匿名登录模式里,如果使用不同的资源来连接,同样的用户名可以被使用多次. 这个选项只在非常特殊的情况下有用. 缺省值是 false.

    {anonymous_protocol, sasl_anon | login_anon | both}

sasl_anon 意味着将使用 SASL 匿名方法. login_anon 意味着将使用匿名登录方法. both 意味着SASL匿名和匿名登录都允许.

例子:

(1)在所有虚拟主机上允许匿名登录:

{auth_method, [anonymous]}.

{anonymous_protocol, login_anon}.

(2)类似前例, 但限于public.example.org:

{host_config, "public.example.org", [{auth_method, [anonymous]},

{anonymous_protocol, login_anon}]}.

(3)在一个虚拟主机上允许匿名登录和internal认证:

{host_config, "public.example.org", [{auth_method, [internal,anonymous]},

{anonymous_protocol, login_anon}]}.

(4)在一个虚拟主机上允许SASL匿名:

{host_config, "public.example.org", [{auth_method, [anonymous]},

{anonymous_protocol, sasl_anon}]}.

(5)在一个虚拟主机上允许SASL匿名和匿名登录:

{host_config, "public.example.org", [{auth_method, [anonymous]},

{anonymous_protocol, both}]}.

(6)在一个虚拟主机允许SASL匿名, 匿名登录和inernal认证:

{host_config, "public.example.org", [{auth_method, [internal,anonymous]},

{anonymous_protocol, both}]}.

PAM验证

ejabberd支持通过插件认证模块(PAM)来认证. PAM目前在AIX、FreeBSD、HP-UX、Linux、Mac OS X、NetBSD和Solaris上都支持. PAM认证缺省是被禁止的, 所以你不得不配置和编译ejabberd以使其支持PAM:

./configure --enable-pam && make install

选项:

    {pam_service, Name}

这个选项定义了PAM服务名. 缺省是 "ejabberd". 更多信息请参考你的操作系统的 PAM 文档.

例子:

{auth_method, [pam]}.

{pam_service, "ejabberd"}.

虽然很容易配置ejabberd使其支持PAM, 但是PAM本身介绍了一些安全问题:

(1)为执行PAM认证,ejabberd使用扩展C-program来调用epam. 缺省情况下,它位于/var/lib/ejabberd/priv/bin/目录下. 在这个例子里,如果你的PAM模块要求root权限(例如pam_unix.so),你不得不把它设为root可执行. 你也不得不为ejabberd赋予访问这个文件的权限,并移除所有其它权限. 以root权限执行以下命令:

chown root:ejabberd /var/lib/ejabberd/priv/bin/epam

chmod 4750 /var/lib/ejabberd/priv/bin/epam

(2)确保系统上安装了最新版本的PAM. 一些旧版本的PAM模块会导致内存泄露. 如果你不能使用最新版本, 你可以定期杀掉(1) epam 进程以减少它的内存消耗: ejabberd将立刻重启这个进程.

(3)epam程序在认证失败时尝试关闭延迟. 然而, 一些PAM模块忽略这个行为并依靠它们自己的配置选项. 你可以新建一个配置文件ejabberd.pam. 这个例子展示如何在pam_unix.so模块关闭延迟:

#%PAM-1.0

auth sufficient pam_unix.so likeauth nullok nodelay

account sufficient pam_unix.so

这不是一个已准备好使用的配置文件: 当你建立你自己的PAM配置时,你必须显示使用它. 注意如果你想在PAM配置文件里设置在认证失败时禁止延迟, 你不得不限制访问这个文件, 这样恶意用户就不能使用你的配置来执行暴力攻击.

(4)你可能希望只允许特定用户登录访问. pam_listfile.so 模块提供这个功能.

(5)如果你使用 pam_winbind 来对一个Windows Active Directory授权, 那么 /etc/nssswitch.conf 必须被配置成使用winbind.

5、访问规则

ACL定义

在ejabberd里访问控制是通过访问控制列表(ACLs)来实现的. 配置文件中ACLs的声明语法如下:

    {acl, ACLName, ACLValue}.

ACLValue 可以是以下之一:

    all

匹配所有JIDs. 例子:

{acl, all, all}.

    {user, Username}    

匹配第一个虚拟主机,名字为 Username 的用户. 例子:

{acl, admin, {user, "yozhik"}}.

    {user, Username, Server}

匹配JID为Username@Server加任何资源的用户. 例子:

{acl, admin, {user, "yozhik", "example.org"}}.

    {server, Server}

匹配从服务器Server来的任何JID. 例子:

{acl, exampleorg, {server, "example.org"}}.

    {resource, Resource}

匹配任何资源为Resource的JID. 例子:

{acl, mucklres, {resource, "muckl"}}.

    {shared_group, Groupname}

匹配这个虚拟主机上的共享名册组Groupname的任何成员. 例子:

{acl, techgroupmembers, {shared_group, "techteam"}}.

    {shared_group, Groupname, Server}

匹配虚拟主机Server上的共享名册组Groupname的任何成员. 例子:

{acl, techgroupmembers, {shared_group, "techteam", "example.org"}}.

    {user_regexp, Regexp}

匹配本地虚拟主机上的任何名字符合Regexp的本地用户. 例子:

{acl, tests, {user_regexp, "^test[0-9]*$"}}.

    {user_regexp, UserRegexp, Server}

匹配服务器Server上名字符合UserRegexp的任何用户. 例子:

{acl, tests, {user_Userregexp, "^test", "example.org"}}.

    {server_regexp, Regexp}

匹配来自符合server_regexp的服务器的任何JID. 例子:

{acl, icq, {server_regexp, "^icq\\."}}.

    {resource_regexp, Regexp}

匹配资源符合resource_regexp的任何JID. 例子:

{acl, icq, {resource_regexp, "^laptop\\."}}.

    {node_regexp, UserRegexp, ServerRegexp}

匹配任何名字符合ServerRegexp的服务器上的任何名字符合UserRegexp的用户. Example:

{acl, yohzik, {node_regexp, "^yohzik$", "^example.(com|org)$"}}.

    {user_glob, Glob}

    {user_glob, Glob, Server}

    {server_glob, Glob}

    {resource_glob, Glob}

    {node_glob, UserGlob, ServerGlob}

这和上面一样. 然而, 它使用 shell glob 模式而不是 regexp. 这些模式能拥有以下特别的字符:

    *

匹配任何包含null字符的字符串.  ?

匹配任何单个字符.

[...]

匹配任何封闭的字符串. 字符范围由一对使用‘-’分割的字符串定义. 如果在‘[’之后的第一个字符是一个‘!’, 则匹配任何不封闭的字符.

以下 ACLName 是预定义的:

    all

匹配任何JID.

    none

不匹配任何JID.     访问权限

一个允许或禁止访问不同服务的条目. 语法是:

    {access, AccessName, [ {allow|deny, ACLName}, ...]}.

当一个JID被检查到可以访问 Accessname, 服务器顺序检查是否那个JID匹配任何在列表里元组的第二个元素. 如果匹配, 返回第一个匹配的元组的第一个元素, 否则返回值‘deny’.

如果你在一个虚拟主机上定义了特定的访问权限, 记住全局定义的访问权限比它们拥有优先权. 这意味着, 当发生冲突的时候, 使用全局服务器上的授权或禁止访问控制,而虚拟主机配置的访问控制无效.

例子:

{access, configure, [{allow, admin}]}.

{access, something, [{deny, badmans},

{allow, all}]}.

以下 AccessName 是预定义的:

    all

总是返回值‘allow’.

    none

总是返回值‘deny’.     使用ACL限制打开的会话

access max_user_sessions 定义了每个用户的最大会话(已认证的连接)数量. 如果一个用户尝试通过使用不同的资源打开更多的会话, 第一个打开的会话将被断开连接. session replace的错误信息将被发送到断开连接的会话. 这个选项的值可能是一个数字, 或infinity. 缺省值是infinity.

语法是:

        {access, max_user_sessions, [ {MaxNumber, ACLName}, ...]}.

这个例子对所有用户限制每用户会话数为5, 对管理员限制为10:

{access, max_user_sessions, [{10, admin}, {5, all}]}.

使用ACL限制到一个远程XMPP服务器的多个连接

access max_s2s_connections 定义了可以建立多少个S2S连接到一个特定的远程XMPP服务器. 缺省值是1. 也可以使用access max_s2s_connections_per_node.

语法是:

        {access, max_s2s_connections, [ {MaxNumber, ACLName}, ...]}.

例子:

允许每个远程服务器最多3个连接:

{access, max_s2s_connections, [{3, all}]}.

6、Shapers

shaper允许你限制连接流量. 语法是:

    {shaper, ShaperName, Kind}.

目前只支持maxrate . 语法如下:

    {maxrate, Rate}

这里 Rate 代表最大允许每秒收到的字节数. 当一个连接超过了这个限制, ejabberd停止从socket读取数据,直到平均速率再次降到允许的最大值以下.

例子:

(1)定义一个 shaper 名为 ‘normal’ ,限制流量速度为 1,000 bytes/second:

{shaper, normal, {maxrate, 1000}}.

(2)定义一个 shaper 名为‘fast’,限制流量速度为 50,000 bytes/second:

{shaper, fast, {maxrate, 50000}}.

7、缺省语言

这个选项 language 定义服务器能被XMPP客户端识别的字符串的缺省语言. 如果一个XMPP客户端不支持 xml:lang, 将使用这里定义的语言.

这个选项的语法是:

    {language, Language}.

缺省值是 en. 为了让它生效,在ejabberd的 msgs 目录必须有一个翻译文件 Language.msg.

例如, 设置俄语为缺省语言:

{language, "ru"}.

关于国际化和本地化的更多细节请参看这里,还有这里.

8、CAPTCHA

一些ejabberd模块可被配置成在特定的操作上要求CAPTCHA challenge. 如果客户端不支持 CAPTCHA Forms (XEP-0158), 将提供一个web连接让用户用web浏览器填写challege.

提供了一个示例脚本使用 ImageMagick 的转换程序来生成图片 .

配置选项为:

    {captcha_cmd, Path}

一个生成图片的脚本的全路径. 缺省值为空: undefined

    {captcha_host, ProtocolHostPort}

ProtocolHostPort是一个包含主机名和可选的协议和端口号的字符串. 它必须定义ejabberd从哪里监听CAPTCHA请求。发给用户的URL格式为: http://Host:Port/captcha/,缺省值是:协议http,第一个配置的主机名和端口号80。如果指定端口号不能精确匹配ejabberd监听的端口号(因为使用反向代理或者其它端口转换工具),则必须如下指定传输协议。

另外,一个ejabberd_http listener必须启用captcha选项。

示例配置:

{hosts, ["example.org"]}.

{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.

{captcha_host, "example.org:5280"}.

{listen,

[

...

{5280, ejabberd_http, [

captcha,

...

]

}

]}.

9、STUN

ejabberd可以当作一个独立的 STUN 服务器 (RFC 5389). 目前只支持绑定的使用. 在那个角色中,ejabberd 帮助客户端实现 Jingle ICE (XEP-0176) 支持来发现它们的外部地址和端口.

你应该配置 ejabberd_stun 监听模块. 如果定义了 certfile 选项, ejabberd 在同一个端口复用TCP连接和通过TCP连接的TLS. 很明显, certfile选项仅为tcp定义. 注意无论如何,支持 TCP 或 TLS over TCP,对于绑定使用来说不是必需的,对于TURN功能是保留的. 只有udp传输可以随意配置.

示例配置:

{listen,

[

...

{{3478, udp}, ejabberd_stun, []},

{3478, ejabberd_stun, []},

{5349, ejabberd_stun, [{certfile, "/etc/ejabberd/server.pem"}]},

...

]

}.

你也需要正确地配置 DNS SRV 记录,这样客户端可以很容易地发现一个为你的XMPP域服务的 STUN 服务器. 具体请参考RFC 5389DNS Discovery of a Server 章节.

示例 DNS SRV 配置:

_stun._udp IN SRV 0 0 3478 stun.example.com.

_stun._tcp IN SRV 0 0 3478 stun.example.com.

_stuns._tcp IN SRV 0 0 5349 stun.example.com.

10、包含其它配置文件

配置文件中的选项 include_config_file指示ejabberd立即包含其它配置文件.

基本语法:

    {include_config_file, Filename}.

使用完整语法还可以指定子选项 suboptions :

    {include_config_file, Filename, [Suboption, ...]}.

filename 可使用绝对路径, 或使用主ejabberd配置文件的相对路径. 不能使用通配符. 文件必须存在且可读.

允许的子选项 suboptions 如下:

    {disallow, [Optionname, ...]}

不允许使用那些被包含配置文件中的选项. 满足这个条件的选项立刻变成不可接受. 缺省值为空列表: []

    {allow_only, [Optionname, ...]}

只允许使用那些被包含配置文件中的选项. 不满足这个条件的选项立刻变成不可接受. 缺省值为: all

这是个基本例子:

{include_config_file, "/etc/ejabberd/additional.cfg"}.

在这个例子里, 被包含的文件不允许包含一个监听选项. 如果出现了这个选项, 该选项将不被接受. 这个文件在主配置文件所在目录的一个子目录中.

{include_config_file, "./example.org/additional_not_listen.cfg", [{disallow, [listen]}]}.

在这个例子, ejabberd.cfg 定义了一些 ACL 和 Access rules, 然后包含了另一个文件,里面含有其他 rules:

{acl, admin, {user, "admin", "localhost"}}.

{access, announce, [{allow, admin}]}.

{include_config_file, "/etc/ejabberd/acl_and_access.cfg", [{allow_only, [acl, access]}]}.

并且文件 acl_and_access.cfg 的内容可能如下:

{acl, admin, {user, "bob", "localhost"}}.

{acl, admin, {user, "jan", "localhost"}}.

11、配置文件中的宏选项

在ejabberd配置文件中, 有可能为一个值定义一个宏 macro,以后使用这个宏定义一个选项.

一个宏 macro 可用以下语法定义:

    {define_macro, ’MACRO’, Value}.

MACRO 必须被一对单引号包住, 而且所有字母为大写; 检查以下例子. 值必须是任何合法的随意的 Erlang 项目.

macro的第一个定义会被保留的, 同一个macro的其它定义被忽略.

Macros 在包含了额外的配置文件之后会被处理, 所以有可能在知道用法之前就使用定义在被包含的配置文件里的 macros.

不能使用定义在另一个macro里面的macro.

有两个办法使用宏:

    ’MACRO’

你可以把它当成一个 ejabberd 选项的值, 它将被替换成这个macro之前定义的值. 如果这个 macro 之前没有定义, 程序将崩溃并报错.

    {use_macro, ’MACRO’, Defaultvalue}

使用一个macro,即使它之前没有定义. 如果这个 macro 之前没有定义, 使用缺省值 defaultvalue. 这个用法看起来好像它已被定义并以以下方法使用:

{define_macro, 'MACRO', Defaultvalue}.

'MACRO'

这个例子展示一个宏的基本使用:

{define_macro, 'LOG_LEVEL_NUMBER', 5}.

{loglevel, 'LOG_LEVEL_NUMBER'}.

结果选项被ejabberd解释执行为: {loglevel, 5}.

这个例子展示值可以是任意的Erlang项目:

{define_macro, 'USERBOB', {user, "bob", "localhost"}}.

{acl, admin, 'USERBOB'}.

结果选项被ejabberd解释执行为: {acl, admin, {user, "bob", "localhost"}}.

下面是一个复杂的例子:

{define_macro, 'NUMBER_PORT_C2S', 5222}.

{define_macro, 'PORT_S2S_IN', {5269, ejabberd_s2s_in, []}}.

{listen,

[

{'NUMBER_PORT_C2S', ejabberd_c2s, []},

'PORT_S2S_IN',

{{use_macro, 'NUMBER_PORT_HTTP', 5280}, ejabberd_http, []}

]

}.

在解释执行之后结果为:

{listen,

[

{5222, ejabberd_c2s, []},

{5269, ejabberd_s2s_in, []},

{5280, ejabberd_http, []}

]

}.

二、数据库和LDAP配置

ejabberd缺省使用它内部的 Mnesia 数据库. 然而, 也可能使用关系数据库或一个LDAP服务器来存储持久信息, 长时间存在的数据. ejabberd是非常弹性的: 你可以为不同的虚拟主机配置不同的验证方法, 你可以为相同的主机配置不同的验证机制(fallback), 你可以为模块设置不同的存储系统, 此外.

ejabberd支持以下数据库:

(1)Microsoft SQL Server

(2)Mnesia

(3)MySQL

(4)任何ODBC兼容数据库

(5)PostgreSQL

以下 LDAP 服务器已经过ejabberd测试:

(1)Active Directory

(2)OpenLDAP

(3)通常任何LDAP兼容服务器都应该可以

关于虚拟主机,特别注意: 如果你在ejabberd.cfg定义了多个域, 你可能希望每个虚拟主机配置不同的数据库、验证和存储, 这样在两个虚拟主机之间用户名就不会冲突和混淆. 为此, 下一节的选项描述了必须在每个虚拟主机的 host_config 内部配置. 例如:

{host_config, "public.example.org", [

{odbc_server, {pgsql, "localhost", "database-public-example-org", "ejabberd", "password"}},

{auth_method, [odbc]}

]}.

1、MySQL

尽管这一节将描述当你想使用原生的 MySQL驱动时 ejabberd 的配置, 它将不描述MySQL的安装和数据库的创建. 查看MySQL文档和教程 在ejabberd使用MySQL原生驱动 获得关于这些话题的信息. 注意该教程中包含的关于ejabberd的配置和本节是重复的.

而且, 你可可能会对目录 src/odbc 中的文件 mysql.sql 感兴趣. 这个文件包含ejabberd用于MySQL的schema. 该文件的结尾你可找到更新你的数据库架构schema的信息.

驱动编译

如果你已经使用ejabberd的二进制包安装了ejabberd,或者使用了内含的MySQL支持的ejabberd二进制包,那么你可以忽略此步骤.

(1)首先, 安装 Erlang MySQL 库. 确保被编译的文件在你的 Erlang 路径中; 你可以把它们放到和你的ejabberd .beam 文件相同的目录.

(2)然后, 以允许支持 ODBC 的选项配置并安装 ejabberd (这也需要原生 MySQL 支持!). 为此, 使用以下命令:

./configure --enable-odbc && make install

数据库连接

实际的数据库访问使用选项 odbc_server 来定义. 它的值通常用来定义我们是否想使用 ODBC, 或两个原生接口之一可用, PostgreSQL 或 MySQL.

为使用原生 MySQL 接口, 你可以通过一组如以下格式的参数:

    {mysql, "Server", "Database", "Username", "Password"}

mysql是一个关键字应该被保持. 例如:

    {odbc_server, {mysql, "localhost", "test", "root", "password"}}.

可选的, 有可能定义MySQL使用的端口. 这个选项只是在非常少的情况下有用, 当你没有以缺省端口设置来运行MySQL时. mysql参数可能是以下格式:

    {mysql, "Server", Port, "Database", "Username", "Password"}

Port值应该是一个整数, 没有引号. 例如:

    {odbc_server, {mysql, "localhost", Port, "test", "root", "password"}}.

缺省的ejabberd为每个虚拟主机打开10个到数据库的连接. 使用这个选项来修改该值:

{odbc_pool_size, 10}.

你可以配置一个时间间隔来做一个假的SQL请求以保持到数据库的连接激活. 缺省值为 ’undefined’, 所以没有做 keepalive 请求. 指定以秒计: 例如 28800 意味着 8 小时.

{odbc_keepalive_interval, undefined}.

如果到数据库的连接失败, ejabberd在重试之前等待30秒. 你可以这个选项修改这个间隔:

{odbc_start_interval, 30}.

验证

这个选项值的名字可能被误导, 因为 auth_method 名字用于通过ODBC以及通过原生MySQL接口访问关系数据库. 第一个配置步骤是定义 odbc auth_method. 例如:

{auth_method, [odbc]}.

存储

MySQL也能被从多个ejabberd模块用于存储信息. 这些模块都有一个带‘_odbc’的版本. 这个后缀代表这个模块可以被用于类似MySQL的关系数据库. 为激活你的数据库的存储, 只要确保你的数据库运行正常 (见前一节), 并把不带后缀或ldap模块变量换成带有 odbc 的模块变量. 注意在同一个装载的模块里你不能有多个变量!

2、ODBC兼容

尽管本节将描述当你想使用原生的ODBC 驱动时ejabberd的配置, 它不描述安装和数据库创建. 查看你的数据库的文档. 教程 在ejabberd使用MySQL原生驱动 也会对你有所帮助. 注意该教程中包含的关于ejabberd的配置和本节是重复的.

驱动编译

如果你已经使用ejabberd的二进制包安装了ejabberd,或者包含了对ODBC的支持,那么可以忽略此步骤:

(1)首先, 安装 Erlang MySQL 库 . 确保被编译的文件在你的 Erlang 路径中; 你可以把它们放到和你的ejabberd .beam 文件相同的目录.

(2)然后, 以允许支持 ODBC 的选项配置并安装 ejabberd. 为此, 使用以下命令:

./configure --enable-odbc && make install

数据库连接

实际的数据库访问使用选项 odbc_server 来定义. 它的值通常用来定义我们是否想使用 ODBC, 或两个可用的原生接口之一, PostgreSQL 或 MySQL.

通过ODBC使用数据库, 你可以通过一个ODBC连接字符串作为odbc_server参数. 例如:

{odbc_server, "DSN=database;UID=ejabberd;PWD=password"}.

缺省的ejabberd为每个虚拟主机打开10个到数据库的连接. 使用这个选项来修改该值:

{odbc_pool_size, 10}.

你可以配置一个时间间隔来做一个假的SQL请求以保持到数据库的连接激活. 缺省值为 ’undefined’, 所以没有做 keepalive 请求. 指定以秒计: 例如 28800 意味着 8 小时.

{odbc_keepalive_interval, undefined}.

验证

第一个配置步骤是定义 odbc auth_method. 例如:

{auth_method, [odbc]}.

存储

一个ODBC兼容数据库也能被多个ejabberd模块用于存储信息.这些模块都有一个带‘_odbc’的版本. 这个后缀代表这个模块可以被用于ODBC兼容的关系数据库. 为激活你的数据库的存储, 只要确保你的数据库运行正常 (见前一节), 并把不带后缀或ldap模块变量换成带有 odbc 的模块变量. 注意在同一个装载的模块里你不能有多个变量!

3、LDAP

ejabberd拥有内建的LDAP支持. 你可以通过LDAP服务器验证用户并使用LDAP目录作为vCard存储器.

通常ejabberd把LDAP看作一个只读存储: 它可能察看数据, 但不能新建账号或修改存储在LDAP里的vCard. 然而, 修改密码是可能的,如果允许 mod_register 模块并且LDAP服务器支持RFC 3062.

连接

参数:

    {ldap_servers, [Servers, ...]}

你的LDAP服务器的IP地址或DNS名的列表 . 这个选项时必需的.

    {ldap_encrypt, none|tls}

到LDAP服务器的连接的加密类型. 允许的值为: none, tls. 这个值 tls 允许使用SSL加密LDAP连接. 注意 STARTTLS 加密是不支持的. 缺省值为: none.

    {ldap_tls_verify, false|soft|hard}

这个选项指定当允许TLS时是否验证LDAP服务器证书. 当选项值为 hard,如果证书非法,ejabberd 不继续往下走. 当选项值为 soft,即使检查失败ejabberd仍继续下去. 缺省值为 false,它意味着不执行检查.

    {ldap_port, Number}

连接到你的LDAP服务器的端口. 如果禁止加密,缺省端口为389; 如果允许加密则为636. 如果你配置了一个值, 它存储在 ejabberd的数据库里. 接着, 如果你从这个配置文件移除这个值, 之前存储在数据库的值将被缺省端口取代.

    {ldap_rootdn, RootDN}

绑定的DN. 缺省值为"", 它表示匿名连接 ‘anonymous connection’.

    {ldap_password, Password}

绑定密码 password. 缺省值为 "".

例子:

{auth_method, ldap}.

{ldap_servers, ["ldap.example.org"]}.

{ldap_port, 389}.

{ldap_rootdn, "cn=Manager,dc=domain,dc=org"}.

{ldap_password, "secret"}.

验证

你可以通过LDAP目录验证用户. 可用的选项有:

    {ldap_base, Base}

LDAP存储用户的帐号的基础目录. 这个选项是必需的.

    {ldap_uids, [ {ldap_uidattr} | {ldap_uidattr, ldap_uidattr_format}, ...]}

从中可以获得JID的LDAP属性的列表. 缺省属性为 [{"uid", "%u"}]. 属性的格式为: [{ldap_uidattr}] 或 [{ldap_uidattr, ldap_uidattr_format}]. 你可以使用多个逗号来分隔需要的属性. ldap_uidattr 和 ldap_uidattr_format 的值描述如下: ldap_uidattr 存有JID的user部分的LDAP属性. 缺省值为"uid". ldap_uidattr_format ldap_uidattr变量的格式. 这个格式必须包含一个并且只有一个 pattern 变量 "%u",它将由JID的suer部分替换. 例如,"%u@example.org". 缺省值为 "%u".

    {ldap_filter, Filter}

RFC 4515 LDAP过滤器. 缺省的 Filter 值为: undefined. 例子: "(&(objectClass=shadowAccount)(memberOf=Jabber Users))". 请不要忘记关闭括号并且不要用多余的空格. 在过滤器里你也必须不使用ldap_uidattr属性,因为这个属性将被LDAP filter自动取代.

    {ldap_dn_filter, { Filter, FilterAttrs }}

应用于主过滤器返回的结果的过滤器. 这个filter执行额外的LDAP搜索以得到完整的结果. 当你无法在ldap_filter里定义所有filter rule时这是有用的. 你可以在Filter定义 "%u", "%d", "%s" and "%D" pattern 变量: "%u" 被用户的JID的user部分替代, "%d" 被相应的域(虚拟主机)替代, 所有 "%s" 变量被FilterAttrs属性值连续地替代,"%D" 被 Distinguished Name(DN) 替代. 缺省的,ldap_dn_filter 为 undefined. 例子:

{ldap_dn_filter, {"(&(name=%s)(owner=%D)(user=%u@%d))", ["sn"]}}.

因为这个filter做了额外的LDAP lookups, 只在最后排序时使用它: 如果可能,尝试在 ldap_filter里定义所有 filter rules .

    {ldap_local_filter, Filter}

如果因为性能原因 (该 LDAP 服务器有很多注册用户)你不能使用 ldap_filter , 你可以使用这个本地 filter. local filter 在ejabberd检查一个属性, 而不是 LDAP, 所以限制了这个LDAP目录的负载. 缺省 filter 是: undefined. 示例值:

{ldap_local_filter, {notequal, {"accountStatus",["disabled"]}}}.

{ldap_local_filter, {equal, {"accountStatus",["enabled"]}}}.

{ldap_local_filter, undefined}.

示例     普通示例

让我们以 ldap.example.org 作为我们的 LDAP 服务器名. 我们在 "ou=Users,dc=example,dc=org" 目录使用他们的密码. 同时我们有 addressbook, 在 "ou=AddressBook,dc=example,dc=org" 目录它包含了用户的 emails 和他们的其他信息 . 到LDAP服务器的连接使用TLS加密, 并且使用自定义端口 6123. 相应的验证节应该看起来象这样:

%% Authentication method

{auth_method, ldap}.

%% DNS name of our LDAP server

{ldap_servers, ["ldap.example.org"]}.

%% Bind to LDAP server as "cn=Manager,dc=example,dc=org" with password "secret"

{ldap_rootdn, "cn=Manager,dc=example,dc=org"}.

{ldap_password, "secret"}.

{ldap_encrypt, tls}.

{ldap_port, 6123}.

%% Define the user's base

{ldap_base, "ou=Users,dc=example,dc=org"}.

%% We want to authorize users from 'shadowAccount' object class only

{ldap_filter, "(objectClass=shadowAccount)"}.

现在我们想使用用户的 LDAP-info 作为他们的 vCards. 在我们的 LDAP schema定义了四个属性: "mail" — email地址, "givenName" — 名, "sn" — 姓, "birthDay" — 生日. 我们也想用户搜索到每个其它人. 我们看如何设置:

{modules,

[

...

{mod_vcard_ldap,

[

%% We use the same server and port, but want to bind anonymously because

%% our LDAP server accepts anonymous requests to

%% "ou=AddressBook,dc=example,dc=org" subtree.

{ldap_rootdn, ""},

{ldap_password, ""},

%% define the addressbook's base

{ldap_base, "ou=AddressBook,dc=example,dc=org"},

%% uidattr: user's part of JID is located in the "mail" attribute

%% uidattr_format: common format for our emails

{ldap_uids, [{"mail", "%u@mail.example.org"}]},

%% We have to define empty filter here, because entries in addressbook does not

%% belong to shadowAccount object class

{ldap_filter, ""},

%% Now we want to define vCard pattern

{ldap_vcard_map,

[{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname

{"GIVEN", "%s", ["givenName"]},

{"FAMILY", "%s", ["sn"]},

{"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"

{"EMAIL", "%s", ["mail"]},

{"BDAY", "%s", ["birthDay"]}]},

%% Search form

{ldap_search_fields,

[{"User", "%u"},

{"Name", "givenName"},

{"Family Name", "sn"},

{"Email", "mail"},

{"Birthday", "birthDay"}]},

%% vCard fields to be reported

%% Note that JID is always returned with search results

{ldap_search_reported,

[{"Full Name", "FN"},

{"Nickname", "NICKNAME"},

{"Birthday", "BDAY"}]}

]},

...

]}.

注意 mod_vcard_ldap 模块在LDAP搜索用户的信息之前会先检查用户是否存在.

Active Directory

Active Directory 只是一个预定义属性的LDAP-服务器. 示范配置如下:

{auth_method, ldap}.

{ldap_servers, ["office.org"]}.  % List of LDAP servers

{ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory

{ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager

{ldap_password, "*******"}. % Password to LDAP manager

{ldap_uids, [{"sAMAccountName"}]}.

{ldap_filter, "(memberOf=*)"}.

{modules,

[

...

{mod_vcard_ldap,

[{ldap_vcard_map,

[{"NICKNAME", "%u", []},

{"GIVEN", "%s", ["givenName"]},

{"MIDDLE", "%s", ["initials"]},

{"FAMILY", "%s", ["sn"]},

{"FN", "%s", ["displayName"]},

{"EMAIL", "%s", ["mail"]},

{"ORGNAME", "%s", ["company"]},

{"ORGUNIT", "%s", ["department"]},

{"CTRY", "%s", ["c"]},

{"LOCALITY", "%s", ["l"]},

{"STREET", "%s", ["streetAddress"]},

{"REGION", "%s", ["st"]},

{"PCODE", "%s", ["postalCode"]},

{"TITLE", "%s", ["title"]},

{"URL", "%s", ["wWWHomePage"]},

{"DESC", "%s", ["description"]},

{"TEL", "%s", ["telephoneNumber"]}]},

{ldap_search_fields,

[{"User", "%u"},

{"Name", "givenName"},

{"Family Name", "sn"},

{"Email", "mail"},

{"Company", "company"},

{"Department", "department"},

{"Role", "title"},

{"Description", "description"},

{"Phone", "telephoneNumber"}]},

{ldap_search_reported,

[{"Full Name", "FN"},

{"Nickname", "NICKNAME"},

{"Email", "EMAIL"}]}

]},

...

]}.

三、模块配置

选项 modules 定义ejabberd启动后将被装载的模块的列表. 列表中的每个条目是一个元组,第一个元素是一个模块的名称,第二个是一个模块列表的选项.

语法是:

    {modules, [ {ModuleName, ModuleOptions}, ...]}.

例子:

(1)在这个例子里只有模块 mod_echo 被装载且没有在方括号内指定该模块的选项:

{modules,

[

{mod_echo, []}

]}.

(2)在第二个例子里不带选项地装载了模块 mod_echo, mod_time, 和 mod_version. 特别注意, 除了最后一个条目, 所有条目都以一个逗号结尾:

{modules,

[

{mod_echo, []},

{mod_time, []},

{mod_version, []}

]}.

1、模块一览

2、通用选项

3、mod_announce

4、mod_disco

5、mod_echo

6、mod_http_bind

7、mod_http_fileserver

8、mod_irc

9、mod_last

10、mod_muc

11、mod_muc_log

12、mod_offline

13、mod_ping

14、mod_privacy

15、mod_private

16、mod_proxy65

17、mod_pubsub

18、mod_register

19、mod_roster

20、mod_service_log

21、mod_shared_roster

22、mod_sic

23、mod_stats

24、mod_time

25、mod_vcard

26、mod_vcard_ldap

27、mod_vcard_xupdate

28、mod_version

未完待续。。。

from:http://blog.chinaunix.net/uid-22312037-id-3507236.html