Ejabberd2:安装和操作指南

来自Jabber/XMPP中文翻译计划
2010年6月7日 (一) 19:29How (讨论 | 贡献)的版本
跳转到: 导航, 搜索


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

ejabberd 2.1.3 安装和管理指南

目录

绪论

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, []}
 ]
}.

管理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 版权信息

个人工具