Свой сервер: подробное руководство по установке Prosody: различия между версиями

Материал из Мир Jabber
Перейти к навигацииПерейти к поиску
м (+ mod_throttle_presence)
(Для автоподгрузки сертификатов)
Строка 170: Строка 170:
  prosodyctl install --server=https://modules.prosody.im/rocks/ mod_mam_adhoc # Возможность управлять настройками MAM-архива из jabber-клиента
  prosodyctl install --server=https://modules.prosody.im/rocks/ mod_mam_adhoc # Возможность управлять настройками MAM-архива из jabber-клиента
  prosodyctl install --server=https://modules.prosody.im/rocks/ mod_throttle_presence # Ограничиваем трафик статусов
  prosodyctl install --server=https://modules.prosody.im/rocks/ mod_throttle_presence # Ограничиваем трафик статусов
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_reload_modules # Ставим для возможности обновлять сертификаты без перезагрузки


Конфигурационный файл у Prosody состоит из нескольких секций:
Конфигурационный файл у Prosody состоит из нескольких секций:
Строка 279: Строка 280:
"external_services"; -- calls
"external_services"; -- calls
"admin_adhoc"; -- ad-hoc administration of server
"admin_adhoc"; -- ad-hoc administration of server
        "reload_modules";
}
}
reload_modules = { "groups", "tls" }


-- These modules are auto-loaded, but should you want
-- These modules are auto-loaded, but should you want

Версия 15:59, 15 ноября 2024

В этой статье приводится пример настройки Prosody - одного из самых популярных и легковесных jabber-серверов. Для сервера написано просто-таки огромное число модулей на все случаи жизни, поэтому в руководстве, основанном на версии 0.12.4, будет показано подключение актуальных и популярных функций. В качестве сертификатов будем использовать Let's Encrypt, а в качестве хранилища данных, в том числе архива сообщений - MySQL[1] - и все это на Debian GNU/Linux.

Рассмотрим особенности данной конфигурации.

DNS-записи

Хотя для базового варианта своего jabber-сервера вполне достаточно бесплатного DynDNS-домена, для полноценной конфигурации все же нужно обзавестись собственным доменом, где можно будет добавить все необходимые DNS-записи и сделать субдомены для сервисов. Выбор регистратора и покупка домена остается за рамками данной статьи, тут только приводятся шаги, которые надо сделать после покупки домена в его админке.

Всего понадобится около 15 записей в DNS:

  1. Для удобства, чтобы в случае миграции сервера с одного IP на другой не приходилось переписывать все записи, стоит завести для него субдомен, который будет ссылаться на нужный IP с помощью А-записи (или 2 таких субдомена в случае использования IPv4+IPv6 - один с A-записью, а второй с AAAA), а все остальные записи сделать CNAME-алиасами для него. Например, для данного сервера (jabberworld.info) сделаны 2 субдомена xmpp.jabberworld.info, ссылающиеся на IPv4 и IPv6-адреса.
  2. Создаем субдомены для необходимых сервисов сервера[2] - conference (для конференций), proxy (прокси для прямой передачи файлов), pubsub (сервисы типа "Публикация/подписка", где может сохраняться самая разная информация) и upload (сервис для передачи файлов через HTTP Upload). Все эти записи создаем как CNAME на наш субдомен из 1-го пункта.
  3. Создаем ряд 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[3]. Для максимальной совместимости будем использовать как STUN, так и TURN - все возможные варианты:
_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'ом для записей служит наш алиас из первого пункта.
Для продвинутых
Самый полный вариант подразумевает в том числе создание SRV-записей для каждого из сервисов-субдоменов - тех, к которым будут подключаться сторонние серверы. Например, для конференций это может выглядеть так:
_xmpp-server._tcp.conference.EXAMPLE.COM (порт 5269)
_xmpps-server._tcp.conference.EXAMPLE.COM (порт 5270 для TLS)
Но, как уже говорилось выше, это для совсем уж необычных конфигураций - когда сам домен указывает на один адрес (например, там может работать веб-сервер, предоставляющий чат-логи на сайте https://conference.example.com), а сам jabber-сервер при этом находится совершенно на другом.

Вот как выглядят записи для данного сервера в админке бесплатного DNS-провайдера Hurricane Electric:

Jabber srv.png

Сертификаты

В современном мире стандартной практикой является шифрование соединений, а для этого, в свою очередь, требуются сертификаты от доверенных центров сертификации. Можно, конечно, использовать самоподписанный сертификат, но, во-первых, не все серверы будут их принимать - а значит, к ним не получится подключиться и общаться с их пользователями, а во-вторых, в подключающихся клиентах будут появляться сообщения о недоверенном сертификате, что тоже будет доставлять определенные неудобства. Поэтому стоит воспользоваться услугами одного из популярных бесплатных центров сертификации - Let's Encrypt.

Для работы с сертификатами от Let's Encrypt в Debian есть специальный пакет - certbot, поэтому установите его следующей командой:

sudo apt-get install certbot

Сертификаты от Let's Encrypt выдаются сроком на 3 месяца, поэтому в конце этого срока их нужно обновлять. Для подтверждения владения доменом, а также для автоматизации обновления сертификатов в дальнейшем со стороны Let's Encrypt делается запрос на веб-сервер для указанного домена, поэтому для полноценной работы стоит установить какой-нибудь популярный вариант и прописать там виртуальные хосты для нашего jabber-сервера, а также сервисов на нем (сертификаты будут делаться в том числе для сервисов). Пример конфигурации веб-сервера Apache для данного сервера:

apache_to_jabber_service_domains.conf
<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 файлы, чтобы в дальнейшем их раздавал веб-сервер[4].

После всех приготовлений[5] создайте все необходимые сертификаты. Для этого воспользуйтесь следующими командами (выполнять надо от пользователя root):

certbot certonly --webroot --webroot-path /var/www/EXAMPLE.COM/htdocs/ -d EXAMPLE.COM --rsa-key-size 4096
certbot certonly --webroot --webroot-path /var/www/conference.EXAMPLE.COM/htdocs/ -d conference.EXAMPLE.COM --rsa-key-size 4096
certbot certonly --webroot --webroot-path /var/www/upload.EXAMPLE.COM/htdocs/ -d upload.EXAMPLE.COM --rsa-key-size 4096
certbot certonly --webroot --webroot-path /var/www/pubsub.EXAMPLE.COM/htdocs/ -d pubsub.EXAMPLE.COM --rsa-key-size 4096
certbot certonly --webroot --webroot-path /var/www/proxy.EXAMPLE.COM/htdocs/ -d proxy.EXAMPLE.COM --rsa-key-size 4096

В параметрах после --webroot-path указывается каталог веб-сервера для данного домена, а после -d - сам домен.

После успешного выполнения команд будет выдана информация о созданном сертификате, в том числе 2 файла - цепочка ключей и приватный ключ - сохраните эти пути для дальнейшего использования, они нам еще пригодятся. Всего получится 10 файлов. certbot обновляет сертификаты автоматически, если срок их истечения составляет менее 30 дней - т.е., обновление происходит раз в 2 месяца.

Так как Prosody работает от своего пользователя и не имеет доступа к сертификатам, созданным certbot от рута, то надо каким-то образом предоставить серверу доступ к сертификатам. Самым простым и корректным вариантом на сейчас является выполнение следующей команды от рута[6]:

prosodyctl --root cert import /etc/letsencrypt/live

В дальнейшем эту команду можно использовать после каждого обновления сертификатов - например, указав ее в качестве deploy hook для certbot.

Установка и настройка Prosody

Все подготовительные процедуры завершены, теперь можно приступать непосредственно к установке и настройке своего jabber-сервера. Для поддержки звонков потребуется еще STUN/TURN-сервер - в качестве него будем использовать Coturn. В Debian установить Prosody с поддержкой MySQL[1] и Coturn можно командой

apt-get install prosody coturn lua-dbi-mysql

Примечание: на момент написания статьи самая последняя версия Prosody - 0.12.4 - доступна в репозитории backports. Чтобы установить сервер оттуда - добавьте к команде выше ключ -t bookworm-backports (само-собой, репозиторий должен быть прописан в /etc/apt/sources.list).

Настройку начнем с Coturn - она очень простая и сводится к включению сервиса в файле /etc/default/coturn опции TURNSERVER_ENABLED=1, а также приведению конфиг-файла /etc/turnserver.conf к такому виду:

/etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
verbose
use-auth-secret
static-auth-secret=MYSUPERSECRETKEY
userdb=/var/lib/turn/turndb
realm=EXAMPLE.COM
cert=/etc/turncerts/EXAMPLE.COM.fullchain.pem
pkey=/etc/turncerts/EXAMPLE.COM.privkey.pem
syslog
prod
no-multicast-peers
no-cli
no-tlsv1
no-tlsv1_1
no-rfc5780
no-stun-backward-compatibility
response-origin-only-with-rfc5780

Фактически, изменения в конфиге сводятся по-большей части к следующему:

  • Указываем прослушиваемые порты - они должны быть такие же, как были указаны в SRV-записях в DNS.
  • Включаем use-auth-secret и указываем придуманный ключ-пароль - его мы потом укажем в конфиг-файле у Prosody.
  • Указываем realm - домен и сертификат с ключом для него.

Да, так как Coturn не может напрямую прочитать сертификаты из каталога Let's Encrypt - для правильной работы можно создать отдельный каталог, куда копировать сертификаты с нужными правами. В примере выше это /etc/turncerts. Команду копирования и изменения прав можно объединить в одном скрипте с командой копирования сертификатов для Prosody и вызывать этот скрипт в качестве deploy hook для Let's Encrypt (или просто по Cron'у, например, раз в неделю).

Закончив правку конфиг-файла, перезапускаем TURN-сервер:

systemctl restart coturn.service

Теперь переходим к настройке Prosody. Как уже говорилось, под него есть множество разнообразных модулей. Для удобства добавления модулей добавьте следующие пакеты:

apt-get install luarocks liblua5.4-dev lua-luaossl --no-install-recommends

После чего можно сразу установить полезные модули:

prosodyctl install --server=https://modules.prosody.im/rocks/ mod_admin_web # Поддержка WEB-интерфейса для управления сервером
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_vcard_muc # Поддержка vCard для конференций
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_muc_moderation # Модерирование конференций и возможность удалять спам
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_cloud_notify # Поддержка PUSH-уведомлений
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_cloud_notify_extensions # Дополнительные модули для PUSH
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_register_web # Поддержка регистрации через веб-страницу
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_mam_adhoc # Возможность управлять настройками MAM-архива из jabber-клиента
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_throttle_presence # Ограничиваем трафик статусов
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_reload_modules # Ставим для возможности обновлять сертификаты без перезагрузки

Конфигурационный файл у Prosody состоит из нескольких секций:

  • Общие параметры
  • Параметры виртуал-хоста
  • Параметры сервисов.

Для удобства то, что относится к виртуал-хосту и его сервисам, вынесено в отдельный файл. Для включения нужного виртуал-хоста поместите симлинк на его конфиг в /etc/prosody/conf.d.

/etc/prosody/prosody.cfg.lua
-- Prosody Example Configuration File
--
-- Information on configuring Prosody can be found on our
-- website at https://prosody.im/doc/configure
--
-- Tip: You can check that the syntax of this file is correct
-- when you have finished by running this command:
--     prosodyctl check config
-- If there are any errors, it will let you know what and where
-- they are, otherwise it will keep quiet.
--
-- The only thing left to do is rename this file to remove the .dist ending, and fill in the
-- blanks. Good luck, and happy Jabbering!


---------- Server-wide settings ----------
-- Settings in this section apply to the whole server and are the default settings
-- for any virtual hosts

-- This is a (by default, empty) list of accounts that are admins
-- for the server. Note that you must create the accounts separately
-- (see https://prosody.im/doc/creating_accounts for info)
-- Example: admins = { "user1@example.com", "user2@example.net" }
admins = {
"admin@EXAMPLE.COM"
}

-- This option allows you to specify additional locations where Prosody
-- will search first for modules. For additional modules you can install, see
-- the community module repository at https://modules.prosody.im/
-- For a local administrator it's common to place local modifications
-- under /usr/local/ hierarchy:
plugin_paths = {
	"/usr/lib/prosody/modules",
	"/var/lib/prosody/custom_plugins/"
}

-- This is the list of modules Prosody will load on startup.
-- Documentation for bundled modules can be found at: https://prosody.im/doc/modules
modules_enabled = {

	-- Generally required
		"disco"; -- Service discovery
		"roster"; -- Allow users to have a roster. Recommended ;)
		"saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
		"tls"; -- Add support for secure TLS on c2s/s2s connections

	-- Not essential, but recommended
		"blocklist"; -- Allow users to block communications with other users
		"bookmarks"; -- Synchronise the list of open rooms between clients
		"carbons"; -- Keep multiple online clients in sync
		"dialback"; -- Support for verifying remote servers using DNS
		"limits"; -- Enable bandwidth limiting for XMPP connections
		"pep"; -- Allow users to store public and private data in their account
		"private"; -- Legacy account storage mechanism (XEP-0049)
		"smacks"; -- Stream management and resumption (XEP-0198)
		"vcard4"; -- User profiles (stored in PEP)
		"vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard

	-- Nice to have
		"csi_simple"; -- Simple but effective traffic optimizations for mobile devices
		"ping"; -- Replies to XMPP pings with pongs
		"register"; -- Allow users to register on this server using a client and change passwords
		"time"; -- Let others know the time here on this server
		"uptime"; -- Report how long server has been running
		"version"; -- Replies to server version requests
		"mam"; -- Store recent messages to allow multi-device synchronization
		"turn_external"; -- Provide external STUN/TURN service for e.g. audio/video calls

	-- Admin interfaces
		"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
		"admin_shell"; -- Allow secure administration via 'prosodyctl shell'

	-- HTTP modules
		"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
		--"http_openmetrics"; -- for exposing metrics to stats collectors
		"websocket"; -- XMPP over WebSockets

	-- Other specific functionality
		"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
		"announce"; -- Send announcement to all online users
		--"groups"; -- Shared roster support
		--"legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
		--"mimicking"; -- Prevent address spoofing
		--"motd"; -- Send a message to users when they log in
		"s2s_bidi"; -- Bi-directional server-to-server (XEP-0288)
		"server_contact_info"; -- Publish contact information for this service
		"tombstones"; -- Prevent registration of deleted accounts
		"watchregistrations"; -- Alert admins of registrations
		"welcome"; -- Welcome users who register accounts

		"cloud_notify"; -- push support
		"cloud_notify_extensions"; -- meta-module that simply enables all the modules required to support Siskin or Snikket iOS on a Prosody server
		"register_web"; -- registrations via web interface
		"mam_adhoc"; -- allowing clients to change archiving preferences
		"throttle_presence"; -- automatically cuts down on presence traffic when clients indicate they are inactive
		"external_services"; -- calls
		"admin_adhoc"; -- ad-hoc administration of server
        "reload_modules";
}

reload_modules = { "groups", "tls" }

-- These modules are auto-loaded, but should you want
-- to disable them then uncomment them here:
modules_disabled = {
	-- "offline"; -- Store offline messages
	-- "c2s"; -- Handle client connections
	-- "s2s"; -- Handle server-to-server connections
}

-- Debian:
--   Please, don't change this option since /run/prosody/
--   is one of the few directories Prosody is allowed to write to
--
pidfile = "/run/prosody/prosody.pid";

-- Server-to-server authentication
-- Require valid certificates for server-to-server connections?
-- If false, other methods such as dialback (DNS) may be used instead.

s2s_secure_auth = true

-- Some servers have invalid or self-signed certificates. You can list
-- remote domains here that will not be required to authenticate using
-- certificates. They will be authenticated using other methods instead,
-- even when s2s_secure_auth is enabled.

--s2s_insecure_domains = { "insecure.example" }

-- Even if you disable s2s_secure_auth, you can still require valid
-- certificates for some domains by specifying a list here.

--s2s_secure_domains = { "jabber.org" }


-- Rate limits
-- Enable rate limits for incoming client and server connections. These help
-- protect from excessive resource consumption and denial-of-service attacks.

limits = {
	c2s = {
		rate = "3kb/s";
	};
	s2sin = {
		rate = "50kb/s";
	};
}

-- Authentication
-- Select the authentication backend to use. The 'internal' providers
-- use Prosody's configured data storage to store the authentication data.
-- For more information see https://prosody.im/doc/authentication

authentication = "internal_hashed"

-- Many authentication providers, including the default one, allow you to
-- create user accounts via Prosody's admin interfaces. For details, see the
-- documentation at https://prosody.im/doc/creating_accounts


-- Storage
-- Select the storage backend to use. By default Prosody uses flat files
-- in its configured data directory, but it also supports more backends
-- through modules. An "sql" backend is included by default, but requires
-- additional dependencies. See https://prosody.im/doc/storage for more info.

storage = "sql" -- Default is "internal" (Debian: "sql" requires one of the
-- lua-dbi-sqlite3, lua-dbi-mysql or lua-dbi-postgresql packages to work)

-- For the "sql" backend, you can uncomment *one* of the below to configure:
--sql = { driver = "SQLite3", database = "prosody.sqlite" } -- Default. 'database' is the filename.
sql = { driver = "MySQL", database = "jabber_example_com", username = "jabberuser", password = "MYSECRETPASSWORD", host = "localhost" }
--sql = { driver = "PostgreSQL", database = "prosody", username = "prosody", password = "secret", host = "localhost" }


-- Archiving configuration
-- If mod_mam is enabled, Prosody will store a copy of every message. This
-- is used to synchronize conversations between multiple clients, even if
-- they are offline. This setting controls how long Prosody will keep
-- messages in the archive before removing them.

archive_expires_after = "1w" -- Remove archived messages after 1 week
max_archive_query_results = 20;

-- You can also configure messages to be stored in-memory only. For more
-- archiving options, see https://prosody.im/doc/modules/mod_mam


-- Audio/video call relay (STUN/TURN)
-- To ensure clients connected to the server can establish connections for
-- low-latency media streaming (such as audio and video calls), it is
-- recommended to run a STUN/TURN server for clients to use. If you do this,
-- specify the details here so clients can discover it.
-- Find more information at https://prosody.im/doc/turn

-- Specify the address of the TURN service (you may use the same domain as XMPP)
turn_external_host = "xmpp.EXAMPLE.COM"

-- This secret must be set to the same value in both Prosody and the TURN server
turn_external_secret = "MYSUPERSECRETKEY"


-- Logging configuration
-- For advanced logging see https://prosody.im/doc/logging
--
-- Debian:
--  Logs info and higher to /var/log
--  Logs errors to syslog also
log = {
	-- Log files (change 'info' to 'debug' for debug logs):
	info = "/var/log/prosody/prosody.log";
	error = "/var/log/prosody/prosody.err";
	-- Syslog:
	{ levels = { "error" }; to = "syslog";  };
}


-- Uncomment to enable statistics
-- For more info see https://prosody.im/doc/statistics
statistics = "internal"


-- Certificates
-- Every virtual host and component needs a certificate so that clients and
-- servers can securely verify its identity. Prosody will automatically load
-- certificates/keys from the directory specified here.
-- For more information, including how to use 'prosodyctl' to auto-import certificates
-- (from e.g. Let's Encrypt) see https://prosody.im/doc/certificates

-- Location of directory to find certificates in (relative to main config file):
certificates = "certs"

c2s_direct_tls_ports = { 5223 }
s2s_direct_tls_ports = { 5270 }
c2s_require_encryption = true
s2s_require_encryption = true
tls_profile = "intermediate" -- "modern" if you don't need TLS 1.2

contact_info = {
	abuse = { "xmpp:admin@EXAMPLE.COM" };
	admin = { "xmpp:admin@EXAMPLE.COM" };
	feedback = { "xmpp:admin@EXAMPLE.COM" };
	support = { "https://EXAMPLE.COM", "xmpp:admin@EXAMPLE.COM" };
}

external_services = {
    {
        type = "stun",
        transport = "tcp",
        host = "xmpp.EXAMPLE.COM",
        port = 3478
    }, {
        type = "stun",
        transport = "udp",
        host = "xmpp.EXAMPLE.COM",
        port = 3478
    }, {
        type = "turn",
        transport = "tcp",
        host = "xmpp.EXAMPLE.COM",
        port = 3478
    }, {
        type = "turn",
        transport = "udp",
        host = "xmpp.EXAMPLE.COM",
        port = 3478
    }, {
        type = "stuns",
        transport = "tcp",
        host = "xmpp.EXAMPLE.COM",
        port = 5349
    }, {
        type = "turns",
        transport = "tcp",
        host = "xmpp.EXAMPLE.COM",
        port = 5349
    }
}

consider_websocket_secure = true
consider_bosh_secure = true

----------- Virtual hosts -----------
-- You need to add a VirtualHost entry for each domain you wish Prosody to serve.
-- Settings under each VirtualHost entry apply *only* to that host.
-- It's customary to maintain VirtualHost entries in separate config files
-- under /etc/prosody/conf.d/ directory. Examples of such config files can
-- be found in /etc/prosody/conf.avail/ directory.

------ Additional config files ------
-- For organizational purposes you may prefer to add VirtualHost and
-- Component definitions in their own config files. This line includes
-- all config files in /etc/prosody/conf.d/

-- VirtualHost "localhost"
-- Prosody requires at least one enabled VirtualHost to function. You can
-- safely remove or disable 'localhost' once you have added another.


--VirtualHost "example.com"

------ Components ------
-- You can specify components to add hosts that provide special services,
-- like multi-user conferences, and transports.
-- For more information on components, see https://prosody.im/doc/components

---Set up a MUC (multi-user chat) room server on conference.example.com:
--Component "conference.example.com" "muc"
--- Store MUC messages in an archive and allow users to access it
--modules_enabled = { "muc_mam" }

---Set up a file sharing component
--Component "share.example.com" "http_file_share"

---Set up an external component (default component port is 5347)
--
-- External components allow adding various services, such as gateways/
-- bridges to non-XMPP networks and services. For more info
-- see: https://prosody.im/doc/components#adding_an_external_component
--
--Component "gateway.example.com"
--	component_secret = "password"

Include "conf.d/*.cfg.lua"

---------- End of the Prosody Configuration file ----------
-- You usually **DO NOT** want to add settings here at the end, as they would
-- only apply to the last defined VirtualHost or Component.
--
-- Settings for the global section should go higher up, before the first
-- VirtualHost or Component line, while settings intended for specific hosts
-- should go under the corresponding VirtualHost or Component line.
--
-- For more information see https://prosody.im/doc/configure

Виртуал хост /etc/prosody/conf.avail/EXAMPLE.COM.cfg.lua
-- Section for example.com

VirtualHost "EXAMPLE.COM"
        enabled = true

        -- Assign this host a certificate for TLS, otherwise it would use the one
        -- set in the global section (if any).
        -- Note that old-style SSL on port 5223 only supports one certificate, and will always
        -- use the global one.
        ssl = {
                key = "/etc/prosody/certs/EXAMPLE.COM.key";
                certificate = "/etc/prosody/certs/EXAMPLE.COM.crt";
                options = { "no_sslv2", "no_sslv3" }
        }

        modules_enabled = {
            "admin_web"
		    --"invites"; -- Create and manage invites
		    --"invites_adhoc"; -- Allow admins/users to create invitations via their client
		    --"invites_register"; -- Allows invited users to create accounts
        }
        allow_registration = false -- Allow users to register new accounts via in-band

------ Components ------
-- You can specify components to add hosts that provide special services,
-- like multi-user conferences, and transports.
-- For more information on components, see http://prosody.im/doc/components


-- Set up a SOCKS5 bytestream proxy for server-proxied file transfers:
Component "proxy.EXAMPLE.COM" "proxy65"
        ssl = {
                key = "/etc/prosody/certs/proxy.EXAMPLE.COM.key";
                certificate = "/etc/prosody/certs/proxy.EXAMPLE.COM.crt";
                options = { "no_sslv2", "no_sslv3" }
        }
        -- proxy65_address = "proxy.EXAMPLE.COM"
        proxy65_acl = { "EXAMPLE.COM" }

-- Set up a MUC (multi-user chat) room server on conference.example.com:
Component "conference.EXAMPLE.COM" "muc"
        modules_enabled = {
                "muc_mam",
                "vcard_muc",
                "muc_moderation"
        }
        ssl = {
                key = "/etc/prosody/certs/conference.EXAMPLE.COM.key";
                certificate = "/etc/prosody/certs/conference.EXAMPLE.COM.crt";
                options = { "no_sslv2", "no_sslv3" }
        }
        muc_log_by_default = true
        muc_log_presences = false
        log_all_rooms = false
        muc_log_expires_after = "1w"
        muc_log_cleanup_interval = 4 * 60 * 60
        restrict_room_creation = "local"

Component "upload.EXAMPLE.COM" "http_file_share"
        ssl = {
                key = "/etc/prosody/certs/upload.EXAMPLE.COM.key";
                certificate = "/etc/prosody/certs/upload.EXAMPLE.COM.crt";
                options = { "no_sslv2", "no_sslv3" }
        }

        http_file_share_size_limit = 100*1024*1024 -- 100 MB per file
        http_file_share_expires_after = 7*86400 -- file expiration - 1 week
        http_file_share_global_quota = 1024*1024*1024*10 -- 10 GiB total

Component "pubsub.EXAMPLE.COM" "pubsub"
        ssl = {
                key = "/etc/prosody/certs/pubsub.EXAMPLE.COM.key";
                certificate = "/etc/prosody/certs/pubsub.EXAMPLE.COM.crt";
                options = { "no_sslv2", "no_sslv3" }
        }

Файл конфигурации Prosody очень хорошо комментирован, поэтому рассмотрим ключевые моменты, а также опции, добавленные для дополнительно установленных модулей.

  • Первым в конфиг-файле идет Jabber ID будущего администратора - ему будут доступны команды управления сервером, а также будут присылаться различные уведомления.
  • В plugin_paths добавляется путь к каталогу с устанавливаемыми плагинами.
  • Далее идет обширный список модулей. Рассмотрим некоторые:
    • turn_external позволит нам подключить настроенный ранее Coturn к Prosody для работы звонков.
    • cloud_notify включит поддержку PUSH-уведомлений.
    • register_web включает регистрацию через веб-страницу. Она доступна по адресу https://EXAMPLE.COM:5281/register_web. Штатно тут включена простенькая CAPTCHA, но можно использовать reCaptcha, для этого дополнительно необходимо будет указать ключи для этого сервиса.
    • admin_adhoc позволит выполнять ряд команд на сервере с JID'а администратора из тех клиентов, которые умеют Ad-Hoc.
  • Далее следуют настройки, в которых можно усилить или ослабить проверки сертификатов для других серверов.
  • Следующей ключевой настройкой будет указание сервера баз данных. Как мы уже условились выше, для хранения данных сервера будем использовать MySQL или MariaDB. Prosody имеет весьма простую структуру базы и встроенную схему, поэтому дополнительных действий не требуется.
  • В archive_expires_after можем указать, как скоро нужно чистить архив сообщений для MAM. Для конференций есть отдельная настройка, она будет описана ниже.
  • В turn_external_host и turn_external_secret указывается адрес Coturn и тот самый ключ, который прописывали в /etc/turnserver.conf.
  • Далее - несколько опций касательно безопасности:
    • c2s_direct_tls_ports и s2s_direct_tls_ports включает работу с TLS-портами - они должны быть те же, что указывались в SRV-записях в DNS.
    • c2s_require_encryption и s2s_require_encryption означает использование исключительно шифрованных соединений между серверами, а также между сервером и клиентом.
    • tls_profile настраивает перечень шифров и протоколов, которые может использовать Prosody.
  • В contact_info можно перечислить контакты администратора и, например, адрес конференции поддержки сервера.
  • external_services описывает сервисы, которые предоставляет Coturn.

На этом настройка основной части завершена и далее идет настройка виртуальных хостов и их сервисов:

  • В секции VirtualHost идет указание SSL-сертификатов для домена, а также разрешение регистрации через jabber-клиент и включение веб-интерфейса для управления сервером, который доступен по адресу https://example.com:5281/admin.
  • invites и сопутствующие ему модули позволяют сделать регистрацию по приглашениям. Однако есть одно но (на сейчас): это отключит обычную регистрацию. Поэтому какой вариант оставить - решайте сами.

Далее перечисляется несколько компонентов - сервисов для данного сервера. В показанном примере это конференции, proxy, HTTP Upload и pubsub. Для каждого из них указывается своя пара сертификатов и ключей.

  • Для proxy можно указать субдомен, на котором он будет доступен, а опция proxy65_acl перечисляет домены, которые смогут передавать файлы через этот прокси.
  • Для конференций включается поддержка MAM и модерирования. В опциях задается включение MAM по-умолчанию, время устаревания MAM-архива, а также правила доступа на создание новых конференций.
  • Для модуля http_file_share перечисляются лимиты на размеры одиночных файлов, а также общий размер хранилища и время устаревания загруженных файлов. Для Prosody сделано несколько реализаций HTTP Upload - например, можно переключиться на mod_http_upload, если mod_http_file_share чем-то не устроит или вообще использовать внешний сервис через http_upload_external.

Закончив правку файлов конфигурации - перезапустите Prosody:

systemctl restart prosody

Теперь можете создать пользователя-администратора:

prosodyctl adduser admin@EXAMPLE.COM

А также проверить корректность конфигурации следующими командами:

prosodyctl check config
prosodyctl check certs
prosodyctl check turn

Во всех случаях в конце команда должна возвращать "All checks passed, congratulations!". Сервер готов к использованию!

Сноски

  1. 1,0 1,1 На самом деле выбор MySQL обусловлен с одной стороны ее популярностью на веб-хостингах, с другой - возможностью хранить большие объемы данных, которые могут потребоваться, если вы хотите хранить, например, архив сообщений за длительное время. Однако если таких планов нет и это будет сервер для одного или нескольких человек со скромными запросами - то вполне можно обойтись Sqlite.
  2. Да, если планируется использовать, например, конференции исключительно локально, то можно обойтись и без DNS-записей - сервер и так знает, куда ему подключаться, так как он этот сервис и предоставляет. Но если хочется полноценный сервис, с которым смогут взаимодействовать и другие сервера - то все же потребуются указанные записи в DNS.
  3. https://prosody.im/doc/turn
  4. В таком случае ему нужно обеспечить доступ к каталогу /var/lib/prosody/upload*, плюс обеспечить нужные права веб-серверу, чтобы он мог читать файлы, загруженные через jabber-сервер. Альтернативный вариант - использовать веб-сервер, обслуживающий домен upload.EXAMPLE.COM в качестве прокси и заворачивающий все запросы на https://upload.EXAMPLE.COM:5281/file_share/. Такое решение имеет еще одно преимущество: разнообразные клиенты (не только Jabber) будут гораздо охотнее показывать превью для обычных HTTP/HTTPS-ссылок (т.е., на 80 или 443-м порту), а не тех, где контент отдается на "необычном" порту - вроде 5281 в данном примере.
  5. Более подробно можно почитать тут: Свой сервер: подготовка веб-сервера и сертификатов
  6. https://prosody.im/doc/letsencrypt

Ссылки