一、基本配置
配置文件将在你第一次启动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-0124和XEP-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 5389的DNS 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支持以下数据库:
(2)Mnesia
(3)MySQL
(4)任何ODBC兼容数据库
(5)PostgreSQL
以下 LDAP 服务器已经过ejabberd测试:
(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