Ejabberd2:安装和操作指南

来自Jabber/XMPP中文翻译计划
(版本间的差异)
跳转到: 导航, 搜索
(域负载均衡机制)
(文字错误,“把本” 改为 “版本)
 
(未显示2个用户的2个中间版本)
第1行: 第1行:
[[Category:XMPP服务器软件]]
+
[[Category:XMPP服务器文档]]
 
[[Category:已翻译]]
 
[[Category:已翻译]]
  
第92行: 第92行:
 
Windows安装包把ejabberd安装成了系统服务, 同时有一个快捷方式可以启动一个调试控制台给有经验的管理员使用. 如果你想ejabberd在开机时自动启动, 进入Windows服务设置界面并把ejabberd设置成自动启动. 注意Windows服务还是一个开发中的特性, 例如它不能读取ejabberdctl.cfg文件.
 
Windows安装包把ejabberd安装成了系统服务, 同时有一个快捷方式可以启动一个调试控制台给有经验的管理员使用. 如果你想ejabberd在开机时自动启动, 进入Windows服务设置界面并把ejabberd设置成自动启动. 注意Windows服务还是一个开发中的特性, 例如它不能读取ejabberdctl.cfg文件.
  
在一个 *nix 系统, 如果你想ejabberd在开机时启动成为一个服务, 从 ’bin’目录拷贝 ejabberd.init 到类似 /etc/init.d/ejabberd (取决于你的操作系统的把本). 新建一个系统用户 ejabberd; 它将用于启动该服务的脚本. 然后你可以以root身份调用 /etc/inid.d/ejabberd 来启动服务.
+
在一个 *nix 系统, 如果你想ejabberd在开机时启动成为一个服务, 从 ’bin’目录拷贝 ejabberd.init 到类似 /etc/init.d/ejabberd (取决于你的操作系统的版本). 新建一个系统用户 ejabberd; 它将用于启动该服务的脚本. 然后你可以以root身份调用 /etc/inid.d/ejabberd 来启动服务.
  
 
如果ejabberd不能在Windows里正确地启动, 尝试用启动菜单或桌面的快捷方式启动它. 如果window显式错误14001, 解决方案是安装: "Microsoft Visual C++ 2005 SP1 Redistributable Package". 你可以从 http://www.microsoft.com/ 下载它. 然后卸载并再次安装ejabberd.
 
如果ejabberd不能在Windows里正确地启动, 尝试用启动菜单或桌面的快捷方式启动它. 如果window显式错误14001, 解决方案是安装: "Microsoft Visual C++ 2005 SP1 Redistributable Package". 你可以从 http://www.microsoft.com/ 下载它. 然后卸载并再次安装ejabberd.
第3,760行: 第3,760行:
  
 
<source lang="ini">
 
<source lang="ini">
{domain_balancing, "component.example.com", BalancingCriteria, Number}.
+
{domain_balancing, "component.example.com", BalancingCriteria}.
 
</source>
 
</source>
  

2015年5月5日 (二) 03:37的最后版本


本文的英文原文来自 http://www.process-one.net/en/ejabberd/guide_en

ejabberd 2.1.4 安装和管理指南

目录

绪论

ejabberd是一个用Erlang/OTP语言写的自由和开源的即时消息服务器.

ejabberd是跨平台,分布式, 容错, 并基于开放标准的实时通讯系统.

ejabberd的设计坚若磐石,是一个功能服丰富的XMPP服务器.

ejabberd同时适合小规模布署和超大规模布署, 无论它们是否需要可伸缩性.

关键功能

ejabberd是:

  • 跨平台的: ejabberd可以运行在Microsoft Windows和Unix派生系统,例如Linux, FreeBSD和NetBSD.
  • 分布式的: 你可以在一个集群的机器上运行ejabberd,并且所有的机器都服务于同一个或一些Jabbe域. 当你需要更大容量的时候,你可以简单地增加一个廉价节点到你的集群里. 因此, 你不需要买一个昂贵的高端机器来支持上万个并发用户.
  • 容错: 你可以布署一个ejabberd集群,这样一个正常运行的服务的所有必需信息将被复制到所有节点. 这意味着如果其中一个节点崩溃了, 其他节点将无中断的继续运行. 另外, 也可以‘不停机’增加或更换节点.
  • 易于管理: ejabberd建立于开源的Erlang. 所以你不需要安装外部服数据库, 外部web服务器, 除此以外因为每个东西都已经包含在里面, 并且处于开箱可用状态. 其他管理上的好处包括:
    • 详尽的文档.
    • 便捷的安装程序,包括在Linux, Mac OS X, 以及Windows系统下.
    • Web管理.
    • 共享名册组.
    • 命令行管理工具.
    • 可外部集成的验证机制.
    • 发送匿名消息的能力.
  • 国际化: ejabberd领导国际化. 非常适合全球化. 相关功能包括:
    • 翻译成25种语言.
    • 支持IDNA.
  • 开放标准: ejabberd是的一个完全支持XMPP标准的开源Jabber服务器.
    • 完全兼容XMPP.
    • 基于XML的协议.
    • 支持的协议很多.

额外功能

而且, ejabberd广泛支持的其他先进特性:

  • 模块化
    • 只装在你想要的模块.
    • 在你自己的自定义模块扩展ejabberd.
  • 安全性
    • 支持c2s和s2s连接的SASL和STARTTLS.
    • 支持s2s连接的STARTTLS和Dialback.
    • 可通过HTTPS安全访问的Web管理.
  • 数据库
    • 快速布署的内部数据库(Mnesia).
    • 原生的MySQL支持.
    • 原生的PostgreSQL支持.
    • 支持ODBC数据存储.
    • 支持Microsoft SQL Server.
  • 验证
    • 内部验证.
    • PAM, LDAP 和 ODBC.
    • 外部验证脚本.
  • 其他

安装Installing ejabberd

用ejabberd二进制安装包安装

最简单的安装ejabberd即时消息服务器的方法可能是使用ProcessOne发布的二进制安装包. 已发布的ejabberd版本的二进制安装包在 ProcessOne ejabberd 下载页可以找到: http://www.process-one.net/en/ejabberd/downloads

安装包将布署和配置一个完整的不需要任何依赖的ejabberd服务器.

在 *nix 系统里, 记住启动之前把二进制安装包文件的属性设置成可执行的. 例如:

chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin
./ejabberd-2.0.0_1-linux-x86-installer.bin

ejabberd可以任何时候手工启动, 或在系统启动时由操作系统自动启动.

要手动启动和停止, 可使用安装包建立的桌面快捷方式. 如果机器没有图形系统, 使用在ejabberd安装目录下的 ’bin’ 目录脚本 ’start’ 和 ’stop’.

Windows安装包把ejabberd安装成了系统服务, 同时有一个快捷方式可以启动一个调试控制台给有经验的管理员使用. 如果你想ejabberd在开机时自动启动, 进入Windows服务设置界面并把ejabberd设置成自动启动. 注意Windows服务还是一个开发中的特性, 例如它不能读取ejabberdctl.cfg文件.

在一个 *nix 系统, 如果你想ejabberd在开机时启动成为一个服务, 从 ’bin’目录拷贝 ejabberd.init 到类似 /etc/init.d/ejabberd (取决于你的操作系统的版本). 新建一个系统用户 ejabberd; 它将用于启动该服务的脚本. 然后你可以以root身份调用 /etc/inid.d/ejabberd 来启动服务.

如果ejabberd不能在Windows里正确地启动, 尝试用启动菜单或桌面的快捷方式启动它. 如果window显式错误14001, 解决方案是安装: "Microsoft Visual C++ 2005 SP1 Redistributable Package". 你可以从 http://www.microsoft.com/ 下载它. 然后卸载并再次安装ejabberd.

如果ejabberd不能正确启动并且生成一个崩溃的dump, 表示有严重问题. 在Windows下你可以尝试使用 bin/live.bat 脚本启动ejabberd, 或在其它操作系统执行命令 bin/ejabberdctl live . 用这个办法你可以看到Erlang提供的错误消息并且辨别出确切的问题.

ejabberdctl管理脚本位于 bin 目录. 关于ejabberdctl和用于微调Erlang运行时系统的可配置选项,详见 4.1 章.

用操作系统特定的包安装ejabberd

一些操作系统提供了特定的适应系统体系结构和库的ejabberd包. 它经常也会检查依赖的包并执行基本的配置任务,类似新建初始管理帐号. 例如Debian和Gentoo. 更多信息请查找你的操作系统提供的资源.

那些包经常新建一个脚本,类似 /etc/init.d/ejabberd,在开机时启动和停止 ejabberd 服务.

用CEAN安装ejabberd

CEAN (Comprehensive Erlang Archive Network) 是一个存放了很多Erlang程序二进制包的仓库,包括了ejabberd和它所有的依赖包. 这些二进制包可用于多种不同的系统结构, 所以对于二进制安装包和操作系统的ejabberd包来说,这是一个备选.

根据你如何处理你的CEAN安装而定,你需要新建自己的 ejabberd 启动脚本. 缺省的ejabberdctl脚本位于 ejabberd 的 priv 目录并且用作一个示例.

从源码安装ejabberd

发布ejabberd稳定版的规范方式是源码包. 从源码编译ejabberd在 *nix 系统是非常容易的, 只要你的系统拥有所有的依赖包.

需求

为了在一个‘类Unix’ 操作系统编译ejabberd, 你需要:

  • GNU Make
  • GCC
  • Libexpat 1.95 或更高版本
  • Erlang/OTP R10B-9 或更高版本. 推荐的版本是 R12B-5. 对 R13 的支持是实验性质的.
  • OpenSSL 0.9.6 或更高版本, 用于 STARTTLS, SASL 和 SSL 加密. 可选的, 高度推荐.
  • Zlib 1.2.3 或更高版本, 用于支持流压缩 (XEP-0138). 可选的.
  • Erlang mysql library. 可选的. 用于支持 MySQL 验证或存储. 见 3.2.1 节.
  • Erlang pgsql library. 可选的. 用于支持 PostgreSQL 验证或存储. 见 3.2.3 节.
  • PAM library. 可选的. 用于F 可插拔的验证模块 (PAM). 见 3.1.4 节.
  • GNU Iconv 1.8 或更高版本, 用于 IRC 网关 (mod_irc). 可选的. 在系统里不需要 GNU Libc. 见 3.3.8 节.
  • ImageMagick’s 转换程序. 可选的. 用于 CAPTCHA 挑战. 见 3.1.8 节.
  • exmpp 0.9.2 或更高版本. 可选的. 用于以 XEP-0227 XML文件格式导入/导出用户数据.

下载源码

ejabberd的发布版本在 ProcessOne ejabberd 下载页: http://www.process-one.net/en/ejabberd/downloads

另外, 最新的开发源码可使用命令行从 Git 仓库获得:

git clone git://git.process-one.net/ejabberd/mainline.git ejabberd
cd ejabberd
git checkout -b 2.1.x origin/2.1.x

编译

编译ejabberd可执行以下命令:

./configure
make

编译配置脚本允许很多选项. 要获得所有选项列表执行以下命令:

./configure --help

一些你可能有兴趣修改的选项如下:

--prefix=/

指定运行make install命令时文件将要拷贝的路径.

--enable-user[=USER]

允许普通系统用户执行ejabberdctl脚本 (参见 4.1 节), 读取配置, 读写 spool 目录, 读写 log 目录. 这个帐号的用户和组必须在运行make install之前就存在于机器上. 这个帐号不需要一个暴露的 HOME 目录, 因为缺省将使用 /var/lib/ejabberd/ .

--enable-pam

允许PAM验证方法 (参见 3.1.4 节).

--enable-odbc or --enable-mssql

如果你想使用外部数据库则需要这个选项. 详见 3.2 节.

--enable-full-xml

允许使用基于XML的优化. 例如它将使用 CDATA 来逃逸 XMPP 流中的字符串. 只有你确定你的XMPP客户端有一个全兼容的XML分析器才使用这个选项.

--disable-transient-supervisors

对临时进程禁止使用Erlang/OTP监督.

安装

安装ejabberd到目标目录, 执行以下命令:

make install

注意安装ejabberd的时候你可能需要系统管理员的权限.

缺省的新建文件和目录如下:

/etc/ejabberd/
   配置文件目录:
   ejabberd.cfg
       ejabberd配置文件
   ejabberdctl.cfg
       管理脚本配置文件
   inetrc
       网络DNS配置文件
/lib/ejabberd/
   ebin/
       Erlang二进制文件(*.beam) 
   include/
       Erlang头文件(*.hrl) 
   priv/
       运行时需要的其他文件
       bin/
           可执行程序
       lib/
           二进制系统文件(*.so) 
       msgs/
           翻译文件(*.msgs) 
/sbin/ejabberdctl
   管理脚本(见 4.1 节) 
/share/doc/ejabberd/
   ejabberd文档
/var/lib/ejabberd/
   Spool目录:
   .erlang.cookie
       Erlang cookie文件(见 5.3 节) 
   acl.DCD, ...
       Mnesia数据库spool文件(*.DCD, *.DCL, *.DAT) 
/var/log/ejabberd/
   日志目录(见 7.1 节):
   ejabberd.log
       ejabberd服务日志
   erlang.log
       Erlang/OTP系统日志

启动

你可以使用ejabberdctl命令行管理脚本来启动和停止ejabberd. 如果你提供了配置选项 --enable-user=USER (见 2.4.3 节), 你可以以那个系统帐号或root的身份执行ejabberdctl.

用法示例:

ejabberdctl start
 
ejabberdctl status
The node ejabberd@localhost is started with status: started
ejabberd is running in that node
 
ejabberdctl stop

如果ejabberd无法启动并生成一个崩溃dump, 表示有严重问题. 你可以尝试使用命令ejabberdctl live启动ejabberd来查看由Erlang提供的出错信息并识别出确切的问题.

关于ejabberdctl和微调Erlang运行时系统的可配置选项,详见 4.1 节.

如果你希望ejabberd在开机时以服务身份启动, 拷贝 ejabberd.init 到类似 /etc/init.d/ejabberd 目录(取决于你的操作系统版本). 新建一个系统用户ejabberd; 它将被启动该服务的脚本使用. 然后你可以以root身份在开机时调用 /etc/inid.d/ejabberd 来启动该服务.

BSD的具体说明

在BSD系统编译ejabberd的命令为:

gmake

Sun Solaris的具体说明

你需要一个GNU install, 但是Solaris里没有带. 如果你的Solaris系统是为 blastwave.org 包仓库配置的,这将很容易安装. 确保 /opt/csw/bin 目录在你的 PATH 参数里,然后运行:

pkg-get -i fileutils

如果那个软件名为 ginstall, 修改 ejabberd Makefile 脚本以适应你的系统, 例如:

cat Makefile | sed s/install/ginstall/ > Makefile.gi

最终这样安装ejabberd:

gmake -f Makefile.gi ginstall

Microsoft Windows的具体说明

需求

要在一个Microsoft Windows系统里编译ejabberd, 你需要:

编译

我们假定你将把很多库文件尽可能放在 C:\sdk\ 目录,这样更容易跟踪为了安装ejabberd都需要些什么.

1. 安装 Erlang emulator (例如, 在 C:\sdk\erl5.5.5).

2. 安装 Expat 库文件到 C:\sdk\Expat-2.0.0 目录.

拷贝文件 C:\sdk\Expat-2.0.0\Libs\libexpat.dll 到你的Windows系统目录(例如, C:\WINNT 或 C:\WINNT\System32)

3. 编译和安装 Iconv 库到目录 C:\sdk\GnuWin32.

拷贝文件 C:\sdk\GnuWin32\bin\lib*.dll 到你的Windows系统目录(更多安装指引可在iconv分发版的 README.woe32 文件找到 ).

注意: 也可以不拷贝 libexpat.dll 和 iconv.dll 到Windows系统目录, 而是把目录 C:\sdk\Expat-2.0.0\Libs 和 C:\sdk\GnuWin32\bin 加到 PATH 环境变量去.

4. 安装 OpenSSL 到 C:\sdk\OpenSSL 目录并增加 C:\sdk\OpenSSL\lib\VC 到你的环境变量或拷贝二进制文件到你的系统目录.

5. 安装 ZLib 到 C:\sdk\gnuWin32 目录. 拷贝 C:\sdk\GnuWin32\bin\zlib1.dll 到你的系统目录. 如果你修改了你的 path ,它应该在安装 libiconv 之后已经设置好了.

6. 确保你能从你的路径访问Erlang二进制文件. 例如: set PATH=%PATH%;"C:\sdk\erl5.6.5\bin"

7. 取决于你如果结束实际的库文件安装,你可能需要在文件configure.erl中检查和调整路径.

8. 在目录ejabberd\src中运行:

      configure.bat
      nmake -f Makefile.win32

9. 编辑文件 ejabberd\src\ejabberd.cfg 并运行

      werl -s ejabberd -name ejabberd

新建XMPP管理帐号

你需要一个XMPP帐号并赋予他管理权限来进行ejabberd Web管理:

1. 在你的ejabberd服务器注册一个XMPP帐号, 例如admin1@example.org. 有两个办法来注册一个XMPP帐号:

1.1. 使用ejabberdctl (见 4.1 节):
            ejabberdctl register admin1 example.org FgT5bk3
1.2. 使用一个XMPP客户端进行带内注册(见 3.3.18 节).

2. 编辑ejabberd配置文件来给你创建的XMPP帐号赋予管理权限:

      {acl, admins, {user, "admin1", "example.org"}}.
      {access, configure, [{allow, admins}]}.

你可以赋予管理权限给多个XMPP帐号, 也可以赋予权限给其他XMPP服务器.

3. 重启ejabberd以装载新配置.

4. 用你的浏览器打开Web管理界面(http://server:port/admin/). 确保键入了完整的JID作为用户名(在这个例子里是: admin1@example.org. 你需要加一个后缀的原因是因为ejabberd支持虚拟主机.

升级ejabberd

要升级一个ejabberd安装到一个新版本, 简单地卸载这个旧版本, 然后安装新版本就可以了. 当然, 重要的是配置文件和Mnesia数据库spool目录不能删除.

在它需要的时候ejabberd在启动时会自动更新Mnesia数据表. 如果你也使用一个外部数据库来存储一些模块, 检查新的ejabberd版本的发布备注(release notes)是否指出也需要更新那些表.

配置ejabberd

基本配置

配置文件将在你第一次启动ejabberd时装载. 从该文件获得的内容将被解析并存储到内部的ejabberd数据库. 以后的配置将从数据库装载,并且任何配置文件里的命令都会被添加到数据库里.

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

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

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

override_global.
override_local.
override_acls.

有了这些行,旧的全局选项(在一个集群的所有ejabberd节点之间分享), 本地选项(特有的用于本地ejabberd节点的) 以及 ACLs 将在新配置添加之前被移除.

主机名

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

语法是:

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

示例:

  • 服务一个域:
      {hosts, ["example.org"]}.
  • 服务多个域:
      {hosts, ["example.net", "example.com", "jabber.somesite.org"]}.

虚拟主机

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

语法是:

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

示例:

  • 域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, ""}]}.
  • 域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"}]}
                   ]
  }
 ]}.

监听端口

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

  • 端口号. 还有可选的IP地址和/或一个传输协议.
  • 监听这个端口的模块.
  • TCP socke和监听中的模块的选项.

这个选项的语法是:

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

定义一个 listener 有很多语法.

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

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

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

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

端口号,IP地址和传输协议

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

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

一些IP地址的示例值:

  • "0.0.0.0" 监听所有IPv4网络接口. 这是当没有指定IP地址时的缺省值.
  • "::" 监听所有IPv6网络接口
  • "10.11.12.13" 监听IPv4地址 10.11.12.13
  • "::FFFF:127.0.0.1" 是IPv6地址 ::FFFF:127.0.0.1/128
  • {10, 11, 12, 13} 是IPv4地址 10.11.12.13
  • {0, 0, 0, 0, 0, 65535, 32512, 1} 是IPv6地址 ::FFFF:127.0.0.1/128
  • {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1} 是IPv6地址 FDCA:8AB6:A243:75EF::1/128

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

监听的模块

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

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
选项

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

{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 挑战(见 3.1.8 节).

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节. 如果队列大小达到限制(因为, 例如, 节的接收者太慢), 这个FSM和相应的连接(如果有)将被终止并且记录一个出错信息. 这个选项的合理的值依赖于你的硬件配置. 无论如何, 把这个大小设为1000个元素以上应该没什么感觉. 这个选项可被指定给 ejabberd_service 和 ejabberd_c2s listeners, 或也可以全局地指定给 ejabberd_s2s_out. 如果这个选项没有指定给 ejabberd_service 或 ejabberd_c2s listeners, 则使用全局配置的值. 允许的值为整数和 ’undefined’. 缺省值为: ’undefined’.

{max_stanza_size, Size}

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

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

指定一个或多个 handlers 来伺服HTTP请求. Path是一个字符串列表; 所以以那个 Path 启动的 URIs 将被 Module 伺服. 例如, 你希望 mod_foo to 伺服以 /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 允许组件发送的包的’from’属性可以是任何随意的域. 注意 XEP-0114 要求域必须和组件的主机名吻合. 只有你确保自己需要的情况下才应该激活这个选项. 缺省值是: false.

{shaper, none|ShaperName}

这个选项为端口定义一个塑型者 shaper (见 3.1.6 节). 缺省值是 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分钟).

{max_fsm_queue, Size}

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

{route_subdomains, local|s2s}

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

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

  • 有三个域. 缺省证书文件是 server.pem. 然而, 连接到域example.com的c2s和s2s使用文件example_com.pem.
  • 端口 5222 使用 STARTTLS 监听 c2s 连接, 同时允许简单连接用于旧的客户端.
  • 端口 5223 使用旧的 SSL 监听 c2s 连接 .
  • 端口 5269 使用 STARTTLS 监听 s2s 连接. 这个socket设为IPv6而不是IPv4.
  • 端口 3478 监听通过 UDP 发出的 STUN 请求 .
  • 端口 5280 监听 HTTP 请求, 并伺服 HTTP 轮询服务.
  • 端口 5281 监听 HTTP 请求, 并使用 HTTPS 伺服 Web Admin (见 4.3 节). 这个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"}.

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

  • 端口 5222 (所有IPv4地址)和端口5223 (SSL, IP 192.168.0.1 和 fdca:8ab6:a243:75ef::1)监听c2s连接 ,并禁止名为 ‘bad’的用户.
  • 端口 5269 (所有IPv4地址)为了允许安全通讯而使用STARTTLS监听s2s连接. 远程XMPP服务器的链入和链出连接被禁止, 只有两个服务器可以连接: "jabber.example.org" 和 "example.com".
  • 端口 5280 在所有的IPv4地址伺服 Web Admin 和 HTTP Polling 服务. 注意它也可能在不同端口伺服它们. 4.3 节的第二个例子展示了怎样确切的做法.
  • 除了管理员,所有用户的通讯流量限制为 1,000 Bytes/second
  • AIM 网关 aim.example.org 被连接到localhost IP 地址(127.0.0.1 and ::1)的 5233 端口 , 连接密码为‘aimsecret’.
  • ICQ 网关 JIT (icq.example.org and sms.example.org) 被以密码‘jitsecret’连接到端口 5234 .
  • MSN 网关 msn.example.org 被以密码‘msnsecret’连接到端口 5235 .
  • Yahoo! 网关 yahoo.example.org 被以密码‘yahoosecret’连接到端口 5236 .
  • Gadu-Gadu 网关 gg.example.org 被以密码‘ggsecret’连接到端口 5237 .
  • Jabber Mail 组件 jmc.example.org 被以密码‘jmsecret’连接到端口 5238 .
  • 服务自定义允许特别的选项用来逃避对从这个组件发送的包里检查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>

验证

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

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

ejabberd支持以下验证方法:

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

内部

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

例子:

  • 在example.org使用内部验证, 在example.net使用LDAP验证:
      {host_config, "example.org", [{auth_method, [internal]}]}.
      {host_config, "example.net", [{auth_method, [ldap]}]}.
  • 在所有虚拟主机使用内部验证:
      {auth_method, internal}.
SASL匿名和匿名登录

这个值 anonymous 将允许内部验证方法.

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

{allow_multiple_connections, false|true}

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

{anonymous_protocol, sasl_anon | login_anon | both}

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

那些选项为每个虚拟主机定义的选项 host_config 参数 (见 3.1.2 节).

例子:

  • 在所有虚拟主机上允许匿名登录:
      {auth_method, [anonymous]}.
      {anonymous_protocol, login_anon}.
  • 类似前例, 但限于 public.example.org:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, login_anon}]}.
  • 在一个虚拟主机允许匿名登录和内部验证:
      {host_config, "public.example.org", [{auth_method, [internal,anonymous]},
                                           {anonymous_protocol, login_anon}]}.
  • 在一个虚拟主机允许SASL匿名:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, sasl_anon}]}.
  • 在一个虚拟主机允许SASL匿名和匿名登录:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, both}]}.
  • 在一个虚拟主机允许SASL匿名, 匿名登录, 和内部验证:
      {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 验证缺省是被禁止的, 所以你不得不使用 PAM support enabled 选项来配置并编译ejabberd:

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

选项:

{pam_service, Name}

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

例子:

{auth_method, [pam]}.
{pam_service, "ejabberd"}.

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

  • 为执行PAM验证,ejabberd使用名为 epam 的外部C程序. 缺省的, 它位于 /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
  • 确保你已在你的系统安装了最新版本的PAM. 一些旧版本的PAM模块会导致内存溢出. 如果你不能使用最新版本, 你可以定期杀掉(1) epam 进程以减少它的内存消耗: ejabberd将立刻重启这个进程.
  • 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配置文见里设置在验证失败时禁止延迟, 你不得不限制访问这个文件, 这样恶意用户就不能使用你的配置来执行暴力攻击.
  • 你可能希望只允许特定用户登录访问. pam_listfile.so 模块提供这个功能.
  • 如果你使用 pam_winbind 来对一个Windows Active Directory授权, 那么 /etc/nssswitch.conf 必须被配置成使用winbind.

访问规则

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 匹配任何在列表里这一元组的第二个元素命名的 ACLs. 如果匹配, 返回第一个匹配的元组的第一个元素, 否则返回值‘deny’.

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

例子:

{access, configure, [{allow, admin}]}.
{access, something, [{deny, badmans},
                     {allow, all}]}.

以下 AccessName 是预定义的:

all

总是返回值‘allow’.

none

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

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

语法是:

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

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

{access, max_user_sessions, [{10, admin}, {5, all}]}.
使用ACL限制到一个远程XMPP服务器的多个连接

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

语法是:

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

例子:

  • 允许每个远程服务器最多3个连接:
      {access, max_s2s_connections, [{3, all}]}.

整形

整形允许你限制连接的通讯量. 语法是:

{shaper, ShaperName, Kind}.

目前只支持一种整形 maxrate . 语法如下:

{maxrate, Rate}

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

例子:

  • 定义一个 shaper 名为 ‘normal’ ,限制流量速度为 1,000 bytes/second:
      {shaper, normal, {maxrate, 1000}}.
<source>
 
* 定义一个 shaper 名为‘fast’,限制流量速度为 50,000 bytes/second:
 
<source lang="ini">
      {shaper, fast, {maxrate, 50000}}.

缺省语言

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

这个选项的语法是:

{language, Language}.

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

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

{language, "ru"}.

附录 A 提供了关于国际化和本地化的更多细节.

CAPTCHA

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

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

配置选项为:

{captcha_cmd, Path}

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

{captcha_host, Host}

发给用户的 URL 的 Host 部分. 你可以包含端口号. 发给用户的 URL 的格式为: http://Host/captcha/ ,缺省值是第一个被配置的主机名.

另外, 必须允许一个 ejabberd_http 监听者拥有 captcha 选项. 见 3.1.3 节.

示例配置:

{hosts, ["example.org"]}.
 
{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
{captcha_host, "example.org:5280"}.
 
{listen,
 [
  ...
  {5280, ejabberd_http, [
                         captcha,
                         ...
                        ]
  }
 
]}.

STUN

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

你应该配置 ejabberd_stun 监听模块,如 3.1.3 节所述. 如果定义了 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.

包含其它配置文件

一个配置文件中的选项 include_config_file 代表 ejabberd 包含了其他配置文件to include other configuration files immediately.

基本语法:

{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"}.

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

{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"}}.

配置文件中的宏选项

在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支持以下数据库:

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

  • Active Directory (见 3.2.5 节)
  • OpenLDAP
  • 通常任何LDAP兼容服务器都应该可以; 通知我们关于你以不在列表中的服务器的成功例子以便我们列在这里.

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

{host_config, "public.example.org", [
  {odbc_server, {pgsql, "localhost", "database-public-example-org", "ejabberd", "password"}},
  {auth_method, [odbc]}
]}.

MySQL

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

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

驱动编译

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

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

Microsoft SQL Server

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

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

驱动编译

你可忽略此步骤,如果你已经使用ejabberd的二进制包安装了ejabberd,并使用了内含的ODBC支持.

如果你想以ODBC方式使用Microsoft SQL Server, 你需要以支持ODBC和允许Microsoft SQL Server选项来配置, 编译和安装 ejabberd. 为此, 使用以下命令:

./configure --enable-odbc --enable-mssql && make install
数据库连接

一个Microsoft SQL Server数据库连接的配置和为一个ODBC兼容服务器的配置相同 (见 3.2.4 节).

验证

一个Microsoft SQL Server数据库验证的配置和为一个ODBC兼容服务器的配置相同 (见 3.2.4 节).

存储

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

PostgreSQL

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

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

驱动编译

你可忽略此步骤,如果你已经使用ejabberd的二进制包安装了ejabberd,并包含了对PostgreSQL的支持.

  1. 首先, 从 ejabberd-modules SVN 仓库安装 Erlang pgsql 库. 确保被编译的文件在你的 Erlang 路径中; 你可以把它们放到和你的ejabberd .beam 文件相同的目录.
  2. 然后, 以允许支持 ODBC 的选项配置并安装 ejabberd (对于原生的 PostgreSQL 支持这也是必需的!). 为此, 使用以下命令:
      ./configure --enable-odbc && make install
数据库连接

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

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

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

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

{odbc_server, {pgsql, "localhost", "database", "ejabberd", "password"}}.

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

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

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

{odbc_server, {pgsql, "localhost", 5432, "database", "ejabberd", "password"}}.

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

{odbc_pool_size, 10}.

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

{odbc_keepalive_interval, undefined}.
验证

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

{auth_method, [odbc]}.
存储

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

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

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实现不支持SASL验证.

验证

你可以通过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}, ...]}.

例子:

  • 在这个例子里只有模块 mod_echo 被装载宁且没有在方括号内定义该模块的选项:
      {modules,
       [
        {mod_echo,      []}
       ]}.
  • 在第二个例子里不带选项地装载了模块 mod_echo, mod_time, 和 mod_version. 特别注意, 除了最后一个条目, 所有条目都以一个逗号结尾:
      {modules,
       [
        {mod_echo,      []},
        {mod_time,      []},
        {mod_version,   []}
       ]}.

模块一览

下表列出ejabberd里的所有模块.

模块 功能 依赖
mod_adhoc 特定命令 (XEP-0050)
mod_announce 管理公告 推荐 mod_adhoc
mod_caps 实体能力 (XEP-0115)
mod_configure 使用特定命令配置服务器 mod_adhoc
mod_disco 服务发现 (XEP-0030)
mod_echo XMPP节回音
mod_irc IRC网关
mod_last 最后活动 (XEP-0012)
mod_last_odbc 最后活动 (XEP-0012) 支持的数据库 (*)
mod_muc 多用户聊天 (XEP-0045)
mod_muc_log 多用户聊天室记录 mod_muc
mod_offline 离线消息存储 (XEP-0160)
mod_offline_odbc 离线消息存储 (XEP-0160) 支持的数据库 (*)
mod_ping XMPP Ping 和定期保持连接 (XEP-0199)
mod_privacy 禁止通讯 (XMPP IM)
mod_privacy_odbc 禁止通讯 ((XMPP IM) 支持的数据库 (*)
mod_private 私有XML存储 (XEP-0049)
mod_private_odbc 私有XML存储 (XEP-0049) 支持的数据库 (*)
mod_proxy65 SOCKS5字节流 (XEP-0065)
mod_pubsub 发行-订阅 (XEP-0060), PEP (XEP-0163) mod_caps
mod_pubsub_odbc 发行-订阅 (XEP-0060), PEP (XEP-0163) 支持的数据库 (*) 和 mod_caps
mod_register I带内注册 (XEP-0077)
mod_roster 名册管理 (XMPP IM)
mod_roster_odbc 名册管理 (XMPP IM) 支持的数据库 (*)
mod_service_log 拷贝用户消息到日志服务
mod_shared_roster 共享名册管理 mod_roster 或 mod_roster_odbc
mod_sic Server IP检查 (XEP-0279)
mod_stats 统计信息收集 (XEP-0039)
mod_time 实体时间 (XEP-0202)
mod_vcard 电子名片 (XEP-0054)
mod_vcard_ldap 电子名片 (XEP-0054) LDAP服务器
mod_vcard_odbc 电子名片 (XEP-0054) 支持的数据库 (*)
mod_vcard_xupdate 基于vCard的头像 (XEP-0153) mod_vcard 或 mod_vcard_odbc
mod_version 软件版本 (XEP-0092)
  • (*) 这个模块需要数据库支持. 关于支持的数据库列表, 见 3.2 节.

通过后缀你可以看到每个模块需要哪个数据库后端:

  • 没有后缀, 这意味着那个模块使用Erlang的内建数据库 Mnesia 作为后端.
  • ‘_odbc’, 这意味着该模块需要一个支持的数据库 (见 3.2 节) 作为后端.
  • ‘_ldap’, 这意味着该模块需要一个LDAP服务器作为后端.

如果你想要, 有可能使用一个关系数据库来存储信息件. 你可以通过在ejabberd 配置文件修改模块名称带上_odbc 后缀来实现这点. 你可以为以下数据使用关系数据库:

  • 最后连接日期和时间: 使用 mod_last_odbc 取代 mod_last.
  • 离线消息: 使用 mod_offline_odbc 取代 mod_offline.
  • 名册: 使用 mod_roster_odbc 取代 mod_roster.
  • 用户的VCARD: 使用 mod_vcard_odbc 取代 mod_vcard.
  • 私有XML存储: 使用 mod_private_odbc 取代 mod_private.
  • 用户黑名单规则: 使用 mod_privacy_odbc 取代 mod_privacy.

你可以在ejabberd网站找到更多别人捐献的模块的信息. 请记住这些捐献可能不能用或它们有些bug和安全泄露. 所以, 使用他们是你们自己的风险!

通用选项

以下选项被多个模块使用. 所以, 它们被单列一节.

iqdisc

很多模块为处理发到这个服务器或一个用户(例如. 给 example.org 或给 user@example.org)的不同namespaces的IQ queries定义了处理程序. 这个选项定义了这些queries的处理原则.

语法是:

{iqdisc, Value}

可能的值有:

no_queue

一个拥有此处理原则的 namespace 的所有 queries 会被立即处理. 这也意味着在这个包完全处理完之前,不可以处理任何包. 如果一个query的处理可能消耗比较长的时间,今后将不推荐这个原则.

one_queue

在这种情况下,将为一个拥有此处理原则的 namespace建立一个独立的队列来处理它们. 另外, 这个队列的处理和其他包的队列是并行的. 这个原则是最推荐的.

{queues, N}

N个独立的队列被建立用来处理这些 queries. 因而 queries 被并行处理, 但是以一个可控的方法.

parallel

对每一个拥有此原则的包产生一个独立的Erlang进程. 所以, 所有这些包被并行处理. 尽管Erlang进程的产生成本相对较低, 这可能中断服务器的正常工作, 因为Erlang模拟器对进程数量有限制 (缺省为32000).

例子:

{modules,
 [
  ...
  {mod_time, [{iqdisc, no_queue}]},
  ...
 ]}.
host

这个选项定义一个ejabberd 模块提供的服务的 Jabber ID.

语法是:

{host, HostName}

如果你在 HostName 里包含了关键字 "@HOST@" , 它在启动时被替换为真实的虚拟主机字符串.

这个例子配置了 echo 模块以 Jabber ID mirror.example.org来提供它的回音服务:

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

无论如何, 如果有多个虚拟主机并且这个模块在所有虚拟主机中都被激活, 必须使用"@HOST@" 关键字:

{modules,
 [
  ...
  {mod_echo, [{host, "mirror.@HOST@"}]},
  ...
 ]}.

mod_announce

本模块允许配置用户广播公告并设定本日消息 (MOTD). 被配置的用户可以在一个XMPP客户端使用Ad-hoc命令或发送消息给指定的JIDs来执行这些动作.

特定命令被列于服务发现. 要使用此功能, 必须激活 mod_adhoc 模块.

可以发送消息的特定 JIDs 清单如下. 在每个条目的第一个 JID 将只应用于指定的虚拟主机 example.org, 而括号里的 JID 将应用于ejabberd的所有虚拟主机.

example.org/announce/all (example.org/announce/all-hosts/all)

消息将被发送给所有注册用户. 如果用户在线并连接了多个资源, 只有高优先级的资源将收到消息. 如果注册用户没有连接, 消息将离线存储,假定激活了离线存储 (见 [[Ejabberd2:安装和操作指南#mod_offline|3.3.12] 节).

example.org/announce/online (example.org/announce/all-hosts/online)

消息被发送到所有已连接的用户. 如果用户在线且连接了多个资源, 所有资源将接收到消息.

example.org/announce/motd (example.org/announce/all-hosts/motd)

该消息被设置为每日消息 (MOTD) 并在用户登录时被发送给用户. 另外这个消息会被发送给所有连接的用户 (类似 announce/online).

example.org/announce/motd/update (example.org/announce/all-hosts/motd/update)

该消息被设置为每日消息 (MOTD) 并在用户登录时被发送给用户. 这个消息不发送给任何当前已连接的用户.

example.org/announce/motd/delete (example.org/announce/all-hosts/motd/delete)

任何发送到此JID的消息移除现有的每日消息 (MOTD).

选项:

{access, AccessName}

这个选项指定谁被允许发送公告并设置每日消息 (缺省的, 没有人能发送这类消息).

例子:

  • 只有管理员能发送公告:
      {access, announce, [{allow, admins}]}.
 
      {modules,
       [
        ...
        {mod_adhoc, []},
        {mod_announce, [{access, announce}]},
        ...
       ]}.
  • 管理员以及 direction 可发送公告:
      {acl, direction, {user, "big_boss", "example.org"}}.
      {acl, direction, {user, "assistant", "example.org"}}.
      {acl, admins, {user, "admin", "example.org"}}.
 
      {access, announce, [{allow, admins},
                          {allow, direction}]}.
 
      {modules,
       [
        ...
        {mod_adhoc, []},
        {mod_announce, [{access, announce}]},
        ...
       ]}.

注意 mod_announce 在大的布署里可能是资源敏感的,因为它可能广播非常多的消息. 对于拥有成百上千用户的ejabberd实例,这个模块应该被禁止.

mod_disco

这个模块增加多服务发现 (XEP-0030) 的支持. 激活本模块, 你的服务器上的服务可以被XMPP客户端发现. 注意ejabberd没有模块支持被取代的 Jabber Browsing (XEP-0011) 和 Agent Information (XEP-0094). 于是,如果你想它们能发现你提供的服务,XMPP客户端需要支持这个比较新的发现协议.

选项:

{iqdisc, Discipline}

这定义服务发现的IQ queries的处理原则 (http://jabber.org/protocol/disco#itemshttp://jabber.org/protocol/disco#info) (见 3.3.2).

{extra_domains, [Domain, ...]}

使用这个选项, 你可以指定一个增加到服务发现条目列表中的附加域的列表.

{server_info, [ {Modules, Field, [Value, ...]}, ... ]}

指定关于本服务器的额外的信息, 参见 XMPP服务的联系地址 (XEP-0157). Modules 可以是关键字‘all’, 这种情况下信息被汇报给所有服务; 或是一个 ejabberd 模块的列表, 这种情况下信息仅被指定给那些模块提供的服务. 可以指定任意的 Field 和 Value , 不只是联系地址.

例子:

  • 提供一个链接到jabber.org上的Jabber用户目录:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["users.jabber.org"]}]},
        ...
       ]}.
  • 提供一个链接到其他服务器的网关:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["icq.example.com",
                                      "msn.example.com"]}]},
        ...
       ]}.
  • 提供一个链接到一些友好的服务器:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["example.org",
                                      "example.com"]}]},
        ...
       ]}.
  • 使用这个配置, 所有服务在主服务器显示滥用地址, 回复地址, 并同时在主服务器和vJUD服务显示管理员地址:
      {modules,
       [
        ...
        {mod_disco, [{server_info, [
            {all,
             "abuse-addresses",
             ["mailto:abuse@shakespeare.lit"]},
            {[mod_muc],
             "Web chatroom logs",
             ["http://www.example.org/muc-logs"]},
            {[mod_disco],
             "feedback-addresses",
             ["http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit"]},
            {[mod_disco, mod_vcard],
             "admin-addresses",
             ["mailto:xmpp@shakespeare.lit", "xmpp:admins@shakespeare.lit"]}
        ]}]},
        ...
       ]}.

mod_echo

本模块简单地对任何XMPP包发出回音给发送者. ejabberd和XMPP客户端调试可能对这个镜子感兴趣.

选项:

{host, HostName}

这个选项定义服务的Jabber ID. 如果 host 选项没指定, Jabber ID 将是前缀‘echo.’加该虚拟主机的 hostname . 关键字 "@HOST@" 在启动时被替换成真实的虚拟主机名.

例子: 镜子, 镜子, 在墙上, 他们谁是最美丽的?

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

mod_http_bind

本模块实现了定义于 XEP-0124XEP-0206的 XMPP over Bosh (正式的名字是 HTTP Binding). 它在这个将被伺服的服务上以一个可配置的资源扩展了ejabberd的HTTP服务, .

要使用 HTTP-Binding, 激活这个模块:

{modules,
 [
  ...
  {mod_http_bind, []},
  ...
]}.

并增加 http_bind 到 HTTP 服务. 例如:

{listen, 
 [
  ...
  {5280, ejabberd_http, [
                         http_bind,
                         http_poll,
                         web_admin
                        ]
  },
  ...
]}.

使用这个配置, module 将伺服发送给 http://example.org:5280/http-bind/ 的请求. 记住这个页面不是被设计给web浏览器使用的, 它是被支持XMPP over Bosh的XMPP客户端使用的.

如果你想以不同的URI路径设置服务或使用一个不同的模块, 你可以使用选项request_handlers手工配置它. 例如:

{listen, 
 [
  ...
  {5280, ejabberd_http, [
                         {request_handlers, [{["http-bind"], mod_http_bind}]},
                         http_poll,
                         web_admin
                        ]
  },
  ...
]}.

选项:

{max_inactivity, Seconds}

以秒数定义最大闲置时间. 缺省值为30秒. 例如, 设置成50秒:
    {modules,
     [
      ...
      {mod_http_bind, [ {max_inactivity, 50} ]},
      ...
    ]}.

mod_http_fileserver

这个简单的模块从本地磁盘通过HTTP提供文件服务.

选项:

{docroot, Path}

伺服文件的目录.

{accesslog, Path}

使用一个类似Apache格式的日志文件. 如果没指定本选项则不记录日志.

{directory_indices, [Index, ...]}

包含一个或多个目录的索引文件, 类似 Apache的 DirectoryIndex 变量. 当一个web请求去到一个目录而不是常规的文件, 那些目录的 indices 被顺序装载, 并且返回被发现的第一个.

{custom_headers, [ {Name, Value}, ...]}

表明自定义的HTTP头将被包含在所有应答中. 缺省值是: []

{content_types, [ {Name, Type}, ...]}

指定内容类型的扩展. 已经定义了很多 content types , 使用本选项你可以增加新的定义, 修改或删除现存的. 要删除现有定义, 简单的以一个值定义它: ‘undefined’.

{default_content_type, Type}

指定 content type 使用未知的扩展. 缺省是‘application/octet-stream’.

这个实例配置将从本地目录 /var/www 在地址 http://example.org:5280/pub/archive/ 提供文件服务. 在这个例子定义了一个新的 content type ogg, png 重新定义了, 而 jpg 定义被删除了. 要使用本模块你必须激活它:

{modules,
 [
  ...
  {mod_http_fileserver, [
                         {docroot, "/var/www"}, 
                         {accesslog, "/var/log/ejabberd/access.log"},
                         {directory_indices, ["index.html", "main.htm"]},
                         {custom_headers, [{"X-Powered-By", "Erlang/OTP"},
                                           {"X-Fry", "It's a widely-believed fact!"}
                                          ]},
                         {content_types, [{".ogg", "audio/ogg"},
                                          {".png", "image/png"},
                                          {".jpg", undefined}
                                         ]},
                         {default_content_type, "text/html"}
                        ]
  },
  ...
]}.

并且在HTTP服务里把它定义为一个处理器:

{listen, 
 [
  ...
  {5280, ejabberd_http, [
                         ...
                         {request_handlers, [
                                             ...
                                             {["pub", "archive"], mod_http_fileserver},
                                             ...
                                            ]
                         },
                         ...
                        ]
  },
  ...
]}.

mod_irc

本模块是一个 IRC 网关用于加入IRC服务器的频道.

最终用户信息:

  • 一个支持‘groupchat 1.0’或 Multi-User Chat (XEP-0045)的XMPP客户端需要加入IRC频道.
  • 一个IRC频道可能被以近似相同的方式加入一个XMPP多用户聊天室. 不同处是房间名将变成‘channel%irc.example.org’,在这个情况下 irc.example.org 是伺服‘channel’的IRC服务器. 并且当然这个主机应该指向IRC网关而不是多用户聊天服务.
  • 你可以注册你的昵称,通过发送‘IDENTIFY password’到 nickserver!irc.example.org@irc.jabberserver.org.
  • 键入你的密码,通过发送‘LOGIN nick password’到 nickserver!irc.example.org@irc.jabberserver.org.
  • IRC网关提供 Ad-Hoc Commands (XEP-0050) 来加入一个频道, 并设定自定义的 IRC 用户名和编码.
  • 当使用一个流行的XMPP服务器, 可能它没有到一些IRC服务器的连接存在,因为它们限制从一个IP来的连接的数量.

选项:

{host, HostName}

这个选项定义该服务的 Jabber ID. 如果 host 选项未定义, Jabber ID 将是该虚拟主机的 hostname 加上前缀‘irc.’. 关键字 "@HOST@" 在启动时被替换成真实的虚拟主机名.

{access, AccessName}

这个选项可被用于定义谁能使用 IRC 网关 (缺省值: all).

{default_encoding, Encoding}

设置缺省的 IRC 编码. 缺省值: "koi8-r"

例子:

  • 在第一个例子里, IRC网关在你的所有带有前缀‘irc.’的虚拟主机上可用. 进一步的, 任何人可以使用这个这个网关. 缺省编码设为 "iso8859-15".
      {modules,
       [
        ...
        {mod_irc, [{access, all}, {default_encoding, "iso8859-15"}]},
        ...
       ]}.
  • 在下一个例子,IRC网关对于那些拥有前缀irc-t.net的JIDs可用. 而且, 这个网关只可以被example.org的两个用户以及example.com上的所有用户使用:
      {acl, paying_customers, {user, "customer1", "example.org"}}.
      {acl, paying_customers, {user, "customer2", "example.org"}}.
      {acl, paying_customers, {server, "example.com"}}.
 
      {access, irc_users, [{allow, paying_customers}, {deny, all}]}.
 
      {modules,
       [
        ...
        {mod_irc, [{access, irc_users},
                   {host, "irc.example.net"}]},
        ...
       ]}.

mod_last

本模块增加对最后活动(XEP-0012)的支持. 它可被用于发现什么时候离线用户最后一次访问服务器, 并知道在这台服务器上一个连接的用户的最后活动, 或查询ejabberd服务器的运行时间.

选项:

{iqdisc, Discipline}

这是为 最后活动(jabber:iq:last) IQ queries 定义处理原则(见 3.3.2 节).

mod_muc

本模块提供一个多用户聊天(XEP-0045)服务. 用户可以发现现有房间, 加入或新建房间. 房间的房客可以公开或私下聊天.

多用户聊天的一些功能:

  • 发送公开或私有消息给房间房客.
  • 邀请其他用户到一个房间.
  • 设定一个房间的标题.
  • 建立密码保护房间.
  • 踢人或拉黑名单.

这个MUC服务允许任何Jabber ID注册一个昵称, 这样没有别人可以在该MUC服务的任何房间使用那个昵称. 为了注册一个昵称, 在你的XMPP客户端打开服务发现并注册到该MUC服务.

本模块支持集群和负载均衡. 一个模块可被每个集群节点启动. 在特定的时间房间分布于所有可用的MUC模块实例上. 多用户聊天模块是集群的但房间本身不是集群的,也不是容错的: 如果管理那些房间的节点挂了, 那些房间就消失了并且它们将在第一次尝试连接得到的可用节点上重建.

Module 选项:

{host, HostName}

这个选项定义服务的Jabber ID. 如果 host 选项未指定, 该Jabber ID将是虚拟主机的hostname加上前缀‘conference.’. 关键字 "@HOST@" 在启动时被替换为真实的虚拟主机名.

{access, AccessName}

你可以指定谁有权使用多用户聊天服务. 缺省每个人都被允许使用它.

{access_create, AccessName}

为配置在多用户聊天服务里谁被允许创建新房间 , 可使用这个选项. 缺省任何本地ejabberd服务器的帐号都被允许新建房间.

{access_persistent, AccessName}

为配置谁被允许修改持久 ’persistent’房间的选项. 缺省任何本地ejabberd服务器的帐号被允许修改那个选项.

{access_admin, AccessName}

这个选项指定谁被允许管理多用户聊天服务. 缺省值为 none, 它意味着只有房间创建者可以管理他的房间. 管理员们可以发送一个普通消息给服务 JID, 并且它将被作为一个服务消息显示在所有房间. 管理员们可以发送一个 groupchat 消息给一个激活的房间的JID, 并且该消息将被显示为一个服务消息.

{history_size, Size}

当用户进入房间时被发送给用户的一个当前讨论的短小历史. 使用此选项你可以定义保持的历史数据数量,用来在用户加入房间时发送给他们. 这个值是一个整数. 设定这个值为 0 禁止历史功能并且, 导致一个结果, 没东西保留在内存里. 这个缺省值是 20. 这个值是全局的并且因而会影响服务的所有房间.

{max_users, Number}

这个选项定义是服务级别的, 每房间允许的最大用户数. 它可以低于每个房间的配置但是不能在单个的房间配置里增加. 缺省值为200.

{max_users_admin_threshold, Number}

这个选项定义,当房间允许的最大房客数量达到之后,被允许进入房间的服务管理员或房间所有者的数量. 缺省限制为 5.

{max_user_conferences, Number}

这个选项定义给定用户能加入的房间的最大数量. 缺省值为 10. 这个选项被用于阻止可能的滥用. 注意这是个软限制: 一些用户有时候可以在集群配置里加入更多的会议.

{max_room_id, Number}

这个选项定义,当新建一个房间时,Room ID 字符串的可以有的最大长度. 缺省值是不限制: infinite.

{max_room_name, Number}

这个选项定义,当配置一个房间时,Room Name 字符串的可以有的最大长度. 缺省值是不限制: infinite.

{max_room_desc, Number}

这个选项定义,当配置一个房间时,Room Description 字符串的可以有的最大长度. 缺省值是不限制: infinite.

{min_message_interval, Number}

这个选项定义,在一个房客发送的两个消息之间的最小间隔时间,以秒计. 这个选项是全局的并且检查所有房间. 可使用一个十进制值. 当这个选项没定义时, 消息速率是不限制的. 这个功能可用来保护MUC服务不被房客滥用并限制服务广播的消息数量. 对于这个最小消息间隔时间,一个比较好的值是0.4秒. 如果一个房客试图更快地发送消息, 发回一个错误并解释这个消息已被抛弃并描述为什么消息不被接受的原因.

{min_presence_interval, Number}

这个选项定义一个给定房客的两次出席信息变更之间的最小时间,以秒计. 这个选项是全局的并且会对所有房间生效. 可以用一个十进制数值. 当这个选项没有定义的时候, 没有限制. 这个选项可被用于保护一个MUC服务不被房客滥用. 如果一个房客试图在指定的间隔时间内更多次的变更出席信息, 这个出席信息被 ejabberd 缓存并只有在间隔延迟过期后最新的出席信息被广播给房间里的所有房客. 中间的出席信息包被安静的抛弃. 一个好的选项值是4秒.

{default_room_options, [ {OptionName, OptionValue}, ...]}

这个选项允许定义期望的缺省房间选项. 注意一个房间的创建者可以在任何时候使用一个有MUC能力的XMPP客户端修改他自己的房间的选项. 可用的房间选项和缺省值有:
{allow_change_subj, true|false}
允许房客修改标题.
{allow_private_messages, true|false}
房客可以发送私有消息给其他房客.
{allow_query_users, true|false}
房客可发送 IQ queries 给其他房客.
{allow_user_invites, false|true}
允许房客发送邀请.
{allow_visitor_nickchange, true|false}
允许游客修改昵称.
{allow_visitor_status, true|false}
允许游客在出席信息更新里发送status状态文本. I如果不允许, 在广播出席信息更新给房间里所有的房客时这个 status 文本被剥离.
{anonymous, true|false}
这个房间是匿名的: 房客看不到其他房客的真实JIDs. 注意房间主持人们总是看得见房客的真实JIDs.
{logging, false|true}
公开消息被使用mod_muc_log记录.
{max_users, 200}
房间里房客的最大数量.
{members_by_default, true|false}
进入房间的房客缺省成为参与者, 所以他们有发言权 ’voice’.
{members_only, false|true}
只有房间成员可以进入.
{moderated, true|false}
只有拥有发言权 ’voice’的房客可以发送公开消息.
{password, "roompass123"}
房间密码. 你可能希望也激活下一个选项.
{password_protected, false|true}
要求密码才能进入房间.
{persistent, false|true}
即使最后一个房客离开,房间仍持久存在.
{public, true|false}
房间在MUC服务列表里是公开的, 所以它是可发现的.
{public_list, true|false}
参与者名单是公开的, 不需要进入房间就能拿到.
{title, "Room Title"}
一个自然语言的房间称谓.
所有房间选项能被设定为 true 或 false, 除了 password 和 title 是字符串, 以及 max_users 是整数.

例子:

  • 在第一个例子里,每个人都允许使用多用户聊天服务. 每个人也将能创建房间但只有用户admin@example.org被允许管理任何房间. 在这个例子里他也是一个全局的管理员. 当admin@example.org发送一个消息,例如‘Tomorrow, the XMPP server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.’ 给 conference.example.org, 这个消息将被显示在所有激活的房间里. 在这个例子里历史功能被禁止了.
      {acl, admin, {user, "admin", "example.org"}}.
 
      {access, muc_admin, [{allow, admin}]}.
 
      {modules,
       [
        ...
        {mod_muc, [{access, all},
                   {access_create, all},
                   {access_admin, muc_admin},
                   {history_size, 0}]},
        ...
       ]}.
  • 在第二个例子里多用户聊天服务只允许在我们的域和其他的服务器上注册了的付费客户访问. 当然管理员也是允许访问房间的. 而且, 他是唯一被授权可以建立并管理房间的. 当admin@example.org发送一个消息,例如‘Tomorrow, the Jabber server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.’ 给 conference.example.org, 它将被显示在所有激活的房间里. 没有使用 history_size 选项, 这意味着这个功能被激活但缺省值为20个历史消息,将被发送给用户们.
      {acl, paying_customers, {user, "customer1", "example.net"}}.
      {acl, paying_customers, {user, "customer2", "example.com"}}.
      {acl, paying_customers, {user, "customer3", "example.org"}}.
      {acl, admin, {user, "admin", "example.org"}}.
 
      {access, muc_admin, [{allow, admin},
                            {deny, all}]}.
      {access, muc_access, [{allow, paying_customers},
                            {allow, admin},
                            {deny, all}]}.
 
      {modules,
       [
        ...
        {mod_muc, [{access, muc_access},
                   {access_create, muc_admin},
                   {access_admin, muc_admin}]},
        ...
       ]}.
  • 在以下例子里, MUC使用了反滥用选项. 一个房客每0.4秒不能发送超过一个消息并且不能超过每4秒之内变更一次出席信息. Room IDs 和 Room Names 的长度被限制为 20 个字符, 而 Room Description 限制为 300 个字符. 没有定义 ACLs, 但一些用户限制可能被加入:
      {modules,
       [
        ...
        {mod_muc, [{min_message_interval, 0.4},
                   {min_presence_interval, 4},
                   {max_room_id, 20},
                   {max_room_name, 20},
                   {max_room_desc, 300}]},
        ...
       ]}.
  • 这个例子展示如何使用 default_room_options 来确保新建房间缺省拥有的选项.
      {modules,
       [
        ...
        {mod_muc, [{access, muc_access},
                   {access_create, muc_admin},
                   {default_room_options,
                    [
                     {allow_change_subj, false},
                     {allow_query_users, true},
                     {allow_private_messages, true},
                     {members_by_default, false},
                     {title, "New chatroom"},
                     {anonymous, false}
                    ]},
                   {access_admin, muc_admin}]},
        ...
       ]}.

mod_muc_log

本模块允许可选的把多用户聊天 (MUC)的公开谈话记录转为HTML. 一旦你激活了这个模块, 用户可以使用有MUC能力的XMPP客户端加入一个房间, 并且如果他们有足够的权限, 他们可以请求一个配置表单来设定配置并允许房间记录.

功能:

  • 每页顶端加上房间细节: room 称谓, JID, 作者, 标题以及配置.
  • 房间JID 在生成的HTML里是一个链接,可用来加入该房间(使用 XMPP URI).
  • 标题和房间配置变更会被跟踪和显示.
  • 加入, 离开, 修改昵称, 踢人, 拉黑名单和‘/me’被跟踪和显示, 包括原因(如果有).
  • 生成的 HTML 文件是 XHTML 1.0 Transitional 和 CSS 兼容的.
  • 时间戳是自参考的链接.
  • 快速浏览的链接在顶上: 前一天, 下一天, 上.
  • CSS被用于style定义, 可以使用一个自定义的 CSS 文件.
  • 消息和标题里的URLs被转换为超链接.
  • 时间戳上的时区被显示在记录文件里.
  • 可在每一个页的顶部增加一个自定义链接.

选项:

{access_log, AccessName}

这个选项限制哪个房客被允许激活和禁止房间记录. 缺省值为 muc_admin. 注意对于为了这个缺省设定生效,你需要有一个用于 muc_admin 的 access rule .

{cssfile, false|URL}

使用这个选项你可以设置是否该HTML文件应该使用一个自定义的CSS文件或他们需要使用嵌入的CSS文件. 被允许的值有 false 和一个指向某CSS文件的URL. 使用第一个值, HTML文件将包含一个嵌入的CSS代码. 使用后一个, 你可以指定自定义CSS文件的URL (例如: "http://example.com/my.css"). 缺省的值是 false.

{dirname, room_jid|room_name}

允许配置房间目录的名字. 被允许的值有 room_jid 和 room_name. 使用前者的值, 房间目录名将是完整的房间JID. 使用后者, 房间目录名将只是房间的名字, 不包括 MUC服务名. 缺省值是room_jid.

{dirtype, subdirs|plain}

新建目录的类型可使用此选项指定. 允许的值有 subdirs 和 plain. 使用前者, 子目录以每年和月新建. 使用后者, 记录文件名包含完整的日期, 并且没有子目录. 缺省值是 subdirs.

{file_format, html|plaintext}

定义日志文件的格式: html 存储成HTML格式, plaintext 存储成纯文本. 缺省值为 html.

{outdir, Path}

这个选项是应该被存储的HTML文件的目录的全路径. 确保ejabberd守候进程对那个目录有写权限. 缺省值为 "www/muc".

{spam_prevention true|false}

为了阻止垃圾, spam_prevention 选项增加了一个特别的属性给链接来阻止它们通过搜索引擎来索引. 缺省值为 true, 它意味着 nofollow 属性将被加到用户提交的链接里.

{timezone, local|universal}

记录的时区可使用本选项配置. 允许的值有 local 和 universal. 使用前者, 将使用Erlang通过操作系统获得的本地时间. 使用后者, 将使用GMT/UTC 时间. 缺省值为 local.

{top_link, {URL, Text}}

使用本选项你可以定制化每个日志文件的右上角的链接. 缺省值是 {"/", "Home"}.

例子:

  • 在第一个例子里,任何房间所有者能激活记录, 并将使用一个自定义的CSS文件 (http://example.com/my.css). 记录文件的名字将包含完整日期, 并且将没有子目录. 记录文件将被存储在 /var/www/muclogs, 且时区将是GMT/UTC. 最后, 顶端链接将是 <a href="http://www.jabber.ru/">Jabber.ru</a>.
      {access, muc, [{allow, all}]}.
 
      {modules,
       [
        ...
        {mod_muc_log, [
                       {access_log, muc},
                       {cssfile, "http://example.com/my.css"},
                       {dirtype, plain},
                       {dirname, room_jid},
                       {outdir, "/var/www/muclogs"},
                       {timezone, universal},
                       {spam_prevention, true},
                       {top_link, {"http://www.jabber.ru/", "Jabber.ru"}}
                      ]},
        ...
       ]}.
  • 在第二个例子里只有admin1@example.org和admin2@example.net可以激活记录, 并且将使用嵌入的CSS文件. 记录名将只包含日期(数字), 且每年和月将有子目录. 这个记录文件将被存储在 /var/www/muclogs, 且将使用本地时间. 最后, 顶端链接将是缺省的 <a href="/">Home</a>.
      {acl, admins, {user, "admin1", "example.org"}}.
      {acl, admins, {user, "admin2", "example.net"}}.
 
      {access, muc_log, [{allow, admins},
                         {deny, all}]}.
 
      {modules,
       [
        ...
        {mod_muc_log, [
                       {access_log, muc_log},
                       {cssfile, false},
                       {dirtype, subdirs},
                       {outdir, "/var/www/muclogs"},
                       {timezone, local}
                      ]},
        ...
       ]}.

mod_offline

本模块实现离线消息存储 (XEP-0160). 这意味着所有被发送给一个离线用户的消息将被存储在服务器上直到那个用户再次上线. 所以它非常类似邮件的工作. 注意 ejabberdctl 有一个命令删除过期的消息 (见 4.1 节).

{access_max_user_messages, AccessName}

这个选项定义哪个 access rule 将被强迫用来限制一个用户所拥有的离线消息的最大数量(配额). 当一个用户有太多离线消息, 任何收到的新消息将被抛弃, 并且将返回一个 资源约束 错误给发送者. 缺省值为 max_user_offline_messages. 接着你可以用类似max_user_sessions的语法定义一个 access rule (见 3.1.5 节).

这个例子允许强力用户拥有大到 5000 个离线消息, 管理员达到 2000, 所有其他用户达到 100.

{acl, admin, {user, "admin1", "localhost"}}.
{acl, admin, {user, "admin2", "example.org"}}.
{acl, poweruser, {user, "bob", "example.org"}}.
{acl, poweruser, {user, "jane", "example.org"}}.
 
{access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}.
 
{modules,
 [
  ...
  {mod_offline,  [ {access_max_user_messages, max_user_offline_messages} ]},
  ...
 ]}.

mod_ping

这个模块实现对XMPP Ping (XEP-0199) 和 定期保持连接 的支持. 当本模块激活时,ejabberd正确应答 ping 请求, 如协议所述.

配置选项:

{send_pings, true|false}

如果这个选项设为 true, 服务器在一个给定的间隔时间 ping_interval发送 pings 给已连接的不活跃的客户端. 这对于保持活着的客户端连接或检查可用性是有用的. 缺省这个选项是禁止的.

{ping_interval, Seconds}

多久发送一次 ping 给已连接的用户, 如果前一个选项被激活. 如果一个客户端连接在这个间隔内没有发送或接收任何节, 一个 ping 请求被发送给客户端. 缺省值为60秒.

{timeout_action, none|kill}

当一个客户端在32秒内不回答一个服务器的ping请求时,服务器做什么. 缺省是什么也不做.

这个例子激活了 Ping 应答, 配置该模块发送 pings 给4分钟内不活跃的客户端连接, 并且如果一个客户端在32秒内不回答 ping , 它的连接将被关闭:

{modules,
 [
  ...
  {mod_ping,  [{send_pings, true}, {ping_interval, 240}, {timeout_action, kill}]},
  ...
 ]}.

mod_privacy

本模块实现定义于XMPP IM第十章的禁止通讯 (也被称为隐私规则) . 如果最终用户在他们的XMPP客户端也支持它, 他们将能够:

  • 收到某人的隐私列表privacy lists.
  • 增加, 删除, 和修改某人的隐私列表privacy lists.
  • 设置, 修改, 或减少激活的列表active lists.
  • 设置, 修改, 或减少缺省列表default list (即, 缺省那个列表是激活的).
  • 允许或禁止消息,基于JID, group, 或 订阅类型subscription type (或全局的).
  • 允许或禁止入站的出席信息通知,基于JID, group, 或 订阅类型subscription type (或全局的).
  • 允许或禁止出站的出席信息通知,基于JID, group, 或 订阅类型subscription type (或全局的).
  • 允许或禁止IQ节,基于JID, group, 或 订阅类型subscription type (或全局的).
  • 允许或禁止所有通讯,基于JID, group, 或 订阅类型subscription type (或全局的).
(从 http://xmpp.org/rfcs/rfc3921.html#privacy)

选项:

{iqdisc, Discipline}

这为禁止通讯(jabber:iq:privacy) IQ queries (见 3.3.2 节)定义处理原则 .

mod_private

本模块增加对私有XML存储(XEP-0049)的支持:

使用这个方法, XMPP实体能存储私有数据到服务器并在任何必要的时候获得它. 存储的数据可以是任何东西, 只要它是合法的XML. 对这个namespace的一个典型的用法是服务器端存储特定客户端的配置; 另一个是标签存储(XEP-0048).

选项:

{iqdisc, Discipline}

这为私有XML存储 (jabber:iq:private) IQ queries 定义处理原则(见 3.3.2).

mod_proxy65

本模块实现SOCKS5字节流(XEP-0065). 它允许把ejabberd当作一个在两个XMPP客户端之间的文件传输代理. 选项:

{host, HostName}

这个选项定义该服务的Jabber ID. 如果 host 选项没指定, Jabber ID将是该虚拟主机的hostname加上前缀‘proxy.’. 关键字 "@HOST@" 在启动时被替换为真实的虚拟主机名.

{name, Text}

定义服务的服务发现名称. 缺省是 "SOCKS5 Bytestreams".

{ip, IPTuple}

这个选项定义监听哪个网络接口. 缺省是该服务的DNS名解析到的一个IP地址, 或, 如果失败, 则是{127,0,0,1}.

{port, Number}

这个选项定义监听链入连接的端口. 缺省是 7777.

{hostname, HostName}

定义一个在建立和客户端的会话时服务声明的hostname. 当你在一个NAT后面运行这个服务的时候这是有用的. 缺省是 ip 选项的值. 例如: "proxy.mydomain.org", "200.150.100.50". 注意在流协商的时候不是所有客户端都懂得域名, 所以在这个选项设定域名时你应该思考两次.

{auth_type, anonymous|plain}

SOCKS5验证类型. 可能的值有 anonymous 和 plain. 缺省是 anonymous.

{access, AccessName}

为文件传输发起者定义 ACL. 缺省是 all.

{max_connections, Number}

每个文件传输的发起者的激活连接的最大数. 缺省不限制.

{shaper, none|ShaperName}

这个选项为文件传输端定义塑性shaper. 有最大带宽的Shaper将被选择. 缺省是 none.

例子:

  • 本模块最简单的配置:
      {modules,
       [
        ...
        {mod_proxy65, []},
        ...
       ]}.
  • 更复杂的配置.
      {acl, proxy_users, {server, "example.org"}}.
      {access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
 
      {acl, admin, {user, "admin", "example.org"}}.
      {shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
      {access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
 
      {modules,
       [
        ...
        {mod_proxy65, [{host, "proxy1.example.org"},
                       {name, "File Transfer Proxy"},
                       {ip, {200,150,100,1}},
                       {port, 7778},
                       {max_connections, 5},
                       {access, proxy65_access},
                       {shaper, proxy65_shaper}]},
        ...
       ]}.

mod_pubsub

本模块提供一个发行-订阅 服务 (XEP-0060). 在mod_pubsub里,功能可以使用插件来扩展. 实现PEP (基于Pubsub的个人信息事件) (XEP-0163) 的plugin, 在缺省的 ejabberd 配置文件中是被允许的, 并且它需要 mod_caps.

选项:

{host, HostName}

这个选项定义了该服务的Jabber ID. 如果 host 选项没定义, Jabber ID将是该虚拟主机的hostname加上前缀‘pubsub.’. 关键字 "@HOST@" 在启动时被替换成真实的虚拟主机名. 如果你使用了 mod_pubsub_odbc, 请确保前缀只包含一个点dot, 例如‘pubsub.’, 或 ‘publish.’,.

{access_createnode, AccessName}

这个选项使用 ACL 和 ACCESS来限制哪个用户被允许建立 pubsub 节点. 缺省本地ejabberd服务器的任何帐号被允许新建 pubsub 节点.

{max_items_node, MaxItems}

定义可被一个节点存储的条目的最大数量. 缺省值为 10.

{plugins, [ Plugin, ...]}

用于指定plugins使用哪个pubsub节点. 列表的第一个缺省被使用. 如果这个选项没定义, 缺省 plugins 列表为: ["flat"]. PubSub客户端能定义使用哪个plugin,当新建一个节点的时候: 增加 type=’plugin-name’ 属性到这个 create 节元素里.

{nodetree, Nodetree}

用于指定使用哪个节点树 nodetree. 如果没定义, 缺省使用 pubsub nodetree : "tree". 每个主机只能使用一个 nodetree , 且被所有节点 plugins 共享.
"virtual" nodetree 不把节点存储在数据库里. 它使用tons of nodes存储资源到系统. 如果使用 "virtual" nodetree, 你只能允许那些节点 plugins: ["flat","pep"] 或 ["flat"]; 任何其他 plugins 配置将不工作. 同时, 所有节点将有缺省配置, 并且不能被修改. 使用 "virtual" nodetree 需要从一个干净的数据库启动, 如果你之前使用了缺省的 "tree" nodetree,它将不工作.
"dag" nodetree 为 PubSub集合节点(XEP-0248)提供实验性的支持. 在那种情况下你也应该增加 "dag" 节点 plugin 作为缺省值, 例如: {plugins, ["dag","flat","hometree","pep"]}

{ignore_pep_from_offline, false|true}

用于指定是否我们应该获取当我们连接时在我们的名册里处于离线状态的联系人的PEP最后发行条目. 值有 true 或 false. 如果不定义, pubsub 假定为 true,所以我们只能获取在线联系人的最后条目.

{last_item_cache, false|true}

指定是否 pubsub 应该缓存最后条目. 值为 true 或 false. 如果没定义, pubsub不缓存最后条目. 在没有那么多节点的系统上, 缓存最后条目加速了 pubsub 并允许增加用户连接频率. 开销主要是内存使用, 因为每个条目都存储在内存里.

{pep_mapping, [ {Key, Value}, ...]}

这允许定义一个 键-值 列表来在给定 PEP 名字空间选择定义节点 plugins . 以下例子将为每个拥有 tune namespace的PEP节点使用 node_tune 替代 node_pep :
      {mod_pubsub, [{pep_mapping, [{"http://jabber.org/protocol/tune", "tune"}]}]}

配置例子使用 flat 节点作为缺省值, 并允许使用 flat, nodetree 和 pep 节点:

{modules,
 [
  ...
  {mod_pubsub, [
                {access_createnode, pubsub_createnode},
                {plugins, ["flat", "hometree", "pep"]}
               ]},
  ...
 ]}.

使用 ODBC 数据库要求使用重复的plugins. 以下例子展示前一个配置加上 ODBC 之后的用法:

{modules,
 [
  ...
  {mod_pubsub_odbc, [
                {access_createnode, pubsub_createnode},
                {plugins, ["flat_odbc", "hometree_odbc", "pep_odbc"]}
               ]},
  ...
 ]}.

mod_register

本模块增加对带内注册(XEP-0077)的支持. 这个协议允许最终用户使用XMPP客户端做:

  • 在服务器注册一个新帐号.
  • 在服务器上给一个现有帐号修改密码.
  • 删除一个服务器上的现有帐号.

选项:

{access, AccessName}

这个选项可被配置来指定限制注册的 rules. 如果一个 rule 在请求的用户名返回‘deny’, 那个用户名的注册被禁止. (缺省没有限制).

{access_from, AccessName}

缺省的, ejabberd不允许从s2s或已有的c2s会话注册一个新帐号. 你可以修改它,通过在这个选项定义 access rule. 谨慎使用: 允许从s2s注册会导致流氓用户的不可控的大量帐号注册.

{welcome_message, Message}

设定一个欢迎信息发送给每一个新注册的帐号. 第一个字符串是标题, 第二个字符串是消息 body. 在body里你可以用字符: \n 设定一个新行

{registration_watchers, [ JID, ...]}

这个选项定义一个 JIDs 列表,每次有人注册新帐号,他们将收到通知.

{iqdisc, Discipline}

这为带内注册(jabber:iq:register) IQ queries (见 3.3.2 节)定义处理原则.

这个模块也从服务器读取另一个全局定义的选项: {registration_timeout, Timeout}. 这个选项限制从一个给定IP或用户名发出的注册请求的频率. 所以, 一个用户在前一个注册之后,经过这个数量的秒数之前不能从相同IP地址或JID注册一个新帐号. Timeout被表示为秒数, 并且必须是一个整数. 要禁止此限制, 把整数替换成单词,类似: infinity. 缺省值为: 600 秒.

例子:

  • 下个例子禁止注册太短的帐号名 prohibits:
      {acl, shortname, {user_glob, "?"}}.
      {acl, shortname, {user_glob, "??"}}.
      %% The same using regexp:
      %%{acl, shortname, {user_regexp, "^..?$"}}.
 
      {access, register, [{deny, shortname},
                          {allow, all}]}.
 
      {modules,
       [
        ...
        {mod_register, [{access, register}]},
        ...
       ]}.
  • 这个配置禁止使用带内注册新建和删除帐号, 但允许现有帐号修改密码:
      {access, register, [{deny, all}]}.
 
      {modules,
       [
        ...
        {mod_register, [{access, register}]},
        ...
       ]}.
  • 这个配置禁止所有带内注册功能: 新建, 删除帐号和修改密码:
      {modules,
       [
        ...
        %% {mod_register, [{access, register}]},
        ...
       ]}.
  • 定义一个欢迎信息和两个注册观察者. 也定义一个注册超时为一小时:
      {registration_timeout, 3600}.
      {modules,
       [
        ...
        {mod_register,
         [
          {welcome_message, {"Welcome!", "Hi.\nWelcome to this Jabber server.\n Check http://www.jabber.org\n\nBye"}},
          {registration_watchers, ["admin1@example.org", "boss@example.net"]}
         ]},
        ...
       ]}.

mod_roster

本模块实现名册管理,定义于 RFC 3921: XMPP IM. 也支持 名册版本 (XEP-0237).

选项:

{iqdisc, Discipline}

这为名册管理 (jabber:iq:roster) IQ queries (see section [Ejabberd2:安装和操作指南[#iqdisc|3.3.2]] 节) 指定处理原则.

{versioning, false|true}

激活名册版本. 这个选项缺省是禁止的.

{store_current_id, false|true}

如果激活这个选项, 当前版本数量被存储在数据库. 如果被禁止, 版本数量在每次飞行计算. 激活这个选项同时减少ejabberd和数据库的负载. 任何情况下这个选项不影响客户端. 该选项只是当允许名册版本时有用. 该选项缺省是被禁止的. 重要: 如果你使用 mod_shared_roster, 你必须禁止这个选项.

这个示例配置允许使用当前id存储的名册版本:

{modules,
 [
  ...
  {mod_roster, [{versioning, true}, {store_current_id, true}]},
  ...
 ]}.

mod_service_log

本模块通过一个XMPP消息审计服务,例如Bandersnatch,增加了对最终用户的包进行记录的支持. 所有用户包被封装在一个 <route/> 元素里并发送给一个特定服务(们).

选项:

{loggers, [Names, ...]}

使用这个选项可以指定将接收包的一个 (列表之一) 服务(们).

例子s:

  • 这是把所有的用户包记录到运行在bandersnatch.example.com的Bandersnatch 服务,:
      {modules,
       [
        ...
        {mod_service_log, [{loggers, ["bandersnatch.example.com"]}]},
        ...
       ]}.
  • 这是把所有最终用户的包记录到运行在bandersnatch.example.com的Bandersnatch服务以及运行在bandersnatch.example.org的备份服务上:
      {modules,
       [
        ...
        {mod_service_log, [{loggers, ["bandersnatch.example.com",
                                      "bandersnatch.example.org"]}]},
        ...
       ]}.

mod_shared_roster

本模块允许你新建共享名册组. 这意味着你可以新建人员组,组里的成员从他们的名册里的其他组也可以看到成员. 这个功能的最大好处是最终用户不需要手工添加所有用户到他们的名册, 并且他们不能永久性地从共享名册组删除用户. 一个共享名册组可拥有来自任何XMPP服务器的成员, 但是出席信息from和to将只在创建该组的相同的虚拟主机的成员之间可用.

共享名册组只可以通过Web管理编辑. 每个组有唯一标识符和以下参数:

Name

组名, 它将被显示在名册里.

Description

组描述. 这个参数不影响任何东西.

Members

组成员的完整JIDs列表, 在Web管理 里面每行一个. 为了把虚拟主机上的所有注册用户设为成员, 你可以使用特殊的参数: @all@. 注意这个参数被设计用于一个只有几百用户的小服务器.

Displayed groups

那些成员将出现在名册上的组的列表.

例子:

  • 假设一个计算机俱乐部希望它的所有成员在他们的名册里看到所有其他成员. 为了达到这点, 他们需要建立一个共享名册组类似下表:
Identification Group ‘club_members’
Name 俱乐部成员
Description 来自计算机俱乐部的成员
Members
member1@example.org
member2@example.org
member3@example.org
Displayed groups club_members
  • 在另一个情况下,我们有一个公司,它有三个部门: 管理部, 市场部和销售部. 所有组成员应该在他们的名册里看到其他成员. 另外, 所有经理应该在他们的名册里有所有市场部和销售部的人. 同时, 所有市场人员和全部销售队伍应该看到所有经理. 这个场景可由新建以下共享名册组来达到,如下表所示:
Identification Group ‘management’ Group ‘marketing’ Group ‘sales’
Name 管理部 市场部 销售部
Description
Members
manager1@example.org
manager2@example.org
manager3@example.org
manager4@example.org
marketeer1@example.org
marketeer2@example.org
marketeer3@example.org
marketeer4@example.org
saleswoman1@example.org
salesman1@example.org
saleswoman2@example.org
alesman2@example.org
Displayed groups
管理
市场
销售
管理
市场
管理
销售

mod_sic

本模块增加了对服务器IP检查 (XEP-0279)的支持. 这个协议允许客户端发现它的外部IP地址.

选项:

{iqdisc, Discipline}

这为urn:xmpp:sic:0 IQ queries (见 3.3.2 节)定义了处理原则 .

mod_stats

This module adds support for Statistics Gathering (XEP-0039). This protocol allows you to retrieve next statistics from your ejabberd deployment:

  • Total number of registered users on the current virtual host (users/total).
  • Total number of registered users on all virtual hosts (users/all-hosts/total).
  • Total number of online users on the current virtual host (users/online).
  • Total number of online users on all virtual hosts (users/all-hosts/online).

选项:

{iqdisc, Discipline}

这为统计信息收集 (http://jabber.org/protocol/stats) IQ queries (见 3.3.2 节) 定义了处理原则.

因为只有少量的客户端 (例如 Tkabber) 和软件库支持这个 XEP, 一些例子以 XML 方式给出 ,为了获得统计信息,你需要发送它. 它们是:

  • 你可以请求当前虚拟主机 (example.org)的在线用户数量:
      <iq to='example.org' type='get'>
        <query xmlns='http://jabber.org/protocol/stats'>
          <stat name='users/online'/>
        </query>
      </iq>
  • 你可以请求所有虚拟主机上注册用户的总数量:
      <iq to='example.org' type='get'>
        <query xmlns='http://jabber.org/protocol/stats'>
          <stat name='users/all-hosts/total'/>
        </query>
      </iq>

mod_time

本模块功能支持实体时间 (XEP-0202). 通过使用这个 XEP, 你能发现另一个实体所在位置的时间.

选项:

{iqdisc, Discipline}

这为实体时间 (jabber:iq:time) IQ queries (见 3.3.2 节)定义了处理原则 .

mod_vcard

本模块允许最终用户存储和接收他们的电子名片vCard, 以及接收别的用户的电子名片vCards, 定义于 vcard-temp (XEP-0054). 这个模块也实现了一个基于这些用户的vCards的简单的Jabber用户目录. 进一步的, 当收到请求时它允许服务器发送它自己的名片vCard.

选项:

{host, HostName}

这个选项定义该服务的Jabber ID. 如果 host 选项没定义, Jabber ID将是该虚拟主机的hostname加前缀‘vjud.’. 关键字 "@HOST@" 在启动时被替换成真实的虚拟主机名.

{iqdisc, Discipline}

这为vcard-temp IQ queries (见 3.3.2 节)定义了处理原则 .

{search, true|false}

这个选项定义是否允许搜索功能,如果禁止,选项 host 将被忽略,并且 Jabber用户目录服务将不出现在服务发现条目列表里. 缺省值为true.

{matches, infinity|Number}

使用这个选项, 搜索结果的数量将被限制. 如果这下选项的值设为 infinity, 所有搜索结果被汇报. 缺省值为 30.

{allow_return_all, false|true}

这个选项允许你指定是否输入字段为空来进行搜索操作应该返回所有已在他们的vCard中加入信息的用户. 缺省值为 false.

{search_all_hosts, true|false}

如果这个选项设为 true, 搜索操作将应用于所有虚拟主机. 反之只有当前主机将被搜索. 缺省值为 true. 这个选项在 mod_vcard 是可用的, 但是在 mod_vcard_odbc 是不可用的.

例子:

  • 在第一种情况下, 搜索结果被限制为20个条目, 当人们做空的搜索时,每个添加了信息到他们的vCard的用户将被列出 , 并且只有当前主机的用户会被返回:
      {modules,
       [
        ...
        {mod_vcard, [{search, true},
                     {matches, 20},
                     {allow_return_all, true},
                     {search_all_hosts, false}]},
        ...
       ]}.
  • 第二种情况不同在于,搜索结果是不限制的, 并且所有虚拟主机将被搜索而不是只有当前主机:
      {modules,
       [
        ...
        {mod_vcard, [{search, true},
                     {matches, infinity},
                     {allow_return_all, true}]},
        ...
       ]}.

mod_vcard_ldap

ejabberd能映射LDAP属性到vCard字段. 这个行为在 mod_vcard_ldap 模块实现. 本模块不依赖于验证方法 (见 3.2.5 节).

经常的 ejabberd 对待 LDAP 像一个只读存储器: 它可能查看数据, 但是不能新建帐号或编辑存储在LDAP里的 vCard. 无论如何, 修改密码是可能的,如果 mod_register 模块激活了并且 LDAP 服务器支持 RFC 3062.

mod_vcard_ldap模块有它自己的可选参数. 第一组参数和设定验证方法时的顶极LDAP参数含义相同: ldap_servers, ldap_port, ldap_rootdn, ldap_password, ldap_base, ldap_uids, and ldap_filter. 见 3.2.5 节查看关于这些选项的详细信息. 如果这些选项中的一个没有设置, ejabberd将以相同哦功能名字查找顶极选项.

第二组参数包括以下的 mod_vcard_ldap-专有 选项:

{host, HostName}

这个选项定义该服务的Jabber ID. 如果 host 选项没定义, Jabber ID将是该虚拟主机的hostname加上前缀‘vjud.’. 关键字 "@HOST@" 在启动时被替换成真实的虚拟主机名.

{iqdisc, Discipline}

这为 vcard-temp IQ queries (见 3.3.2 节)定义了处理原则 .

{search, true|false}

这个选项指定是否搜索功能被允许(值: true) 或禁止(值: false). 如果禁止, 选项 host 将被忽略,并且Jabber用户目录服务将不出现在服务发现条目列表里. 缺省值为 true.

{matches, infinity|Number}

使用这个选项, 搜索结果的数量被限制. 如果该选项值设为 infinity, 所有结果被汇报. 缺省值为 30.

{ldap_vcard_map, [ {Name, Pattern, LDAPattributes}, ...]}

使用此选项,你可以设置一个表,映射LDAP属性到vCard字段. Name是 vCard 的类型名,定义于 RFC 2426. Pattern是一个字符串,包含 pattern 变量 "%u", "%d" 或 "%s". LDAPattributes 是包含LDAP属性的列表. pattern变量 "%s" 将被从 List_of_LDAP_attributes顺序替换成 LDAP 属性值, "%u" 将被替换成一个JID的user部分, 而"%d" 将被替换成一个JID的domain部分. 缺省为:
    [{"NICKNAME", "%u", []},
     {"FN", "%s", ["displayName"]},
     {"LAST", "%s", ["sn"]},
     {"FIRST", "%s", ["givenName"]},
     {"MIDDLE", "%s", ["initials"]},
     {"ORGNAME", "%s", ["o"]},
     {"ORGUNIT", "%s", ["ou"]},
     {"CTRY", "%s", ["c"]},
     {"LOCALITY", "%s", ["l"]},
     {"STREET", "%s", ["street"]},
     {"REGION", "%s", ["st"]},
     {"PCODE", "%s", ["postalCode"]},
     {"TITLE", "%s", ["title"]},
     {"URL", "%s", ["labeleduri"]},
     {"DESC", "%s", ["description"]},
     {"TEL", "%s", ["telephoneNumber"]},
     {"EMAIL", "%s", ["mail"]},
     {"BDAY", "%s", ["birthDay"]},
     {"ROLE", "%s", ["employeeType"]},
     {"PHOTO", "%s", ["jpegPhoto"]}]

{ldap_search_fields, [ {Name, Attribute}, ...]}

这个选项定义搜索表单和参与搜索的LDAP属性. Name 是搜索表单字段的名字,它将使用翻译文件自动翻译 (查看 msgs/*.msg 找寻可用的单词). Attribute 是LDAP属性或 pattern "%u". 缺省值是:
    [{"User", "%u"},
     {"Full Name", "displayName"},
     {"Given Name", "givenName"},
     {"Middle Name", "initials"},
     {"Family Name", "sn"},
     {"Nickname", "%u"},
     {"Birthday", "birthDay"},
     {"Country", "c"},
     {"City", "l"},
     {"Email", "mail"},
     {"Organization Name", "o"},
     {"Organization Unit", "ou"}]

{ldap_search_reported, [ {SearchField, VcardField}, ...]}

这个选项定义哪个搜索字段应该汇报. SearchField 是一个搜索表单的字段名,它将使用翻译文件自动翻译 (去 msgs/*.msg 查看可用的单词). VcardField 是vCard 字段名,定义于 ldap_vcard_map 选项. 缺省为:
    [{"Full Name", "FN"},
     {"Given Name", "FIRST"},
     {"Middle Name", "MIDDLE"},
     {"Family Name", "LAST"},
     {"Nickname", "NICKNAME"},
     {"Birthday", "BDAY"},
     {"Country", "CTRY"},
     {"City", "LOCALITY"},
     {"Email", "EMAIL"},
     {"Organization Name", "ORGNAME"},
     {"Organization Unit", "ORGUNIT"}]

例子:

  • 假设 ldap.example.org 是我们的一个LDAP服务器的名字. 我们有用户,他们的密码在 "ou=Users,dc=example,dc=org" 目录. 同时我们也有地址簿 addressbook, 它包含用户的 emails 和他们的其他信息, 在 "ou=AddressBook,dc=example,dc=org" 目录. 相应的验证节应该看起来是这样:
      %% 验证方法
      {auth_method, ldap}.
      %% 我们的LDAP服务器的DNS名
      {ldap_servers, ["ldap.example.org"]}.
      %% 我们想授权的用户仅为 'shadowAccount' object class
      {ldap_filter, "(objectClass=shadowAccount)"}.
现在我们想使用用户的 LDAP-信息 作为他们的 vCards. 我们在我们的 LDAP schema定义了四个属性
"mail" — emai地址, "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
            {"FIRST", "%s", ["givenName"]},
            {"LAST", "%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搜索用户的信息之前会先检查用户是否存在.
  • ldap_vcard_map 例子:
      {ldap_vcard_map,
       [{"NICKNAME", "%u", []},
        {"FN", "%s", ["displayName"]},
        {"CTRY", "Russia", []},
        {"EMAIL", "%u@%d", []},
        {"DESC", "%s\n%s", ["title", "description"]}
       ]},
  • ldap_search_fields 例子:
      {ldap_search_fields,
       [{"User", "uid"},
        {"Full Name", "displayName"},
        {"Email", "mail"}
       ]},
  • ldap_search_reported 例子:
      {ldap_search_reported,
       [{"Full Name", "FN"},
        {"Email", "EMAIL"},
        {"Birthday", "BDAY"},
        {"Nickname", "NICKNAME"}
       ]},

mod_vcard_xupdate

用户的客户端能在该用户的vCard存储一个头像. 基于vCard的头像 协议 (XEP-0153) 提供了一个方法给客户端来通知联系人他的头像的哈希值. 然而, 简单或小的客户端可能没有实现那个协议.

如果本模块被激活, 所有出站的客户端出席信息节代替客户端自动获得头像哈希值. 所以, 联系人收到这个带有更新数据的出席信息节(见 XEP-0153),就好像客户端自己把它插入进去的一样. 如果客户端已经在出席信息节里包含了这样的元素, 它被替换成 ejabberd 生成的元素.

通过激活本模块, 每次 vCard 修改就重新进行一次哈希值计算, 每个由客户端发送的出席信息导致一次哈希值接收,以及一次出席信息节的重写. 因此, 激活本模块将在服务器发生一些计算开销,如果客户端频繁修改他们的出席信息的话.

mod_version

本模块实现软件版本(XEP-0092). 所以, 当被查询时它应答 ejabberd 的版本.

选项:

{show_os, true|false}

是否应该显示操作系统. 缺省值是 true.

{iqdisc, Discipline}

这为软件版本(jabber:iq:version) IQ queries (见 3.3.2 节)定义了处理原则 .

管理ejabberd服务器

ejabberdctl

使用ejabberdctl命令行管理脚本,你可以执行ejabberdctl命令(详见下一节, 4.1.1) 和一些普通的 ejabberd 命令 (详见 [[4.2). 这意味着你可以在一个本地或远程ejabberd服务器(通过提供参数 --node NODENAME)上启动,停止以及执行一些其他的管理任务.

ejabberdctl脚本可在文件 ejabberdctl.cfg 里配置. 这个文件包含每个可配置的选项的详细的信息. 见 4.1.2 节.

ejabberdctl脚本返回数字状态码. 成功显示为 0, 错误显示为 1, 其它码可被用于特定结果. 这可以由其他脚本使用,来自动决定一个命令是否成功, 例如使用: echo $?

ejabberdctl命令

不带任何参数执行 ejabberdctl时, 它显示可用的选项. 如果没有一个 ejabberd 服务器在运行, 可用的参数是:

start

以后台模式启动ejabberd. 这是缺省方法.

debug

连接一个 Erlang shell 到一个已存在的 ejabberd 服务器. 这允许在ejabberd服务器上执行交互命令.

live

以live模式启动 ejabberd: shell 保持连接到已启动的服务器, 显示日志信息并允许执行交互命令.

如果已经有一个ejabberd服务器在系统里运行, ejabberdctl 展示以下 ejabberdctl 命令以及那台服务器上所有可用的 ejabberd 命令 (见 4.2.1 节).

ejabberdctl命令如下:

help

获得关于ejabberdctl或任何可用的命令的帮助. 试下 ejabberdctl help help.

status

检查ejabberd服务器的状态.

stop

停止ejabberd服务器.

restart

重启ejabberd服务器.

mnesia

获得关于Mnesia数据库的信息.

ejabberdctl脚本可被限制为需要验证并执行一些 ejabberd命令; 见 4.2.2 节. 增加这个选项到文件 ejabberd.cfg. 在这个例子没有限制:

{ejabberdctl_access_commands, []}.

如果账号 robot1@example.org 被注册到 ejabberd ,以密码 abcdef (使用 MD5 为 E8B501798950FC58AAD83C8C14978E), 并且 ejabberd.cfg 包含以下设定:

{hosts, ["example.org"]}.
{acl, bots, {user, "robot1", "example.org"}}.
{access, ctlaccess, [{allow, bots}]}.
{ejabberdctl_access_commands, [ {ctlaccess, [registered_users, register], []} ]}.

那么你可以在 shell 里做这个:

$ ejabberdctl registered_users example.org
Error: no_auth_provided
$ ejabberdctl --auth robot1 example.org E8B501798950FC58AAD83C8C14978E registered_users example.org
robot1
testuser1
testuser2

Erlang运行时系统

ejabberd是一个 Erlang/OTP 应用,运行在一个Erlang运行时系统内部. 这个系统是用环境变量和命令行参数来配置的. ejabberdctl管理脚本可能会使用其中的一些. 你可以在ejabberdctl.cfg文件里配置其中的一部分, 里面已包含了关于它们的详细描述. 本节描述所有环境变量和命令行参数的参考.

环境变量:

EJABBERD_CONFIG_PATH

ejabberd配置文件的路径.

EJABBERD_MSGS_PATH

翻译字符串的目录路径.

EJABBERD_LOG_PATH

ejabberd服务日志文件的路径.

EJABBERD_SO_PATH

二进制系统库的目录路径.

EJABBERD_DOC_PATH

ejabberd文档的目录路径.

EJABBERD_PID_PATH

ejabberd启动时建立的PID文件的路径.

HOME

ejabberd的家Home目录的路径. 这个路径用于读取文件 .erlang.cookie.

ERL_CRASH_DUMP

崩溃报告dump文件的路径.

ERL_INETRC

指示使用名字解析的哪个IP. 如果使用 -sname, 要么指定这个选项,要么指定 -kernel inetrc filepath.

ERL_MAX_PORTS

并发开放的Erlang端口的最大数量.

ERL_MAX_ETS_TABLES

ETS和Mnesia表的最大数量.

命令行参数:

-sname ejabberd

这个Erlang节点将只使用主机名的第一部分来指定, 即,本域之外的其他Erlang节点不能够联系联络这个节点. 在大多数情况下这是可取的.

-name ejabberd

这个Erlang节点将被完全指定. 这只在如果你计划在不同的网络配置一个ejabberd集群时有用.

-kernel inetrc ’"/etc/ejabberd/inetrc"’

指出使用名字解析的哪个IP. 如果使用 -sname, 要么指定这个选项,要么指定 ERL_INETRC.

-kernel inet_dist_listen_min 4200 inet_dist_listen_min 4210

定义 epmd ( 5.2 节)可以监听的第一个和最后一个端口.

-detached

启动Erlang系统并从系统控制台分离. 运行守护进程和后台进程时有用.

-noinput

确保Erlang系统不尝试读任何输入. 运行守护进程和后台进程时有用.

-pa /var/lib/ejabberd/ebin

指定Erlang二进制文件(*.beam)所在目录.

-s ejabberd

告诉Erlang运行时系统启动ejabberd应用.

-mnesia dir ’"/var/lib/ejabberd/"’

指定Mnesia数据库目录.

-sasl sasl_error_logger {file, "/var/log/ejabberd/erlang.log"}

Erlang/OTP系统日志文件的路径. 这里SASL意味着 系统架构支持库“System Architecture Support Libraries” 而不是 简单验证和安全层 “Simple Authentication and Security Layer”.

+K [true|false]

内核轮询.

-smp [auto|enable|disable]

SMP(多CPU)支持.

+P 250000

Erlang进程的最大数量.

-remsh ejabberd@localhost

在一个远程Erlang节点打开一个Erlang shell.

-hidden

到其他节点的连接是隐藏的(没有公开发布). 结果是这个节点不被认为是集群的一部分. 当启动一个临时的ctl或debug节点的时候这是很重要的.

注意当使用shell脚本的时候一些字符需要逃逸, 例如 " 和 {}. 你可在Erlang手册页 (erl -man erl)找到其他选项.

ejabberd命令

一个ejabberd命令是一个通过名字指定的抽象函数, 在ejabberd_commands 服务里注册并有一个已定义的编号和出入和输出类型. 那些命令能被定义在任何Erlang模块并使用任何合法的前端执行.

ejabberd包含一个前端用来执行ejabberd命令: 脚本ejabberdctl. 其他可被安装以不同方式来执行ejabberd命令的已知的前端有: ejabberd_xmlrpc (XML-RPC 服务), mod_rest (HTTP POST 服务), mod_shcommands (ejabberd WebAdmin 页面).

ejabberd命令清单

ejabberd缺省包含了一些ejabberd命令. 当更多模块被安装, 在前端又会有新命令可以用.

获得可用命令和它们的帮助的最容易的方法, 是使用ejabberdctl脚本:

$ ejabberdctl help
Usage: ejabberdctl [--node nodename] [--auth user host password] command [options]
 
Available commands in this ejabberd node:
  backup file                  Store the database to backup file
  connected_users              List all established sessions
  connected_users_number       Get the number of established sessions
  ...

最多人感兴趣的是:

reopen_log

在日志文件改名之后重新打开它们. 如果在调用此命令之前旧文件没有被改名, 它们自动改名为 "*-old.log". 见 7.1 节.

backup ejabberd.backup

存储内部的 Mnesia 数据库到一个二进制备份文件.

restore ejabberd.backup

立刻从一个二进制文件恢复内部的 Mnesia 数据库. 如果你有一个很大的数据库,这将消耗很多内存, 所以最好使用 install_fallback.

install_fallback ejabberd.backup

安装成fallback的二进制备份文件: 它将在下一次ejabberd启动的时候被用于恢复数据库. 这意味着, 在运行这个命令之后, 你不得不重启 ejabberd. 这个命令比restore需要更少的内存.

dump ejabberd.dump

Dump内部的 Mnesia 数据库到一个文本文件 dump.

load ejabberd.dump

立刻从一个文本文件dump恢复. 这不建议用于大数据库, 因为它将消耗很多时间, 内存和cpu. 在那种情况下,它适合使用 backup 和 install_fallback.

import_piefxis, export_piefxis, export_piefxis_host

这些选项可被用于迁移帐户,使用 XEP-0227 格式的 XML文件 从/到 另外一个 Jabber/XMPP 服务器或转移一个虚拟主机的用户到另一个 ejabberd 安装环境. 也见于 ejabberd迁移工具.

import_file, import_dir

这些选项可被用于迁移使用jabberd1.4格式的XML文件的帐户, 从其他 Jabber/XMPP 服务器. 已经有 从其他软件迁移到ejabberd的教程.

delete_expired_messages

这个选项可被用于删除旧的离线消息. 当离线消息数量非常高的时候有用.

delete_old_messages days

删除指定天数之前的离线消息.

register user host password

在那个域以给定的密码注册一个帐号.

unregister user host

注销给定帐号.

以AccessCommands限制执行

前端可能被配置成限制访问特定的命令. 在那种情况下, 必须提供验证信息. 在每个前端,AccessCommands 选项被定义在不同的地方. 但是所有情况下这个选项的语法都是相同的:

AccessCommands = [ {Access, CommandNames, Arguments}, ...]
Access = atom()
CommandNames = all | [CommandName]
CommandName = atom()
Arguments = [ {ArgumentName, ArgumentValue}, ...]
ArgumentName = atom()
ArgumentValue = any()

缺省值是不定义任何限制: []. 当执行一个命令时提供验证信息, 为一个被允许执行相应命令的本地XMPP帐号的 Username, Hostname 和 Password . 这意味着这个帐号必须在本地ejabberd已经注册, 因为这个信息将被验证. 可能提供纯文本密码或它的 MD5 哈希值.

当定义了一个或多个访问限制,并且提供了验证信息, 每个限制被验证直到某人完全符合: 这个帐号和 Access rule匹配, 命令名字列于 CommandNames 之中, 并且提供的参数和Arguments不抵触.

以下例子用来理解这个语法, 让我们假设那些选项:

{hosts, ["example.org"]}.
{acl, bots, {user, "robot1", "example.org"}}.
{access, commaccess, [{allow, bots}]}.

访问限制的列表只允许 robot1@example.org 执行所有命令:

[{commaccess, all, []}]

看看另一个限制列表 (相应的 ACL 和 ACCESS 没有显式):

[
 %% 这个 bot 能执行所有命令:
 {bot, all, []},
 %% 这个 bot 只能执行命令 'dump'. 不限制参数:
 {bot_backups, [dump], []}
 %% 这个 bot 可执行所有命令,
 %% 但是如果使用 'host' 参数, 它必须是 "example.org":
 {bot_all_example, all, [{host, "example.org"}]},
 %% 这个 bot 只能执行命令 'register',
 %% 并且如果使用参数 'host' , 它必须是 "example.org":
 {bot_reg_example, [register], [{host, "example.org"}]},
 %% 这个 bot 能执行命令 'register' 和 'unregister',
 %% 如果使用参数 host , 它必须是 "test.org":
 {_bot_reg_test, [register, unregister], [{host, "test.org"}]}
]

Web管理

ejabberd Web管理允许使用web浏览器管理大部分ejabberd.

这个功能缺省是激活的: 一个使用选项 web_admin (见 3.1.3 节)的 ejabberd_http 监听者被包含在监听的端口里. 然后你可以在你中意的wen浏览器里打开 http://server:port/admin/ . 你将被要求键入一个拥有管理员权限的ejabberd用户的 username (全 Jabber ID) 和 password . 在验证之后你将看到一个页面类似 figure 4.1.

webadmmain.png
Figure 4.1: Top page from the Web Admin

这里你可以编辑访问限制, 管理用户, 建立备份, 管理数据库, 允许/禁止 监听的端口, 查看服务器统计数据,…

access rule 配置决定那些帐号可以访问Web管理以及修改它. access rule webadmin_view 仅被赋予查看权限: 那些帐号能以只读方式浏览Web管理.

示例配置:

  • 你可以把Web管理伺服于和HTTP 轮询界面相同的端口. 在这个了例子里你应该把你的web浏览器指向 http://example.org:5280/admin/ 来管理所有虚拟主机或指向 http://example.org:5280/admin/server/example.com/ 来管理虚拟主机 example.com. 在你访问Web管理之前你需要键入从一个被允许配置ejabberd的已注册的用户那里得到的 username, JID 和 password . 在这个例子里你可键入 username ‘admin@example.net’ 来管理所有虚拟主机 (第一个 URL). 如果你以‘admin@example.com’登录到http://example.org:5280/admin/server/example.com/ ,你只能管理虚拟主机 example.com. 帐号‘reviewer@example.com’可以只读模式浏览虚拟主机.
      {acl, admins, {user, "admin", "example.net"}}.
      {host_config, "example.com", [{acl, admins, {user, "admin", "example.com"}}]}.
      {host_config, "example.com", [{acl, viewers, {user, "reviewer", "example.com"}}]}.
 
      {access, configure, [{allow, admins}]}.
      {access, webadmin_view, [{allow, viewers}]}.
 
      {hosts, ["example.org"]}.
 
      {listen,
       [
        ...
        {5280, ejabberd_http, [http_poll, web_admin]},
        ...
       ]}.
  • 因为安全的原因, 你可以在一个安全的连接上伺服Web管理, 在一个不同于HTTP轮询接口的端口上, 并把它绑定到内部的局域网IP. 这个Web管理将只能被浏览器从https://192.168.1.1:5282/admin/ 访问:
      {hosts, ["example.org"]}.
 
      {listen,
       [
        ...
        {5280, ejabberd_http, [
                               http_poll
                              ]},
        {{5282, "192.168.1.1"}, ejabberd_http, [
                                                web_admin,
                                                tls, {certfile, "/usr/local/etc/server.pem"}
                                               ]},
        ...
       ]}.

在ejabberd Web管理 特定的页面包含了一个连接到 ejabberd安装和操作指南 的相关章节. 为了显式这些链接, 本指南的一个 HTML 格式的拷贝必须安装在该系统上. 该文件缺省的放在 "/share/doc/ejabberd/guide.html". 该文档的目录可以被环境变量 EJABBERD_DOC_PATH 指定. 参见 4.1.2 节.

特设命令

如果你激活了 mod_configure 和 mod_adhoc, 你可以使用一个 XMPP 客户端在 ejabberd执行很多管理任务. 该客户端必须支持 Ad-Hoc Commands (XEP-0050), 而你必须以一个拥有适当权限的帐号登录到该 XMPP 服务器.

修改计算机主机名

ejabberd使用分布式的 Mnesia 数据库. 作为分布式数据库, Mnesia 强制它的文件一致性, 所以它在它里面存储Erlang节点名 (见 5.4 节). 一个Erlang节点的名字包含了该计算机的hostname. 所以, 如果你修改ejabberd运行的机器的名字,或当你移动ejabberd到一个不同的机器上,那么Erlang节点名也修改了.

你有两个办法在一个新节点名的 ejabberd 上使用旧的 Mnesia 数据库: 把旧节点名放入 ejabberdctl.cfg, 或转换数据库到为新节点名.

那些例子步骤将备份, 转换并装载 Mnesia 数据库. 你需要要么有旧的 Mnesia spool 目录,要么有一个 Mnesia 的备份. 如果你已经有一个旧的数据库的备份文件, 你可以直接去步骤 5. 你也需要知道旧节点名和新节点名. 如果你不知道它们, 执行ejabberdctl或在ejabberd 日志文件里查找它们.

在开始之前, 设置一些变量:

OLDNODE=ejabberd@oldmachine
NEWNODE=ejabberd@newmachine
OLDFILE=/tmp/old.backup
NEWFILE=/tmp/new.backup

1. 强制以旧节点名启动 ejabberd :

      ejabberdctl --node $OLDNODE start

2. 生成一个备份文件:

      ejabberdctl --node $OLDNODE backup $OLDFILE

3. 停止旧节点:

      ejabberdctl --node $OLDNODE stop

4. 确保在 Mnesia spool 目录没有文件 . 例如:

      mkdir /var/lib/ejabberd/oldfiles
      mv /var/lib/ejabberd/*.* /var/lib/ejabberd/oldfiles/

5. 启动 ejabberd. 不需要再指定任何节点名:

      ejabberdctl start

6. 转换备份到新节点名:

      ejabberdctl mnesia_change_nodename $OLDNODE $NEWNODE $OLDFILE $NEWFILE

7. 安装备份文件作为一个fallback:

      ejabberdctl install_fallback $NEWFILE

8. 停止 ejabberd:

      ejabberdctl stop
你可能在日志文件看到一个错误信息, 这是正常的, 不要担心:
      Mnesia(ejabberd@newmachine):
      ** ERROR ** (ignoring core)
      ** FATAL ** A fallback is installed and Mnesia must be restarted.
        Forcing shutdown after mnesia_down from ejabberd@newmachine...

9. 现在你可以最后启动 ejabberd:

      ejabberdctl start

10. 检查是否旧数据库的信息可用: accounts, rosters... 完成之后, 记住从公共目录删除临时备份文件.

ejabberd安全

防火墙设置

当你配置防火墙的时候,你需要注意以下 TCP 端口:

端口 描述
5222 用于 Jabber/XMPP 客户端连接的标准端口, 纯文本或 STARTTLS.
5223 Jabber 客户端使用旧的 SSL 方法连接的标准端口 .
5269 用于 Jabber/XMPP 服务器连接的标准端口.
4369 EPMD (5.2 节) 监听Erlang节点名请求.
端口范围 用于两个Erlang节点之间的连接. 这个范围是可配置的(见 5.2 节).

epmd

epmd (Erlang端口映射守候进程) 是一个包含在 Erlang/OTP 里的小的名字服务器,并且在建立分布式 Erlang 通讯时被 Erlang 程序使用. ejabberd 需要 epmd 来使用 ejabberdctl 并且使用集群的ejabberd 节点时也需要它. 这个小的程序是由Erlang自动启动的, 并且永不停止. 如果 ejabberd 停止了, 并且没有任何其他 Erlang 程序运行在系统上, 如果你想的话可以安全地停止 epmd.

ejabberd 运行在一个Erlang节点内部. 为了和 ejabberd 通讯, 脚本 ejabberdctl 启动一个新的 Erlang 节点并连接到这个运行着 ejabberd 的Erlang节点. 为了这个通讯能工作, epmd 必须运行和在端口4369监听名字请求. 你应该在防火墙以这种方式禁止端口4369,即只允许你机器上的程序访问它.

如果你建立了一个许多 ejabberd 实例的集群, 每个 ejabberd 实例被称为一个 ejabberd 节点. 那些 ejabberd 节点使用一个特别的 Erlang 通讯方法来建立集群, 那么 EPMD 再次需要监听端口 4369. 所以, 如果你计划计建立一个 ejabberd 节点的集群,你必须为这个集群涉及的机器打开端口 4369. 记住禁止这个端口使得它无法从互联网访问到.

一旦一个Erlang节点使用EPMD和端口4369解析了另一个Erlang节点的节点名, 节点之间就直接通讯. 在这个情况下使用的端口缺省是随机的, 但是可以在文件 ejabberdctl.cfg里配置. Erlang命令行参数被内部使用, 例如:

erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375

Erlang Cookie

Erlang cookie 是一个数字和字母组成的字符串. 一个Erlang节点在启动时从命令行参数 -setcookie 读取cookie. 如果没有指定, 则从 $HOME/.erlang.cookie 读取cookie 文件. 如果这个文件不存在, 它会被立刻以一个随机的cookie建立. 两个Erlang节点只有它们有相同的cookie才会通讯 . 在Erlang节点上设置一个cookie允许你结构化你的Erlang网络并定义哪个节点被允许连接到哪个.

感谢Erlang cookies, 你可以阻止对Erlang节点的错误访问, 例如当同一台机器上有许多Erlang节点运行不同程序的时候.

设置一个安全cookie是一个简单的方法来增加非法访问你的Erlang节点的困难度. 然而, 对于阻止对Erlang节点的未授权访问或侵扰,cookie系统不是最终有效的. Erlang节点之间的通讯是未加密的, 所以 cookie 可能被网络上的探针读取. 推荐使得Erlang更加安全的方法是禁止端口4369.

Erlang节点名

一个Erlang节点可以拥有一个节点名. 这个名字可能很短 (如果用命令行参数 -sname 指定) 或很长 (如果用参数 -name 指定). 以 -sname 启动一个Erlang节点限制Erlang节点和LAN之间的通讯.

使用选项 -sname 而不是 -name ,是一个简单增加对你的Erlang节点的未授权访问难度的方法. 然而, 对于阻止对Erlang节点的未授权访问或侵扰,它不是最终有效的. 因为有可能伪装你在另一个网络里使用一个修改过的 Erlang epmd. 推荐使得Erlang更加安全的方法是禁止端口4369.

敏感文件安全

ejabberd在文件系统里存储敏感数据要么使用纯文本要么是二进制文件. 文件系统许可应被设置为只允许适当的用户读, 写和执行那些文件和目录.

ejabberd configuration file: /etc/ejabberd/ejabberd.cfg

包含外部组件的管理员的 JID 和密码. 备份文件可能也包含这个信息, 所以整个 /etc/ejabberd/ 目录的安全是必要的.

ejabberd service log: /var/log/ejabberd/ejabberd.log

包含客户端的IP地址. 如果 loglevel 设为 5, 它包含全部的会话和密码. 如果使用了一个 logrotate 系统, 可能有好几个日志文件拥有类似的信息, 所以整个 /var/log/ejabberd/ 目录的安全是必要的.

Mnesia database spool files in /var/lib/ejabberd/

这个文件存储二进制数据, 但是一些部分仍是可读的. 这个文件由 Mnesia 生成并且它们的许可不能被直接设置, 所以整个 /var/lib/ejabberd/ 目录的安全是必要的.

Erlang cookie file: /var/lib/ejabberd/.erlang.cookie

5.3 节.

集群

如何工作

一个XMPP域是由一个或多个ejabberd节点伺服的. 这些节点可能运行在通过网络连接的不同的机器上. 它们都必须有能力连接到所有其他节点的4369端口, 并且必须有相同的 magic cookie (见 Erlang/OTP 文档, 换句话说,在所有节点上,文件 ~ejabberd/.erlang.cookie 必须是相同的 ). 这是必须的,因为所有节点交换关于已连接的用户, s2s连接, 已注册的服务, 等等…信息.

每个 ejabberd 节点有意下模块:

  • router,
  • local router,
  • session manager,
  • s2s manager.

Router

这个模块是每个节点的XMPP包的主router. 它基于它们的目标域来路由它们. 它使用一个全局路由表. 在这个路由表里搜索到包的目的地的域, 并且如果找到, 这个包就被路由到适当的进程. 如果没找到, 它被送到 s2s manager.

Local Router

这个模块路由那些目的域等于服务器的主机名之一的包. 如果目的JID有一个非空的 user 部分, 它路由到 session manager, 反之则它的处理依赖于它的内容.

Session Manager

这个模块路由包到本地用户. 它通过一个出席信息表查找一个包必须被发送给哪个用户资源. 然后该包要么路由到适当的 c2s 进程, 要么存储在离线存储 offline storage, 或弹回.

s2s Manager

这个模块路由包到其他 XMPP 服务器. 首先, 它检查是否已存在一个从该包的源域到目的域的s2s连接. 如果有, s2s manager 路由这个包到伺服这个连接的进程, 反之打开一个新的连接.

集群配置

假定你已经在一个机器named(第一个)上配置了 ejabberd , 并且你需要配置另外一个来做一个 ejabberd 集群. 那么按以下步骤做:

1. 从第一台机器拷贝 ~ejabberd/.erlang.cookie 文件到第二台机器.

(或者) 你也可以增加‘-setcookie content_of_.erlang.cookie’选项到以下所有‘erl’ 命令.

2. 在第二台机器上,在ejabberd工作目录中,以 ejabberd 守候进程用户运行以下命令:

      erl -sname ejabberd \
          -mnesia dir '"/var/lib/ejabberd/"' \
          -mnesia extra_db_nodes "['ejabberd@first']" \
          -s mnesia
这将启动 Mnesia 服务于和 ejabberd@first 相同的数据库. 你可以运行命令 ‘mnesia:info().’检查它. 你应该看到许多远程表和行,类似以下:
注意: 在你的系统里 Mnesia 目录可能是不同的. 要知道 ejabberd 期望在哪里找到 Mnesia 的缺省安装, 不带参数调用 ejabberdctl 然后它将显式一些帮助, 包括 Mnesia database spool 目录.
      running db nodes   = [ejabberd@first, ejabberd@second]

3. 现在在相同的‘erl’会话下运行以下命令:

      mnesia:change_table_copy_type(schema, node(), disc_copies).
这将为该数据库建立本地磁盘存储.
(或者) 在第二个节点通过Web管理修改scheme表的存储类型为‘RAM and disc copy’.

4. 现在你可以增加更多表的复制到这个节点 ,使用‘mnesia:add_table_copy’ 或 ‘mnesia:change_table_copy_type’如上 (只是把 ‘schema’ 替换成其他表名,并且 ‘disc_copies’可以被替换成‘ram_copies’ 或 ‘disc_only_copies’).

哪个表被复制,依赖于你的需要, 你可以从‘mnesia:info().’命令得到一些提示, 通过查看每个位于 ’first’的表的大小和缺省的存储类型.

复制一个表使得这个节点的这个表的查询更加快速. 写入, 另一方面, 将更慢. 而且当然如果复制之一的机器挂了, 其他复制将被使用.

看一下 Mnesia用户指南的 5.3 节(表 片段)将有所帮助.
(或者) 同之前的条目, 但用于不同的表.

5. 运行‘init:stop().’ 或只是 ‘q().’ 退出 Erlang shell. 这可能要花些时间,如果 Mnesia 还没有从first传输和处理完所有数据.

6. 现在在第二台机器上使用和第一台机器类似的配置运行 ejabberd: 你可能不需要重复‘acl’ 和 ‘access’ 选项,因为它们将从第一台机器获得; 并且 mod_irc 只应该在集群里的一台机器上激活.

你可以在其他机器上重复这些步骤来服务于这个域.

服务负载均衡

组件负载均衡

域负载均衡机制

ejabberd包含了一个机制来对插入一个ejabberd集群的组件进行负载均衡. 它意味着你可以在每一个ejabberd集群插入相同组件的一个或多个实例并且流量将自动分布.

缺省的分布式机制尝试递送到组件的一个本地实例. 如果有多个本地实例可用, 随机地选取一个实例. 如果没有本地实例可用, 随机选取一个远程组件实例.

如果你需要一个不同的行为, 你可以通过选项 domain_balancing 修改负载均衡行为. 这个选项的语法如下:

{domain_balancing, "component.example.com", BalancingCriteria}.

多个负载均衡标准可用:

  • destination: 使用包的to属性的全JID.
  • source: 使用包的from属性的全JID.
  • bare_destination: 使用包的to属性的纯JID(没有资源).
  • bare_source: 使用包的from属性的纯JID(没有资源).

如果对应标准的这个值是相同的, 则集群中相同的组件实例将被使用.

负载均衡水桶

当一个给定的组件有失败的风险的时候, 域均衡可能导致服务麻烦. 如果一个组件失败了,服务将无法正确工作,除非会话被重新均衡了.

在这种情况下, 最好限制这个问题在由失败组件处理的这些会话. 这就是 domain_balancing_component_number 选项所做的, 使负载均衡机制不动态化, 而是粘在固定数目的组件实例上.

语法是:

{domain_balancing_component_number, "component.example.com", Number}.

调试

日志文件

一个ejabberd节点写两个日志文件:

ejabberd.log

ejabberd 服务日志, 由 ejabberd 节点汇报的消息

erlang.log

Erlang/OTP 系统日志, 由 Erlang/OTP 使用 SASL (系统架构支持库) 汇报的消息

选项 loglevel 修改文件 ejabberd.log 的详细程度. 语法是:

{loglevel, Level}.

可能的 Level 有:

0

没有ejabberd日志 (不推荐)

1

紧急

2

错误

3

警告

4

信息

5

调试

例如, 缺省配置为:

{loglevel, 4}.

日志文件持续增长, 所以推荐定期流转. 为了流转日志文件, 重命名这个文件然后重新打开它们. ejabberdctl命令reopen-log (请参考 4.1.1 节) 重新打开日志文件, 同时也重命名旧文件,如果你不重命名它们的话.

调试控制台

调试控制台是连接到一个已运行的 ejabberd 服务器的 Erlang shell. 使用这个 Erlang shell, 一个有经验的管理员可以执行复杂的任务.

这个 shell 给予对ejabberd 服务器的完全控制, 所以使用它要非常小心. 在文章 Erlang节点的互连 里有一些简单和安全的例子

要退出这个shell, 关闭窗口或键入: control+c control+c.

Watchdog警告

ejabberd包含了一个看门狗 watchdog 机制,当找出和内存使用有关的问题时,对开发者可能有用. 如果ejabberd服务器的一个进程消耗了超过配置阀值的内存, 一个消息将被发送到ejabberd配置文件中选项 watchdog_admins 定义的 XMPP 帐号.

语法是:

{watchdog_admins, [JID, ...]}.

消耗的内存以words衡量: 一个word在32位系统上是4字节bytes, 在64位系统上是8字节bytes. 这个阀值缺省是 1000000 words. 这个值可以用选项 watchdog_large_heap来配置, 或在一个会话中使用watchdog警报机器人.

语法是:

{watchdog_large_heap, Number}.

示例配置:

{watchdog_admins, ["admin2@localhost", "admin2@example.org"]}.
{watchdog_large_heap, 30000000}.

要移除watchdog管理员, 在选项里移除. 为了移除所有watchdog管理员, 设置该选项为空列表:

{watchdog_admins, []}.

附录 A 国际化和本地化

ejabberd的源码支持本地化. 翻译者可编辑 gettext .po 文件,使用任何可用的软件 (KBabel, Lokalize, Poedit...) 或一个简单的文本编辑器.

接着gettext用来提取, 更新和导出那些 .po 文件成为能被ejabberd读取的 .msg 格式. 为执行那些管理任务, 在 src/ 目录执行 make translations. 可翻译的字符串被从源码提取出来生成文件 ejabberd.pot. 这个文件合并每个 .po 文件来生成更新的 .po 文件. 最后那些 .po 文件被导出成 .msg 文件, 那是个容易被 ejabberd 读取的格式.

所有內建的模块都支持内部的IQ queries的xml:lang 属性 . Figure A.1, 例如, 展示了应答以下 query:

<iq id='5'
    to='example.org'
    type='get'
    xml:lang='ru'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
   discorus.png
   Figure A.1: Service Discovery when xml:lang=’ru’

Web管理也支持 Accept-Language HTTP 头.

   webadmmainru.png
   Figure A.2: Web Admin showing a virtual host when the web browser provides the HTTP header ‘Accept-Language: ru’

附录 B 发行备注

发行备注在 ejabberd主页

附录 C 鸣谢

感谢所有对本指南有贡献的人:

  • Alexey Shchepin (xmpp:aleksey@jabber.ru)
  • Badlop (xmpp:badlop@jabberes.org)
  • Evgeniy Khramtsov (xmpp:xram@jabber.ru)
  • Florian Zumbiehl (xmpp:florz@florz.de)
  • Michael Grigutsch (xmpp:migri@jabber.i-pobox.net)
  • Mickael Remond (xmpp:mremond@process-one.net)
  • Sander Devrieze (xmpp:s.devrieze@gmail.com)
  • Sergei Golovan (xmpp:sgolovan@nes.ru)
  • Vsevolod Pelipas (xmpp:vsevoload@jabber.ru)

附录 D 版权信息

略...

Ejabberd Installation and Operation Guide. Copyright © 2003 — 2010 ProcessOne

This document is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this document; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

个人工具