ejabberd.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. XMPP 服务器配置指南
  2. ===========================
  3. XMPP 是一个具有高度扩展性的通讯协议。在自由软件和黑客社区中,XMPP 被广泛使用,它具有以下特点:
  4. - 去中心化的联邦式协议
  5. - 有成熟的客户端和服务端软件
  6. + 桌面客户端:Gajim, Psi/Psi+, Pidgin/Adium, Dino, Bitlbee, weechat
  7. + Android客户端:Conversations, Xabber
  8. + iOS客户端:ChatSecure/Zom
  9. + 服务端:ejabberd, prosody, openfire
  10. - 大多数客户端支持端到端加密:OpenPGP, OTR, OMEMO
  11. - 服务器开销低
  12. 以下我将介绍如何用 ejabberd 搭建一个支持多种常用 XMPP 扩展(XEP) 的 XMPP 服务器。
  13. ejabberd 简介
  14. -------------
  15. ejabberd 是一个用 Erlang 编写的 XMPP 服务器。Erlang 是一个函数式编程语言,它的并发模型非常适用于编写高并发程序。ejabberd 可以在一个节点上处理百万量级的并发请求。Conversations 官方组建的服务器 conversations.im 即使用 ejabberd,并且 Conversations 社区的人也有参与 ejabberd 的开发。
  16. ejabberd 每几个月会发布一个更新。我的服务器使用滚动更新的发行版 Arch Linux,它的软件仓库中的 ejabberd 在新版本的 tarball 出来之后就会更新,从而我可以一直使用最新版的 ejabberd. ejabberd 在新的版本中会改变一些配置文件的配置项,因此建议管理员在使用最新的 ejabberd 时参考官方的文档。以下我的配置文件基于最新的 ejabberd 18.04 版本。
  17. ejabberd 配置
  18. --------------
  19. ejabberd 的配置文件为 YAML 格式。Arch 的 ejabberd 的配置文件为 /etc/ejabberd/ejabberd.yml.
  20. 首先是配置域名。一个 XMPP 服务器可以提供多个域名的 XMPP 服务,例如我的 XMPP 服务器有 cnjabber.net 和 wehack.space 两个域名,就在配置文件中写::
  21. hosts:
  22. - "cnjabber.net"
  23. - "wehack.space"
  24. 之后很重要的一点是 TLS 的配置。目前 XMPP 使用 STARTTLS 方案,和明文传输同使用 5222 端口,建议强制使用 STARTTLS. 在新版的 ejabberd 中,TLS 密钥和证书的路径使用 ``certfiles`` 配置项指定。
  25. ::
  26. certfiles:
  27. - "/etc/letsencrypt/live/cnjabber.net/*.pem"
  28. - "/etc/letsencrypt/live/wehack.space/*.pem"
  29. define_macro:
  30. 'CIPHERS': "ECDHE+CHACHA20:ECDHE+AESGCM:DHE+AESGCM:DHE+CHACHA20:!3DES:!aNULL:!eNULL:!MEDIUM@STRENGTH"
  31. 'TLSOPTS':
  32. - "no_sslv2"
  33. - "no_sslv3"
  34. - "no_tlsv1"
  35. - "no_tlsv1_1"
  36. - "cipher_server_preference"
  37. - "no_compression"
  38. 'DHFILE': "/etc/ejabberd/dhparam.pem"
  39. listen:
  40. -
  41. port: 5222
  42. ip: "::"
  43. module: ejabberd_c2s
  44. starttls: true
  45. protocol_options: 'TLSOPTS'
  46. dhfile: 'DHFILE'
  47. ciphers: 'CIPHERS'
  48. starttls_required: true
  49. max_stanza_size: 65536
  50. shaper: c2s_shaper
  51. access: c2s
  52. -
  53. port: 5269
  54. ip: "::"
  55. module: ejabberd_s2s_in
  56. ###. ==================
  57. ###' S2S GLOBAL OPTIONS
  58. s2s_use_starttls: required
  59. s2s_protocol_options: 'TLSOPTS'
  60. s2s_dhfile: 'DHFILE'
  61. s2s_ciphers: "ECDHE+HIGH:DHE+HIGH:!SHA1"
  62. 在这里,我们用 TLSOPTS 宏指定禁用 TLS 1.2 之前的 TLS 协议,CIPHERS 宏指定 TLS cipher suite 使用带有前向安全和 AEAD 的算法,为了服务器间的兼容性,在 s2s_ciphers 中我放松了一点 cipher suite 的要求。注意 listen 中的 starttls_required 和 s2s_use_starttls, 我都设置为必须启用加密连接。
  63. certfiles 中是我的 Let's Encrypt 证书和密钥的路径,所有 ejabberd 要用的都要列出来。DHFILE 是 DHE 密钥交换需要的的密钥交换参数,可以用 ``openssl dhparam 3072`` 生成一份。
  64. 之后是 ejabberd 模块的配置。ejabberd 支持的很多特性,包括 XMPP 扩展,都通过它的模块实现。这里我介绍几个比较常用的模块:
  65. - mod_pubsub: pubsub 扩展协议的支持,OMEMO 端到端加密需要用基于 pubsub 的 PEP 扩展发布用户公钥等信息,因此还建议在它下面的 plugins 配置中要加上 pep,注意 ejabberd 默认文件的注释中注明 pep 需要 mod_caps,因此还要启用 mod_caps.
  66. - mod_stream_mgmt: 流管理,建议启用。
  67. - mod_mam: 消息存档管理,对于存储离线消息有用,建议启用。
  68. - mod_http_upload: HTTP 文件上传扩展,有了它,用户可以向 XMPP 服务器上传文件供其他人下载。
  69. - mod_muc: 多人聊天,如果你需要允许用户建立在服务器上的聊天室,需要启用。不启用此模块并不影响使用其他服务器的聊天室。
  70. - mod_version: 启用它可以使其他人查询服务器使用的软件及其版本,我选择禁用它以避免攻击者探测服务器软件及版本。
  71. - mod_register: 启用它可以使用户在服务器上注册帐号,此外,已有用户修改密码也需要此模块,因此建议启用。如果不想开放注册,可以修改相关权限选项禁用注册。
  72. 因此,最终我的配置文件中的相关选项如下::
  73. ##
  74. ## Modules enabled in all ejabberd virtual hosts.
  75. ##
  76. modules:
  77. mod_caps: {}
  78. mod_http_upload:
  79. host: "file.@HOST@"
  80. docroot: "/srv/http/sites/jabber-file/@HOST@"
  81. put_url: "https://file.@HOST@/put"
  82. get_url: "https://file.@HOST@"
  83. mod_http_upload_quota:
  84. max_days: 7
  85. mod_mam: {} # for xep0313, mnesia is limited to 2GB, better use an SQL backend
  86. mod_pubsub:
  87. access_createnode: pubsub_createnode
  88. ignore_pep_from_offline: true
  89. last_item_cache: false
  90. plugins:
  91. - "flat"
  92. - "hometree"
  93. - "pep" # pep requires mod_caps
  94. mod_register:
  95. captcha_protected: true
  96. password_strength: 32
  97. access_from: deny
  98. access: register
  99. ## mod_version: {}
  100. mod_stream_mgmt: {}
  101. HTTP上传及 web 服务器的配置
  102. -----------------------------
  103. 在以上配置中,我启用了 HTTP 上传,因此在 ejabberd 的 listen 部分要加上 HTTP 上传相关的配置::
  104. listen:
  105. -
  106. port: 5222
  107. ip: "::"
  108. module: ejabberd_c2s
  109. # ...
  110. # ...
  111. -
  112. port: 5444
  113. ip: "127.0.0.1"
  114. module: ejabberd_http
  115. request_handlers:
  116. "": mod_http_upload
  117. tls: false
  118. 在这里,我把 HTTP 上传服务设置为 127.0.0.1 的 5444 端口,并且不开 TLS,我要用我的 HTTP 服务器把对外的 HTTP 请求转发到这个端口。
  119. 同时,在 mod_http_upload 中,我设置了 docroot,我要在 HTTP 服务器中设置好文件路径,使得用户可以下载上传的文件。
  120. 我用的 HTTP 服务器是 Caddy, 对域名 wehack.space 的相关配置如下::
  121. https://file.wehack.space {
  122. tls /etc/letsencrypt/live/wehack.space/fullchain.pem /etc/letsencrypt/live/wehack.space/privkey.pem {
  123. protocols tls1.2 tls1.2
  124. must_staple
  125. }
  126. header / {
  127. Strict-Transport-Security "max-age=31536000;"
  128. X-XSS-Protection "1; mode=block"
  129. X-Content-Type-Options "nosniff"
  130. X-Frame-Options "SAMEORIGIN"
  131. }
  132. proxy /put 127.0.0.1:5444 {
  133. transparent
  134. }
  135. root /srv/http/sites/jabber-file/wehack.space
  136. }
  137. 对其他域名也需要进行这样的配置。于是对 HTTP 上传的支持就配置好了。
  138. 总结
  139. ----
  140. 以上是我配置 ejabberd XMPP 服务器的一些笔记。最后,我们启动服务后,用 Conversations 或 Gajim 连接配置好的 XMPP 服务器后,可以查看服务器信息,看看想要的 XEP 是否已经启用。
  141. 如果有什么疑问,欢迎和我交流。