ejabberd

此文档仍在编写中!

ejabberd 是高性能的 XMPP 服务器,可以轻松扩展到大型公共服务器,但对于自托管来说并不太重。它可以相对容易地从 Linux 发行版存储库安装,默认配置适用于运行良好的 XMPP 服务器。然而,这些默认设置往往相当保守,如果您想更好地支持新式 XMPP 功能,就需要进行一些调整。所有 ejabberd 模块设置的官方文档都可以在此处找到。

教程

必要条件:

  • 域名
  • 服务器

本教程从单个虚拟主机[^1]开始。例如,example.net 是域。将所有 example.net 实例替换为您自己的域。

[^1]:虚拟主机允许在一台服务器上运行多个 XMPP 服务。例如,一个 XMPP 服务的域名是 example.net,另一个 XMPP 服务的域名是 example.org,两者在某种程度上是分开的,就像它们在不同的服务器上运行一样。

步骤 1:设置 DNS 记录

XMPP 服务器上的每个服务都需要 DNS A/AAAA 记录和 SRV 记录。

A 记录:

  • example.net
  • muc.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 优先级 权重 端口 目标主机

_xmpp-client._tcp   IN SRV  5 0 5222 example.net.
_xmpps-client._tcp  IN SRV  5 0 5223 example.net.
_xmpp-server._tcp   IN SRV  5 0 5269 example.net.
_xmpps-server._tcp  IN SRV  5 0 5270 example.net.

_xmpp-client._tcp.muc   IN SRV  5 0 5222 example.net.
_xmpps-client._tcp.muc  IN SRV  5 0 5223 example.net.
_xmpp-server._tcp.muc   IN SRV  5 0 5269 example.net.
_xmpps-server._tcp.muc  IN SRV  5 0 5270 example.net.

为每个子域(从 muc 开始),不包括 turn.example.net

最后,为 STUN/TURN 添加一组 SRV 记录。

_stun._udp   IN SRV  5 0 3478 turn.example.net.
_stun._tcp   IN SRV  5 0 3478 turn.example.net.
_stuns._tcp  IN SRV  5 0 5349 turn.example.net.

_turn._udp   IN SRV  5 0 3478 turn.example.net.
_turn._tcp   IN SRV  5 0 3478 turn.example.net.
_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

80443 用于 web 服务器,5222522352695270 用于 XMPP,其余用于 STUN/TURN。

步骤 3:设置 web 服务器并获取 SSL 证书

为了避免使用 Nginx + Certbot 之类的东西,请使用内置的 ejabberd acme 模块,但本文假设希望在同一系统上托管其他 web 服务,在这种情况下,每个 HTTP 服务都将反向代理到单个 HTTPS web 服务。

步骤 4:安装 ejabberd

最后安装系统包。确保构建有 PostgreSQL 支持。

确认文件 /etc/ejabberd/ejabberd.yml 存在,并且运行 ejabberd 的用户可以读取(几乎可以肯定为 ejabberd),如有必要,可以从 github repo 复制示例 ejabberd.ymlwget/curl。如果是从 repo 获取,请确保版本与您的操作系统打包的 ejabberd 版本相对应。

步骤 5:设置 PostgreSQL 数据库

应该为每个虚拟主机创建一个单独的数据库,因为这会使事情更清楚,此外,将来更容易迁移单个虚拟主机。然而,如此处所述,现在也存在只使用一个的能力。

遵循操作系统的标准 PostgreSQL 安装说明。完成此操作后,以管理员身份连接到数据库,然后:

  1. 使用 CREATE USER ejabberd WITH PASSWORD 'your_password'; 创建 ejabberd 数据库用户。别忘了更改密码,并记下来。
  2. 使用 CREATE DATABASE ejabberd_example OWNER ejabberd; 为虚拟主机创建数据库。将 example 替换为与虚拟主机相对应的内容。
  3. 退出 psql shell,并使用命令 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 下获得的证书文件。

hosts:
  - example.net

certfiles:
  - "/etc/ejabberd/certs/*/*"

现在在 YAML 文件的 root 级别设置 default_db: sql。后面应该是 host_config 和虚拟主机的数据库配置,如下所示。根据设置自定义每个值。

host_config:
  example.net:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_example"
    auth_method: sql
    auth_password_format: scram

listen 下,确保每个端口上都启用了所有正确的服务,包括端口 5270(非默认)上的 s2s TLS:

listen:
  -
    port: 5222
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5223
    tls: true
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5269
    module: ejabberd_s2s_in
    max_stanza_size: 524288
  -
    port: 5270
    tls: true
    module: ejabberd_s2s_in
    max_stanza_size: 524288

接下来,启用 HTTP 服务器和 STUN/TURN 服务器模块。将 turn_ipv4_addressip 设置为服务器的 IPv4 地址。HTTP 服务器的 TLS 将关闭,因为它通过之前设置的 web 服务器进行反向代理。

  -
    port: 5443
    module: ejabberd_http
    request_handlers:
      /xmpp/admin: ejabberd_web_admin
      /xmpp/bosh: mod_bosh
      /xmpp/upload: mod_http_upload
      /xmpp/ws: ejabberd_http_ws
      /.well-known/host-meta: mod_host_meta
      /.well-known/host-meta.json: mod_host_meta
  -
    port: 3478
    transport: udp
    module: ejabberd_stun
    use_turn: true
    turn_min_port: 49152
    turn_max_port: 65535
    # The server's public IPv4 address:
    turn_ipv4_address: 0.0.0.0
  -
    port: 5349
    transport: tcp
    module: ejabberd_stun
    use_turn: true
    tls: true
    turn_min_port: 49152
    turn_max_port: 65535
    ip: 0.0.0.0
    turn_ipv4_address: 0.0.0.0

在 root 下设置 s2s_use_starttls: required

此时,可以设置一些 ACL。acls 只是访问控制列表,根据您的需求设置 access_rules,这将是传递给模块设置的内容。建议至少使用管理员用户。例子:

acl:
  admin:
    user: juliet@example.net
  capulet:
    - user: juliet@example.net
	- user: tybalt@example.net
  nurse:
    - user: angelica@example.net

access_rules:
  household: 
    allow: capulet
    allow: nurse

模块

mod_disco 下添加滥用地址。也可以根据 XEP-0157 添加其他联系地址:

modules:
# ...
  mod_disco:
    server_info:
    -
      modules: all
      name: "abuse-addresses"
      urls: ["mailto:abuse@example.net"]

添加 mod_host_meta

  mod_host_meta:
    bosh_service_url: "https://@HOST@/xmpp/bosh"
    websocket_url: "wss://@HOST@/xmpp/ws"

编辑 mod_mam,并将 assume_mam_usage 更改为 false,如果不希望默认在服务器上存档消息,则将 default 更改为 never

  mod_mam:
    db_type: sql
    assume_mam_usage: never
    default: never

添加 mod_stun_disco 以向客户端通告 STUN 服务,分别将 0.0.0.0example.net 更改为服务器的 IP 和主机名:

  mod_stun_disco: 
    credentials_lifetime: 12h
    services:
        -
          host: 0.0.0.0
          port: 3478
          type: stun
          transport: udp
          restricted: false
        -
          host: 0.0.0.0
          port: 3478
          type: turn
          transport: udp
          restricted: true
        -
          host: turn.example.net
          port: 5349
          type: stuns
          transport: tcp
          restricted: false
        -
          host: turn.example.net
          port: 5349
          type: turns
          transport: tcp
          restricted: true

群聊:

将主机设置为 muc 子域,否则它将尝试使用 conference.example.net。默认情况下,在 default_room_options 中设置 mam: false 将禁用服务器端消息存档。

  mod_muc:
    host: muc.example.net
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    access_mam:
      - allow
    default_room_options:
      mam: false

文件代理:

  mod_proxy65:
    access: local
    max_connections: 5

HTTP 文件上传:

  mod_http_upload:
    put_url: https://@HOST@/xmpp/upload
    docroot: /var/www/ejabberdupload
    max_size: 1073741824
    custom_headers:
      "Access-Control-Allow-Origin": "https://@HOST@"
      "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
      "Access-Control-Allow-Headers": "Content-Type"

docroot 创建文件夹,并确保它归 ejabberd 用户所有。将 max_size(最大上传大小)更改为首选值。

发布订阅:

  mod_pubsub:
    access_createnode: pubsub_createnode
    plugins:
      - flat
      - pep
    force_node_config:
      ## Avoid buggy clients to make their bookmarks public
      storage:bookmarks:
        access_model: whitelist

步骤 7:启动服务器并创建管理员用户

启动 ejabberd 服务器!

使用 sudo -u ejabberd ejabberdctl register admin example.net password 注册 admin@example.net,密码为 password

compliance.conversations.im 有一个合规性测试程序来测试服务器。正确设置一切后,可以选择更改配置 root 下的 loglevel

将在 https://example.net/xmpp/admin 上提供一个管理页面。

额外的好东西!

Web 客户端

可以使用 mod_conversejs 设置 conversejs。可能需要更新 web 服务器配置以代理新端点(下面的 /chat)。

listen:
  -
    port: 5443
    module: ejabberd_http
    request_handlers:
      /xmpp/bosh: mod_bosh
      /xmpp/ws: ejabberd_http_ws
      /chat: mod_conversejs

modules:
  mod_conversejs:
    websocket_url: "ws://@HOST@/xmpp/ws"
    bosh_service_url: "https://@HOST@/xmpp/bosh"

附加虚拟主机

对于每个附加虚拟主机,都应该创建一个新的数据库,并将其添加到配置的数据库部分。例如:

host_config:
  example.net:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_net"
    auth_method: sql
    auth_password_format: scram
  example.org:
    sql_type: pgsql
    sql_server: "localhost"
    sql_port: 5432
    sql_username: "ejabberd"
    sql_password: "postgres_password"
    sql_database: "ejabberd_org"
    auth_method: sql
    auth_password_format: scram

配置文件中的声明之间不能有冲突,因此,如果在 root 的 modules 下声明了 mod_mucmod_proxy65mod_http_uploadmod_pubsub,则在 root 的 append_host_config 下为每个虚拟主机必须删除复制它们(以及虚拟主机之间的其他配置差异)。示例如下:

append_host_config:
  example.org:
    modules:
      mod_muc:
        host: muc.example.org
        access_create: org_users
        access_persistent: org_users
        access:
          - allow
        access_admin:
          - allow: admin
        default_room_options:
          mam: false
      mod_proxy65:
        access: org_users
        max_connections: 5
      mod_http_upload:
        access: org_users
        put_url: https://@HOST@/xmpp/upload
        docroot: /var/www/ejabberdupload
        max_size: 1073741824
        custom_headers:
          "Access-Control-Allow-Origin": "https://@HOST@"
          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
          "Access-Control-Allow-Headers": "Content-Type"
      mod_pubsub:
        access_createnode: org_users
        plugins:
          - flat
          - pep
        force_node_config:
          ## Avoid buggy clients to make their bookmarks public
          storage:bookmarks:
            access_model: whitelist
  example.net:
    modules:
      mod_muc:
        hosts: 
          - muc.example.net
        access_create: net_users
        access_persistent: net_users
        access:
          - allow
        access_admin:
          - allow: admin
        default_room_options:
          mam: false
      mod_proxy65:
        access: net_users
        max_connections: 5
      mod_http_upload:
        access: net_users
        put_url: https://@HOST@/xmpp/upload
        docroot: /var/www/ejabberdupload
        max_size: 1073741824
        custom_headers:
          "Access-Control-Allow-Origin": "https://@HOST@"
          "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
          "Access-Control-Allow-Headers": "Content-Type"
      mod_pubsub:
        access_createnode: net_users
        plugins:
          - flat
          - pep
        force_node_config:
          ## Avoid buggy clients to make their bookmarks public
          storage:bookmarks:
            access_model: whitelist

如上所述,可以使用 ACL 禁用对每个虚拟主机的某些服务的访问,例如,为了防止 example.net 上的用户在 muc.example.org 上创建群聊。

独立的 TURN 服务器(Coturn)

在这种情况下,将 mod_stun_disco 更改为这个,并且不启用 STUN/TURN 的 listen 选项。生成认证密钥并将其与 TURN 服务器实例共享。

  mod_stun_disco:
    secret: "auth_secret"
    services:
      -
        host: turn.example.net
        type: stun
      -
        host: turn.example.net
        type: turn

最初改编自:blos.sm

支持聊天

这显然不是详尽的列表,如果您有很好的建议,请在此处联系我们: servers@joinjabber.org (web 聊天) (xmpp)