Песочница
В этой статье приводится пример конфигурирования ejabberd с поддержкой актуальных и популярных функций. В качестве основы взят конфиг-файл с работающего сервера версии 21.12, а в качестве сертификатов используется Let's Encrypt - и все это установлено на Debian GNU/Linux.
Рассмотрим особенности данной конфигурации.
DNS-записи
Хотя для базового варианта своего jabber-сервера вполне достаточно бесплатного DynDNS-домена, для полноценной конфигурации все же нужно обзавестись собственным доменом, где можно будет добавить все необходимые DNS-записи и сделать субдомены для сервисов. Выбор регистратора и покупка домена остается за рамками данной статьи, тут только приводятся шаги, которые надо сделать после покупки домена в его админке.
Всего понадобится около 15 записей в DNS:
- Для удобства, чтобы в случае миграции сервера с одного IP на другой не приходилось переписывать все записи, стоит завести для него субдомен, который будет ссылаться на нужный IP с помощью А-записи (или 2 таких субдомена в случае использования IPv4+IPv6 - один с A-записью, а второй с AAAA), а все остальные записи сделать CNAME-алиасами для него. Например, для данного сервера (jabberworld.info) сделаны 2 субдомена xmpp.jabberworld.info, ссылающиеся на IPv4 и IPv6-адреса.
- Создаем субдомены для необходимых сервисов сервера - conference (для конференций), proxy (прокси для прямой передачи файлов), pubsub (сервисы типа "Публикация/подписка", где может сохраняться самая разная информация) и upload (сервис для передачи файлов через HTTP Upload). Все эти записи создаем как CNAME на наш субдомен из 1-го пункта.
- Создаем ряд SRV-записей для нашего основного домена - они показывают, где именно какой сервис находится. Конечно, если у вас все на одном адресе, то будет работать и так, но мы ведь решили все делать правильно, верно? Итак, нужны такие SRV-записи:
- _xmpp-client._tcp.EXAMPLE.COM (порт 5222) - чтобы указать, куда подключаться jabber-клиенту
- _xmpps-client._tcp.EXAMPLE.COM (порт 5223) - аналогичная запись для TLS-подключений клиентов
- _xmpp-server._tcp.EXAMPLE.COM (порт 5269) - чтобы указать, куда подключаться jabber-серверу
- _xmpps-server._tcp.EXAMPLE.COM (порт 5270) - аналогичная запись для TLS-подключений серверов.
- Записи ниже служат для работы сервиса аудио/видеозвонков через jabber:
- _stun._tcp.EXAMPLE.COM (порт 3478) - STUN через TCP
- _stun._udp.EXAMPLE.COM (порт 3478) - STUN через UDP
- _stuns._tcp.EXAMPLE.COM (порт 5349) - шифрованный STUN через TCP
- _turn._tcp.EXAMPLE.COM (порт 3478) - TURN через TCP
- _turn._udp.EXAMPLE.COM (порт 3478) - TURN через UDP
- _turns._tcp.EXAMPLE.COM (порт 5349) - шифрованный TURN через TCP
- Во всех случаях target'ом для записей служит наш алиас из первого пункта.
Вот как выглядят записи для данного сервера в админке бесплатного DNS-провайдера Hurricane Electric:
Сертификаты
В современном мире стандартной практикой является шифрование соединений, а для этого, в свою очередь, требуются сертификаты от доверенных центров сертификации. Можно, конечно, использовать самоподписанный сертификат, но, во-первых, не все серверы будут их принимать - а значит, к ним не получится подключиться и общаться с их пользователями, а во-вторых, в подключающихся клиентах будут появляться сообщения о недоверенном сертификате, что тоже будет доставлять определенные неудобства. Поэтому стоит воспользоваться услугами одного из популярных бесплатных центров сертификации - Let's Encrypt.
Для работы с сертификатами от Let's Encrypt в Debian есть специальный пакет - certbot, поэтому установите его следующей командой:
sudo apt-get install certbot
Сертификаты от Let's Encrypt выдаются сроком на 3 месяца, поэтому в конце этого срока их нужно обновлять. Для подтверждения владения доменом, а также для автоматизации обновления сертификатов в дальнейшем со стороны Let's Encrypt делается запрос на веб-сервер для указанного домена, поэтому для полноценной работы стоит установить какой-нибудь популярный вариант и прописать там виртуальные хосты для нашего jabber-сервера, а также сервисов на нем (сертификаты будут делаться в том числе для сервисов). Пример конфигурации веб-сервера Apache для данного сервера:
<VirtualHost 185.161.208.229:80 [2a07:c801:0:5::]:80> ServerAdmin webmaster@jabberworld.info DocumentRoot /var/www/jabberworld.info/htdocs ServerName jabberworld.info </VirtualHost> <VirtualHost 185.161.208.229:80 [2a07:c801:0:5::]:80> ServerAdmin webmaster@upload.jabberworld.info DocumentRoot /var/www/upload.jabberworld.info/htdocs ServerName upload.jabberworld.info </VirtualHost> <VirtualHost 185.161.208.229:80 [2a07:c801:0:5::]:80> ServerAdmin webmaster@pubsub.jabberworld.info DocumentRoot /var/www/pubsub.jabberworld.info/htdocs ServerName pubsub.jabberworld.info </VirtualHost> <VirtualHost 185.161.208.229:80 [2a07:c801:0:5::]:80> ServerAdmin webmaster@conference.jabberworld.info DocumentRoot /var/www/conference.jabberworld.info/htdocs ServerName conference.jabberworld.info </VirtualHost> <VirtualHost 185.161.208.229:80 [2a07:c801:0:5::]:80> ServerAdmin webmaster@proxy.jabberworld.info DocumentRoot /var/www/proxy.jabberworld.info/htdocs ServerName proxy.jabberworld.info </VirtualHost>
В каталогах сервера не обязательно должен быть какой-то контент, хотя, например, на основном домене можно разместить какую-то страничку, посвященную jabber-серверу, а на поддомене conference разместить чат-логи конференций. Субдомен upload можно приспособить под загружаемые через HTTP Upload файлы, чтобы в дальнейшем их раздавал веб-сервер.
После всех приготовлений создайте все необходимые сертификаты. Для этого воспользуйтесь следующими командами (выполнять надо от пользователя root):
certbot certonly --webroot --webroot-path /var/www/EXAMPLE.COM/htdocs/ -d EXAMPLE.COM certbot certonly --webroot --webroot-path /var/www/conference.EXAMPLE.COM/htdocs/ -d conference.EXAMPLE.COM certbot certonly --webroot --webroot-path /var/www/upload.EXAMPLE.COM/htdocs/ -d upload.EXAMPLE.COM certbot certonly --webroot --webroot-path /var/www/pubsub.EXAMPLE.COM/htdocs/ -d pubsub.EXAMPLE.COM certbot certonly --webroot --webroot-path /var/www/proxy.EXAMPLE.COM/htdocs/ -d proxy.EXAMPLE.COM
В параметрах после --webroot-path указывается каталог веб-сервера для данного домена, а после -d - сам домен.
После успешного выполнения команд будет выдана информация о созданном сертификате, в том числе 2 файла - цепочка ключей и приватный ключ - сохраните эти пути для дальнейшего использования, они нам еще пригодятся. Всего получится 10 файлов. certbot обновляет сертификаты автоматически, если срок их истечения составляет менее 30 дней - т.е., обновление происходит раз в 2 месяца.
Так как ejabberd работает от своего пользователя и не имеет доступа к сертификатам, созданным certbot от рута, то надо каким-то образом предоставить доступ ejabberd'у к сертификатам. Делать это можно по-разному - кто-то, например, меняет права на созданные сертификаты и добавляет возможность ejabberd'у получать доступ к нужным файлам - правда, эти права сбрасываются после каждого обновления сертификатов. В моем случае я создал для ejabberd отдельный каталог - /etc/ejabberd/certs, куда копируются по cron'у созданные сертификаты и уже там даются права для jabber-сервера.
Настройка ejabberd
Все подготовительные процедуры завершены, теперь можно приступать непосредственно к установке и настройке своего jabber-сервера. В Debian установить ejabberd можно командой
sudo apt-get install ejabberd
Зачастую самая свежая версия может находиться в backports, поэтому при необходимости можно указать конкретный репозиторий из вашего /etc/apt/sources.list с помощью ключа -t - например, -t bullseye-backports. Кроме того, с недавних пор у ejabberd появился официальный DEB и RPM-репозиторий - подробнее об этом можно почитать по этой ссылке.
Штатно ejabberd использует собственную базу данных - Mnesia. Ее объем ограничен 2 ГБ, поэтому если планируется большое количество пользователей, большие объемы сообщений или просто хочется использовать удобные популярные инструменты для работы с привычной вам базой - я бы рекомендовал использовать внешнюю базу данных - например, MySQL или MariaDB. Я так и поступил, тем более сделать это весьма просто - кроме ejabberd просто установите еще пакет erlang-p1-mysql командой
sudo apt-get install erlang-p1-mysql
Создайте базу для jabber-сервера, после чего импортируйте туда схему базы из /usr/share/ejabberd/sql/mysql.sql.
Ниже приводится пример конфигурации jabber-сервера. Рассмотрим его подробнее.
### ### ejabberd configuration file ### ### The parameters used in this configuration file are explained at ### ### https://docs.ejabberd.im/admin/configuration ### ### The configuration file is written in YAML. ### ******************************************************* ### ******* !!! WARNING !!! ******* ### ******* YAML IS INDENTATION SENSITIVE ******* ### ******* MAKE SURE YOU INDENT SECTIONS CORRECTLY ******* ### ******************************************************* ### Refer to http://en.wikipedia.org/wiki/YAML for the brief description. ### However, ejabberd treats different literals as different types: ### ### - unquoted or single-quoted strings. They are called "atoms". ### Example: dog, 'Jupiter', '3.14159', YELLOW ### ### - numeric literals. Example: 3, -45.0, .0 ### ### - quoted or folded strings. ### Examples of quoted string: "Lizzard", "orange". ### Example of folded string: ### > Art thou not Romeo, ### and a Montague? ### # --- ## loglevel: Verbosity of log files generated by ejabberd ## 0: No ejabberd log at all (not recommended) ## 1: Critical ## 2: Error ## 3: Warning ## 4: Info ## 5: Debug loglevel: 4 ## rotation: Disable ejabberd's internal log rotation, as the Debian package ## uses logrotate(8). log_rotate_count: 0 #log_rotate_date: "" ## hosts: Domains served by ejabberd. ## You can define one or several, for example: ## hosts: ## - "example.net" ## - "example.com" ## - "example.org" hosts: - "EXAMPLE.COM" certfiles: - "/etc/ejabberd/certs/conference.EXAMPLE.COM.fullchain.pem" - "/etc/ejabberd/certs/conference.EXAMPLE.COM.privkey.pem" - "/etc/ejabberd/certs/EXAMPLE.COM.fullchain.pem" - "/etc/ejabberd/certs/EXAMPLE.COM.privkey.pem" - "/etc/ejabberd/certs/pubsub.EXAMPLE.COM.fullchain.pem" - "/etc/ejabberd/certs/pubsub.EXAMPLE.COM.privkey.pem" - "/etc/ejabberd/certs/upload.EXAMPLE.COM.fullchain.pem" - "/etc/ejabberd/certs/upload.EXAMPLE.COM.privkey.pem" - "/etc/ejabberd/certs/proxy.EXAMPLE.COM.fullchain.pem" - "/etc/ejabberd/certs/proxy.EXAMPLE.COM.privkey.pem" ## TLS configuration define_macro: 'TLS_CIPHERS': "HIGH:!aNULL:!eNULL:!3DES:@STRENGTH" 'TLS_OPTIONS': - "no_sslv3" # - "no_tlsv1" # - "no_tlsv1_1" - "cipher_server_preference" - "no_compression" ## generated with: openssl dhparam -out dhparams.pem 2048 c2s_ciphers: 'TLS_CIPHERS' s2s_ciphers: 'TLS_CIPHERS' c2s_protocol_options: 'TLS_OPTIONS' s2s_protocol_options: 'TLS_OPTIONS' ## c2s_dhfile: 'DH_FILE' s2s_dhfile: "/etc/ejabberd/dhparams.pem" listen: - port: 3478 ip: "::" transport: udp module: ejabberd_stun auth_realm: "@HOST@" use_turn: true ## The server's public IPv4 address: turn_ipv4_address: "123.123.123.123" ## The server's public IPv6 address: turn_ipv6_address: "2a01:0123:0123:0123::" - port: 3478 ip: "::" transport: tcp module: ejabberd_stun auth_realm: "@HOST@" use_turn: true ## The server's public IPv4 address: turn_ipv4_address: "123.123.123.123" ## The server's public IPv6 address: turn_ipv6_address: "2a01:0123:0123:0123::" - port: 5349 transport: tcp module: ejabberd_stun use_turn: true tls: true ip: "::" ## The server's public IPv4 address: turn_ipv4_address: "123.123.123.123" ## The server's public IPv6 address: turn_ipv6_address: "2a01:0123:0123:0123::" - port: 5000 ip: "::" module: ejabberd_http tls: true request_handlers: /conversejs: mod_conversejs /: mod_http_fileserver - port: 5222 ip: "::" module: ejabberd_c2s max_stanza_size: 262144 shaper: c2s_shaper access: c2s zlib: true starttls_required: true protocol_options: 'TLS_OPTIONS' - port: 5223 ip: "::" module: ejabberd_c2s max_stanza_size: 262144 shaper: c2s_shaper access: c2s tls: true zlib: true starttls_required: true protocol_options: 'TLS_OPTIONS' - port: 5269 ip: "::" module: ejabberd_s2s_in max_stanza_size: 524288 - port: 5270 ip: "::" tls: true module: ejabberd_s2s_in max_stanza_size: 524288 - port: 5280 ip: "::" module: ejabberd_http request_handlers: "/captcha": ejabberd_captcha tls: true - port: 5281 ip: "::" module: ejabberd_http request_handlers: "/admin": ejabberd_web_admin tls: true - port: 5282 ip: "::" module: ejabberd_http request_handlers: "/captcha": ejabberd_captcha "/register": mod_register_web tls: true - port: 5283 ip: "::" module: ejabberd_http request_handlers: "/api": mod_http_api "/bosh": mod_bosh "/upload": mod_http_upload "/ws": ejabberd_http_ws "/captcha": ejabberd_captcha tls: true ## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text ## password storage (see auth_password_format option). disable_sasl_mechanisms: - "digest-md5" - "X-OAUTH2" s2s_use_starttls: required ## Store the plain passwords or hashed for SCRAM: auth_password_format: scram ## Full path to a script that generates the image. captcha_cmd: "/usr/share/ejabberd/captcha.sh" #captcha_url: "https://xmpp.EXAMPLE.COM:5282" captcha_host: "https://EXAMPLE.COM:5282" acl: admin: user: - "ADMIN": "EXAMPLE.COM" local: user_regexp: "" loopback: ip: - "127.0.0.0/8" - "::1/128" - "::FFFF:127.0.0.1/128" access_rules: local: - allow: local c2s: - deny: blocked - allow announce: - allow: admin configure: - allow: admin muc_create: - allow: local muc: - allow pubsub_createnode: - allow: local register: - allow trusted_network: - allow: loopback #webadmin_view: # - viewers: allow api_permissions: "console commands": from: - ejabberd_ctl who: all what: "*" "admin access": who: - access: - allow: - acl: loopback - acl: admin - oauth: - scope: "ejabberd:admin" - access: - allow: - acl: loopback - acl: admin what: - "*" - "!stop" - "!start" "public commands": who: - ip: "127.0.0.1/8" what: - "status" - "connected_users_number" shaper: normal: 2500 fast: 50000 shaper_rules: max_user_sessions: 25 max_user_offline_messages: - 5000: admin - 200 c2s_shaper: - none: admin - normal s2s_shaper: fast modules: mod_adhoc: {} mod_admin_extra: {} mod_announce: access: announce mod_avatar: {} mod_blocking: {} mod_bosh: {} mod_caps: {} mod_carboncopy: {} mod_client_state: {} mod_configure: {} ## mod_delegation: {} # for xep0356 mod_disco: server_info: - modules: all name: "abuse-addresses" urls: - "xmpp:ADMIN@EXAMPLE.COM" - "mailto:ADMIN@EXAMPLE.COM" - modules: [mod_muc] name: "Web chatroom logs" urls: ["https://chatlogs.EXAMPLE.COM"] - modules: all name: "support-addresses" urls: - "xmpp:ADMIN@EXAMPLE.COM" - "xmpp:support@conference.EXAMPLE.COM?join" - "https://my.cool.site" mod_fail2ban: {} mod_http_api: {} mod_http_upload: put_url: "https://@HOST@:5283/upload" thumbnail: false jid_in_url: sha1 custom_headers: "Access-Control-Allow-Origin": "*" "Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS" "Access-Control-Allow-Headers": "Content-Type" mod_http_upload_quota: max_days: 180 mod_mam: ## ## Mnesia is limited to 2GB, better to use an SQL backend ## ## For small servers SQLite is a good fit and is very easy ## ## to configure. Uncomment this when you have SQL configured: db_type: sql assume_mam_usage: true default: roster compress_xml: true use_cache: true cache_life_time: 86400 mod_muc: access: - allow access_admin: - allow: admin access_create: muc_create access_persistent: muc_create default_room_options: mam: true mod_muc_admin: {} mod_offline: access_max_user_messages: max_user_offline_messages mod_muc_log: outdir: "/var/www/chatlogs" access_log: muc cssfile: /var/www/chatlogs.EXAMPLE.COM/htdocs/muc.css #cssfile: http://chatlogs.EXAMPLE.COM/muc.css mod_ping: {} mod_pres_counter: count: 5 interval: 60 mod_privacy: {} mod_private: {} mod_proxy65: # remove ip? ip: 123.123.123.123 access: local max_connections: 10 mod_pubsub: access_createnode: pubsub_createnode plugins: - "flat" - "pep" force_node_config: "eu.siacs.conversations.axolotl.*": access_model: open ## Avoid buggy clients to make their bookmarks public "storage:bookmarks": access_model: whitelist mod_push: {} mod_push_keepalive: {} mod_register: ## Only accept registration requests from the "trusted" ## network (see access_rules section above). ## Think twice before enabling registration from any ## address. See the Jabber SPAM Manifesto for details: ## https://github.com/ge0rg/jabber-spam-fighting-manifesto #ip_access: trusted_network ip_access: all captcha_protected: true registration_watchers: - "ADMIN@EXAMPLE.COM" welcome_message: subject: "Добро пожаловать на Jabber-сервер!" body: "Приветствую. Ведите себя хорошо. Доступен веб-клиент ConverseJS по адресу https://xmpp.EXAMPLE.COM. Лимит на загружаемые файлы - 100 МБ. Срок хранения - 180 дней." mod_roster: versioning: true mod_s2s_dialback: {} mod_shared_roster: {} mod_sic: {} mod_stream_mgmt: resend_on_timeout: if_offline mod_vcard: search: false mod_stun_disco: services: - host: 123.123.123.123 port: 3478 type: stun transport: udp restricted: false - host: 123.123.123.123 port: 3478 type: turn transport: udp restricted: true - host: 123.123.123.123 port: 3478 type: stun transport: tcp restricted: false - host: 123.123.123.123 port: 3478 type: turn transport: tcp restricted: true - host: "2a01:0123:0123:0123::" port: 3478 type: stun transport: udp restricted: false - host: "2a01:0123:0123:0123::" port: 3478 type: turn transport: udp restricted: true - host: "2a01:0123:0123:0123::" port: 3478 type: stun transport: tcp restricted: false - host: "2a01:0123:0123:0123::" port: 3478 type: turn transport: tcp restricted: true - host: EXAMPLE.COM port: 5349 type: stuns transport: tcp restricted: false - host: EXAMPLE.COM port: 5349 type: turns transport: tcp restricted: true mod_vcard_xupdate: {} mod_version: show_os: false mod_stats: {} mod_last: {} # mod_time: {} mod_conversejs: websocket_url: "wss://EXAMPLE.COM:5283/ws" conversejs_script: "https://EXAMPLE.COM:5000/converse.min.js" conversejs_css: "https://EXAMPLE.COM:5000/converse.min.css" # bosh_service_url: "https://EXAMPLE.COM:5283/bosh" default_domain: "EXAMPLE.COM" mod_http_fileserver: docroot: "/var/www/ejabberd/package/dist" accesslog: "/var/log/ejabberd/fileserver-access.log" custom_headers: "Access-Control-Allow-Origin": "*" "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS" "Access-Control-Allow-Headers": "Content-Type" default_db: sql sql_type: mysql sql_server: "localhost" host_config: "EXAMPLE.COM": sql_database: "JABBERDB" sql_username: "DBUSER" sql_password: "SUPERPASSWORD" sql_port: 3306 language: "ru" ### Local Variables: ### mode: yaml ### End: ### vim: set filetype=yaml tabstop=8
- Первым делом указывается один или несколько хостов, которые будет обслуживать сервер - в конфигурационном файле выше он указан как EXAMPLE.COM.
- Далее надо указать перечень файлов сертификатов, которые мы создали раньше.
- Секция Listen описывает порты, которые слушает сервер. Тут перечисляются порты для STUN/TURN (3478) и их шифрованных аналогов (5349); порты для подключения клиентов (5222 и 5223) и серверов (5269 и 5270), а также ряд дополнительных портов. К ним относятся порты для админ-панели сервера (5281), веб-страницы для регистрации пользователей (5282), а также подключений к серверу через Websocket или BOSH и загрузка файлов через HTTP Upload (5283) - я постарался разнести различные сервисы по разным портам, чтобы в дальнейшем было проще, например, ограничить доступ к админ-панели определенными адресами, не блокируя при этом доступ к остальным функциям. Еще одним полезным сервисом является веб-клиент ConverseJS - под него выделен порт 5000 - о нем будет написано чуть ниже. Для некоторых описанных портов необходимо указывать внешний IP-адрес сервера - это нужно, чтобы сервис знал, какой именно адрес отдавать клиентам - это относится к настройкам STUN/TURN и Proxy. В качестве шаблона в показанном конфиге указаны адреса 123.123.123.123 для IPv4 и 2a01:0123:0123:0123:: для IPv6 - если не используете IPv6, то просто закомментируйте соответствующие строки.
- Далее необходимо указать хост, с которого будет отдаваться картинка CAPTCHA.
- Далее указывается один или несколько администраторских аккаунтов - с помощью них можно будет попасть в веб-интерфейс администрирования, зайти в любую конференцию, а также в браузере сервисов будут доступны дополнительные административные пункты.
- После настроек шейпера идет довольно объемное описание различных модулей. Из интересного:
- В server-info для mod_disco можно указать контакты администратора сервера, техподдержки или просто дополнительную информацию.
- В mod_http_upload можно указать адрес, с которого будут отдаваться загруженные на сервер через HTTP Upload файлы. При желании можно использовать не встроенный веб-сервер, а тот веб-сервер, что был настроен для получения сертификатов. Чуть ниже этой опции есть настройка времени устаревания файлов - в примере выше это 180 дней. Если у вас мало места на сервере, то можно поставить это значение поменьше.
- Аналогичным образом можно поступить с mod_muc_log - модулем, позволяющим вести логи конференций (при включении соответствующей опции в настройках этой конференции). В примере выше файлы просто складываются в определенный каталог, а дальше их уже раздает веб-сервер.
- Для модуля proxy65 не забудьте указать внешний адрес сервера.
- Если хотите получать уведомления о новых регистрациях - обратите внимание на параметр registration_watchers в секции mod_register. Тут в том числе можно запретить регистрацию пользователей вообще или ограничить ее определенными адресами (например, локальной сетью), а также задать приветственное сообщение, отправляемое каждому новому пользователю.
- Ниже идет большой блок параметров STUN/TURN-сервера. Укажите внешние IP-адреса сервера и обслуживаемый домен; если у сервера нет IPv6-адреса - закомментируйте соответствующие блоки.
- Предпоследней настройкой в секции модулей идет настройка веб-клиента ConverseJS. В ejabberd 21.12 настройки весьма базовые, но над этим модулем активно идет работа. В минимальном варианте конфигурации можно просто указать Websocket-адрес для подключения к серверу (мы его объявляли в секции Listen). Можно даже не указывать файлы ConverseJS - по умолчанию они могут загружаться напрямую с сайта ConverseJS. Но если хочется большей автономности, то можно сделать так, чтобы их отдавал свой сервер. В свою очередь не обязательно их отдавать через встроенный в ejabberd веб-сервер - для этого можно использовать тот, что настроен для сертификатов - в этом есть даже определенные преимущества: например, файлы могут прозрачно сжиматься перед передачей клиенту, что обеспечит более быструю загрузку интерфейса ConverseJS. Если же хочется более продвинутой конфигурации ConverseJS (например, анонимный чат на сайте для работы техподдержки), то это делается передачей опций через специальную индексную страницу, но это уже выходит за рамки данного руководства.
- Ну и последней опции, требующей вмешательства, являются параметры подключения к созданной ранее базе данных. Если используется несколько виртуальных хостов для ejabberd - можно указать несколько баз через опцию host_config.