Ejabberd源码解析前奏--配置

一、基本配置
    配置文件将在你第一次启动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 3478 stun.example.com.

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

    _stuns._tcp IN SRV 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

原文地址:https://www.cnblogs.com/xuan52rock/p/4592592.html