ejabberd
此文档仍在编写中!
ejabberd 是高性能的 XMPP 服务器,可以轻松扩展到大型公共服务器,但对于自托管来说并不太重。它可以相对容易地从 Linux 发行版存储库安装,默认配置适用于运行良好的 XMPP 服务器。然而,这些默认设置往往相当保守,如果您想更好地支持新式 XMPP 功能,就需要进行一些调整。所有 ejabberd 模块设置的官方文档都可以在此处找到。
教程1
必要条件:
- 域名
- 服务器
本教程从单个虚拟主机[^2]开始。例如,example.net 是域。将所有 example.net 实例替换为您自己的域。
[^2]:虚拟主机允许在一台服务器上运行多个 XMPP 服务。例如,一个 XMPP 服务的域名是 example.net,另一个 XMPP 服务的域名是 example.org,两者在某种程度上是分开的,就像它们在不同的服务器上运行一样。
步骤 1:设置 DNS 记录
XMPP 服务器上的每个服务都需要 DNS A/AAAA 记录和 SRV 记录。
A 记录:
example.netmuc.example.net(用于群聊)upload.example.net(用于 HTTP 文件上传)pubsub.example.net(用于 pubsub 节点)proxy.example.net(用于文件传输代理)turn.example.net(用于 STUN/TURN)
每个都指向要运行 ejabberd 的服务器的 IP 地址。
为每个创建 SRV 记录,指向解析到服务器的域,如下所示:
(所有记录的格式均为 _service._proto.name IN SRV 优先级 权重 端口 目标主机)
1_xmpp-client._tcp IN SRV 5 0 5222 example.net.
2_xmpps-client._tcp IN SRV 5 0 5223 example.net.
3_xmpp-server._tcp IN SRV 5 0 5269 example.net.
4_xmpps-server._tcp IN SRV 5 0 5270 example.net.
和
1_xmpp-client._tcp.muc IN SRV 5 0 5222 example.net.
2_xmpps-client._tcp.muc IN SRV 5 0 5223 example.net.
3_xmpp-server._tcp.muc IN SRV 5 0 5269 example.net.
4_xmpps-server._tcp.muc IN SRV 5 0 5270 example.net.
为每个子域(从 muc 开始),不包括 turn.example.net。
最后,为 STUN/TURN 添加一组 SRV 记录。
1_stun._udp IN SRV 5 0 3478 turn.example.net.
2_stun._tcp IN SRV 5 0 3478 turn.example.net.
3_stuns._tcp IN SRV 5 0 5349 turn.example.net.
4
5_turn._udp IN SRV 5 0 3478 turn.example.net.
6_turn._tcp IN SRV 5 0 3478 turn.example.net.
7_turns._tcp IN SRV 5 0 5349 turn.example.net.
额外信息:由于这些 SRV 委托记录,可以选择在 example.net 以外的服务器上托管
XMPP(即,如果将一个域上的服务拆分到多个服务器)。更多信息请访问
XEP-0368。
步骤 2:打开防火墙端口
打开端口:
TCP: 80 443 5222 5223 5269 5270 3478 5349 49152-65535
UDP: 3478 49152-65535
80 和 443 用于 web 服务器,5222、5223、5269 和 5270 用于 XMPP,其余用于
STUN/TURN。
步骤 3:设置 web 服务器并获取 SSL 证书
为您的域名以及多个子域名获取 SSL 证书,总而言之:
example.netmuc.example.netupload.example.netpubsub.example.netproxy.example.netproxy.example.net
proxypass http://127.0.0.1:5443 通过:
确保对于
/xmpp,您也有代理 websockets 所需的一切。如果您使用 nginx,请增加 HTTP 上传的client_max_body_size。确保证书文件可读和/或位于
ejabberd账号可读的位置。
为了避免使用 nginx + Certbot 之类的东西,请使用内置的 ejabberd acme 模块,但本文假设希望在同一系统上托管其他 web 服务,在这种情况下,每个 HTTP 服务都将反向代理到单个 HTTPS web 服务。
步骤 4:安装 ejabberd
最后安装系统包。确保构建有 PostgreSQL 支持。
确认文件 /etc/ejabberd/ejabberd.yml 存在,并且运行 ejabberd 的账号可以读取(几乎可以肯定为
ejabberd),如有必要,可以从 GitHub
仓库
复制示例 ejabberd.yml 或 wget/curl。如果是从仓库获取,请确保版本与您的操作系统打包的 ejabberd 版本相对应。
步骤 5:设置 PostgreSQL 数据库
应该为每个虚拟主机创建一个单独的数据库,因为这会使事情更清楚,此外,将来更容易迁移单个虚拟主机。然而,如此处所述,现在也存在只使用一个的能力。
遵循操作系统的标准 PostgreSQL 安装说明。完成此操作后,以管理员身份连接到数据库,然后:
- 使用
CREATE USER ejabberd WITH PASSWORD 'your_password';创建 ejabberd 数据库账号。别忘了更改密码,并记下来。 - 使用
CREATE DATABASE ejabberd_example OWNER ejabberd;为虚拟主机创建数据库。将example替换为与虚拟主机相对应的内容。 - 退出
psqlshell,并使用命令curl -s https://raw.githubusercontent.com/processone/ejabberd/master/sql/pg.sql | sudo -u ejabberd psql ejabberd_example从 GitHub 导入数据库模式(再次替换example)。
步骤 6:ejabberd 配置
主机配置
首先将 hosts 下的 localhost 替换为虚拟主机(例如 example.net),然后列出之前在 certfiles
下获得的证书文件。
1hosts:
2 - example.net
3
4certfiles:
5 - "/etc/ejabberd/certs/*/*"
现在在 YAML 文件的 root 级别设置 default_db: sql。后面应该是 host_config
和虚拟主机的数据库配置,如下所示。根据设置自定义每个值。
1host_config:
2 example.net:
3 sql_type: pgsql
4 sql_server: "localhost"
5 sql_port: 5432
6 sql_username: "ejabberd"
7 sql_password: "postgres_password"
8 sql_database: "ejabberd_example"
9 auth_method: sql
10 auth_password_format: scram
监听器
在 listen 下,确保每个端口上都启用了所有正确的服务,包括端口 5270(非默认)上的 s2s TLS:
1listen:
2 -
3 port: 5222
4 module: ejabberd_c2s
5 max_stanza_size: 262144
6 shaper: c2s_shaper
7 access: c2s
8 starttls_required: true
9 -
10 port: 5223
11 tls: true
12 module: ejabberd_c2s
13 max_stanza_size: 262144
14 shaper: c2s_shaper
15 access: c2s
16 starttls_required: true
17 -
18 port: 5269
19 module: ejabberd_s2s_in
20 max_stanza_size: 524288
21 -
22 port: 5270
23 tls: true
24 module: ejabberd_s2s_in
25 max_stanza_size: 524288
接下来,启用 HTTP 服务器和 STUN/TURN 服务器模块。将 turn_ipv4_address 和 ip 设置为服务器的 IPv4
地址。HTTP 服务器的 TLS 将关闭,因为它通过之前设置的 web 服务器进行反向代理。
1 -
2 port: 5443
3 module: ejabberd_http
4 request_handlers:
5 /xmpp/admin: ejabberd_web_admin
6 /xmpp/bosh: mod_bosh
7 /xmpp/upload: mod_http_upload
8 /xmpp/ws: ejabberd_http_ws
9 /.well-known/host-meta: mod_host_meta
10 /.well-known/host-meta.json: mod_host_meta
11 -
12 port: 3478
13 transport: udp
14 module: ejabberd_stun
15 use_turn: true
16 turn_min_port: 49152
17 turn_max_port: 65535
18 # The server's public IPv4 address:
19 turn_ipv4_address: 0.0.0.0
20 -
21 port: 5349
22 transport: tcp
23 module: ejabberd_stun
24 use_turn: true
25 tls: true
26 turn_min_port: 49152
27 turn_max_port: 65535
28 ip: 0.0.0.0
29 turn_ipv4_address: 0.0.0.0
在 root 下设置 s2s_use_starttls: required。
访问控制列表和规则
此时,可以设置一些 ACL。acls 只是访问控制列表,根据您的需求设置
access_rules,这将是传递给模块设置的内容。建议至少使用管理员账号。例子:
1acl:
2 admin:
3 user: juliet@example.net
4 capulet:
5 - user: juliet@example.net
6 - user: tybalt@example.net
7 nurse:
8 - user: angelica@example.net
9
10access_rules:
11 household:
12 allow: capulet
13 allow: nurse
模块
服务器信息发现(联系地址)
在 mod_disco 下添加滥用地址。也可以根据
XEP-0157 添加其他联系地址:
1modules:
2# ...
3 mod_disco:
4 server_info:
5 -
6 modules: all
7 name: "abuse-addresses"
8 urls: ["mailto:abuse@example.net"]
Host-Meta(Web 客户端)
添加 mod_host_meta:
1 mod_host_meta:
2 bosh_service_url: "https://@HOST@/xmpp/bosh"
3 websocket_url: "wss://@HOST@/xmpp/ws"
消息归档管理
编辑 mod_mam,并将 assume_mam_usage 更改为 false,如果不希望默认在服务器上归档消息,则将 default
更改为 never:
1 mod_mam:
2 db_type: sql
3 assume_mam_usage: never
4 default: never
STUN 发现
添加 mod_stun_disco 以向客户端通告 STUN 服务,分别将 0.0.0.0 和 example.net 更改为服务器的 IP
和主机名:
1 mod_stun_disco:
2 credentials_lifetime: 12h
3 services:
4 -
5 host: 0.0.0.0
6 port: 3478
7 type: stun
8 transport: udp
9 restricted: false
10 -
11 host: 0.0.0.0
12 port: 3478
13 type: turn
14 transport: udp
15 restricted: true
16 -
17 host: turn.example.net
18 port: 5349
19 type: stuns
20 transport: tcp
21 restricted: false
22 -
23 host: turn.example.net
24 port: 5349
25 type: turns
26 transport: tcp
27 restricted: true
多用户聊天
将主机设置为 muc 子域,否则它将尝试使用 conference.example.net。默认情况下,在
default_room_options 中设置 mam: false 将禁用服务器端消息归档。
1 mod_muc:
2 host: muc.example.net
3 access:
4 - allow
5 access_admin:
6 - allow: admin
7 access_create: muc_create
8 access_persistent: muc_create
9 access_mam:
10 - allow
11 default_room_options:
12 mam: false
文件代理
1 mod_proxy65:
2 access: local
3 max_connections: 5
HTTP 文件上传
1 mod_http_upload:
2 put_url: https://@HOST@/xmpp/upload
3 docroot: /var/www/ejabberdupload
4 max_size: 1073741824
5 custom_headers:
6 "Access-Control-Allow-Origin": "https://@HOST@"
7 "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
8 "Access-Control-Allow-Headers": "Content-Type"
为 docroot 创建文件夹,并确保它归 ejabberd 账号所有。将 max_size(最大上传大小)更改为首选值。
PubSub
1 mod_pubsub:
2 access_createnode: pubsub_createnode
3 plugins:
4 - flat
5 - pep
6 force_node_config:
7 ## Avoid buggy clients to make their bookmarks public
8 storage:bookmarks:
9 access_model: whitelist
步骤 7:启动服务器并创建管理员账号
启动 ejabberd 服务器!
1sudo -u ejabberd ejabberdctl start
(根据您的操作系统和 ejabberd 的安装方式,此步骤可能有所不同。)
注册管理员用户 admin@example.net,使用密码 password:
1sudo -u ejabberd ejabberdctl register admin example.net password
在 compliance.conversations.im 有一个合规性测试工具可以对服务器进行测试。
正确设置一切后,可以选择更改配置 root 下的
loglevel。
将在 https://example.net/xmpp/admin 上提供一个管理页面。
附加功能!
Web 客户端
可以使用
mod_conversejs
设置 conversejs。可能需要更新 web 服务器配置以代理新端点(下面的 /chat)。
1listen:
2 -
3 port: 5443
4 module: ejabberd_http
5 request_handlers:
6 /xmpp/bosh: mod_bosh
7 /xmpp/ws: ejabberd_http_ws
8 /chat: mod_conversejs
9
10modules:
11 mod_conversejs:
12 websocket_url: "ws://@HOST@/xmpp/ws"
13 bosh_service_url: "https://@HOST@/xmpp/bosh"
附加虚拟主机
对于每个附加虚拟主机,都应该创建一个新的数据库,并将其添加到配置的数据库部分。例如:
1host_config:
2 example.net:
3 sql_type: pgsql
4 sql_server: "localhost"
5 sql_port: 5432
6 sql_username: "ejabberd"
7 sql_password: "postgres_password"
8 sql_database: "ejabberd_net"
9 auth_method: sql
10 auth_password_format: scram
11 example.org:
12 sql_type: pgsql
13 sql_server: "localhost"
14 sql_port: 5432
15 sql_username: "ejabberd"
16 sql_password: "postgres_password"
17 sql_database: "ejabberd_org"
18 auth_method: sql
19 auth_password_format: scram
配置文件中的声明之间不能有冲突,因此,如果在 root 的 modules 下声明了
mod_muc、mod_proxy65、mod_http_upload 和 mod_pubsub,则在 root 的
append_host_config 下为每个虚拟主机必须删除复制它们(以及虚拟主机之间的其他配置差异)。示例如下:
1append_host_config:
2 example.org:
3 modules:
4 mod_muc:
5 host: muc.example.org
6 access_create: org_account
7 access_persistent: org_account
8 access:
9 - allow
10 access_admin:
11 - allow: admin
12 default_room_options:
13 mam: false
14 mod_proxy65:
15 access: org_account
16 max_connections: 5
17 mod_http_upload:
18 access: org_account
19 put_url: https://@HOST@/xmpp/upload
20 docroot: /var/www/ejabberdupload
21 max_size: 1073741824
22 custom_headers:
23 "Access-Control-Allow-Origin": "https://@HOST@"
24 "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
25 "Access-Control-Allow-Headers": "Content-Type"
26 mod_pubsub:
27 access_createnode: org_account
28 plugins:
29 - flat
30 - pep
31 force_node_config:
32 ## Avoid buggy clients to make their bookmarks public
33 storage:bookmarks:
34 access_model: whitelist
35 example.net:
36 modules:
37 mod_muc:
38 hosts:
39 - muc.example.net
40 access_create: net_account
41 access_persistent: net_account
42 access:
43 - allow
44 access_admin:
45 - allow: admin
46 default_room_options:
47 mam: false
48 mod_proxy65:
49 access: net_account
50 max_connections: 5
51 mod_http_upload:
52 access: net_account
53 put_url: https://@HOST@/xmpp/upload
54 docroot: /var/www/ejabberdupload
55 max_size: 1073741824
56 custom_headers:
57 "Access-Control-Allow-Origin": "https://@HOST@"
58 "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
59 "Access-Control-Allow-Headers": "Content-Type"
60 mod_pubsub:
61 access_createnode: net_account
62 plugins:
63 - flat
64 - pep
65 force_node_config:
66 ## Avoid buggy clients to make their bookmarks public
67 storage:bookmarks:
68 access_model: whitelist
如上所述,可以使用 ACL 禁用对每个虚拟主机的某些服务的访问,例如,为了防止 example.net 上的账号在
muc.example.org 上创建群聊。
独立的 TURN 服务器(Coturn)
在这种情况下,将 mod_stun_disco 更改为这个,并且不启用 STUN/TURN 的 listen 选项。生成认证密钥并将其与
TURN 服务器实例共享。
1 mod_stun_disco:
2 secret: "auth_secret"
3 services:
4 -
5 host: turn.example.net
6 type: stun
7 -
8 host: turn.example.net
9 type: turn
优质邀请
自 ejabberd
26.01
版本起,新增了
mod_invites
模块,允许您创建邀请令牌,您可以将这些令牌分享给他人,从而可控地允许他人创建新账号。
配置
下面我们来探讨几种不同的配置方案,帮助您根据自身需求灵活运用这一新功能。
基本配置
仅允许管理员用户,不允许常规带内注册(ibr)
1modules:
2 mod_invites: {}
3 mod_register:
4 allow_modules:
5 - mod_invites
mod_register 实施如 ip_access 之类进一步的限制。Allow local accounts to send account creation invites
1access_rules:
2 access_create_account:
3 allow: local
4#[...]
5modules:
6 mod_invites:
7 access_create_account: access_create_account
提供集成式登陆页面,帮助用户选择合适的客户端软件,并在需要时允许网络注册
集成式登陆页面基于 bootstrap4 和 jQuery。由于某些 Linux 发行版的限制,无法提供其软件包管理系统已包含的库。因此,根据您的安装方式和系统配置,可能需要手动安装这些库。
在 Debian 上非常简单,只需
1sudo apt install libjs-jquery libjs-bootstrap4
为了方便起见,ejabberd 源代码分发中包含一个位于 tools/dl_invites_page_deps.sh 的脚本,您可以这样使用:
1./tools/dl_invites_page_deps.sh /usr/share/javascript
请确保您具有写入此目录的必要权限。
如果您使用 Docker 或我们的二进制镜像,这些可能已经包含在内了。
本指南后续内容将假设我们已将这些库安装到上述位置。
现在配置 ejabberd 的 http 处理程序来提供登陆页面和这些库。
1listen:
2 -
3 port: 5281
4 module: ejabberd_http
5 request_handlers:
6 /xmpp/invites: mod_invites
7 /share: mod_http_fileserver
8# [...]
9modules:
10 mod_http_fileserver:
11 docroot: /usr/share/javascript
12 mod_invites:
13 landing_page: https://@HOST@/xmpp/invites/{{ invite.token }}
/share 服务,您也可以配置您首选的 Web 服务器来实现。改为提供外部登陆页面
如果您不想提供包含的登陆页面,您仍然可以配置外部服务。您可以自行托管,也可以使用现有服务,例如我们提供的 https://invite.joinjabber.org 服务。
在这种情况下,您必须相应地配置 landing_page 参数。
1modules:
2 mod_invites:
3 landing_page: https://invite.joinjabber.org/#{{ invite.uri|strip_protocol }}
管理
从命令行创建账号邀请
1sudo -u ejabberd ejabberdctl generate_invite example.net
如果您想为此账号建议用户名,您可以通过以下方式
1sudo -u ejabberd ejabberdctl generate_invite_with_username sponge_bob example.net
结果将如下所示(取决于您的配置):
1xmpp:example.net?register;preauth=fvR20OkCyXyjZoOSybZh4ebx https://example.net/xmpp/invites/fvR20OkCyXyjZoOSybZh4ebx
第一部分是 XMPP URI,第二部分是登陆页面(仅在配置后存在)。这就是您需要传递的内容。
屏蔽滥用账号
首先,您需要为 mod_invite 的 access_create_account 设置一个专用的访问规则,并在其中添加滥用者的账号。
1access_rules:
2 access_create_account:
3 deny:
4 - user: plankton@example.net
5 allow: local
6# [...]
7modules:
8 mod_invites:
9 access_create_account: access_create_account
如有需要,请重新加载配置。
1sudo -u ejabberdctl reload_config
现在将该账号发出的所有邀请失效。
1sudo -u ejabberdctl expire_invite_tokens plankton example.net
清理数据库
您可以清理过期和已使用的令牌来释放数据库空间。但请注意,此操作会移除所有可追溯信息(“谁邀请了谁”),并重置 max_invites
限制。这可能会影响您识别滥用者的能力。
1sudo -u ejabberd ejabberdctl cleanup_expired_tokens example.net
使用指南
现在是时候推广这一功能了!我们提供了一份指南,介绍了如何在一些常用的 XMPP 客户端中使用此功能。
支持聊天
这显然不是详尽的列表,如果您有任何问题或非常好的建议,请在此处联系我们: servers@joinjabber.org (网页聊天) (xmpp)