Свой сервер: подробное руководство по установке Prosody: различия между версиями
Rain (обсуждение | вклад) (+Coturn) |
Rain (обсуждение | вклад) (+конфиги) |
||
Строка 143: | Строка 143: | ||
</pre> | </pre> | ||
}} | }} | ||
Фактически, изменения в конфиге сводятся по-большей части к следующему: | |||
* Указываем прослушиваемые порты - они должны быть такие же, как были указаны в SRV-записях в DNS. | |||
* Включаем '''use-auth-secret''' и указываем придуманный '''ключ-пароль''' - его мы потом укажем в конфиг-файле у Prosody. | |||
* Указываем '''realm''' - домен и сертификат с ключом для него. | |||
Да, так как Coturn не может напрямую прочитать сертификаты из каталога Let's Encrypt - для правильной работы можно создать отдельный каталог, куда копировать сертификаты с нужными правами. В примере выше это '''/etc/turncerts'''. Команду копирования и изменения прав можно объединить в одном скрипте с командой копирования сертификатов для Prosody и вызывать этот скрипт в качестве deploy hook для Let's Encrypt (или просто по Cron'у, например, раз в неделю). | |||
Теперь переходим к настройке 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_http_upload # Поддержка файлообмена через HTTP Upload | |||
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_register_web # Поддержка регистрации через веб-страницу | |||
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_muc_hats_adhoc # Указание дополнительных ролей в конференциях | |||
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_muc_hats_api # См. выше | |||
prosodyctl install --server=https://modules.prosody.im/rocks/ mod_mam_adhoc # Возможность управлять настройками MAM-архива из jabber-клиента | |||
Конфигурационный файл у Prosody состоит из нескольких секций: общие параметры, параметры виртуал-хоста и параметры сервисов. Для удобства то, что относится к виртуал-хосту и его сервисом, вынесено в отдельный файл. | |||
{{Hider hiding | |||
|title=/etc/prosody/prosody.cfg.lua | |||
|content=<pre> | |||
-- 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 | |||
--"invites"; -- Create and manage invites | |||
--"invites_adhoc"; -- Allow admins/users to create invitations via their client | |||
--"invites_register"; -- Allows invited users to create accounts | |||
"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 | |||
} | |||
-- 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 = "prosody_EXAMPLE.COM", username = "prosodyuser", password = "3zEROPqJhF.tk", 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 = "6BuWNTSPL0$5IYM0FKdAJu6ZG7ep8sFHzAZUr4PNO6IKzwp1Vxb4wD" | |||
-- 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 | |||
</pre> | |||
}} | |||
{{Hider hiding | |||
|title=Виртуал хост /etc/prosody/conf.avail/EXAMPLE.COM.cfg.lua | |||
|content=<pre> | |||
-- 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" | |||
} | |||
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", | |||
"muc_hats_adhoc" | |||
} | |||
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_upload" | |||
ssl = { | |||
key = "/etc/prosody/certs/upload.EXAMPLE.COM.key"; | |||
certificate = "/etc/prosody/certs/upload.EXAMPLE.COM.crt"; | |||
options = { "no_sslv2", "no_sslv3" } | |||
} | |||
http_upload_file_size_limit = 1024*1024*10 -- 10 MB | |||
-- http_max_content_size = 1024*1024*30 | |||
http_upload_quota = 1024*1024*250 -- 250 MB | |||
http_upload_expire_after = 60*60*24*7 -- 1 week | |||
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" } | |||
} | |||
</pre> | |||
}} | |||
{{ToDo|Доделать}} | {{ToDo|Доделать}} |
Версия 19:10, 1 ноября 2023
В этой статье приводится пример настройки Prosody - одного из самых популярных и легковесных jabber-серверов. Для сервера написано просто-таки огромное число модулей на все случаи жизни, поэтому в руководстве, основанном на версии 0.12.4, будет показано подключение актуальных и популярных функций. В качестве сертификатов будем использовать 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-адреса.
- Создаем субдомены для необходимых сервисов сервера[1] - 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-подключений серверов.
- _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:
Сертификаты
В современном мире стандартной практикой является шифрование соединений, а для этого, в свою очередь, требуются сертификаты от доверенных центров сертификации. Можно, конечно, использовать самоподписанный сертификат, но, во-первых, не все серверы будут их принимать - а значит, к ним не получится подключиться и общаться с их пользователями, а во-вторых, в подключающихся клиентах будут появляться сообщения о недоверенном сертификате, что тоже будет доставлять определенные неудобства. Поэтому стоит воспользоваться услугами одного из популярных бесплатных центров сертификации - 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 файлы, чтобы в дальнейшем их раздавал веб-сервер[3].
После всех приготовлений[4] создайте все необходимые сертификаты. Для этого воспользуйтесь следующими командами (выполнять надо от пользователя 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 от рута, то надо каким-то образом предоставить доступ ejabberd'у к сертификатам. Самым простым и корректным вариантом на сейчас является выполнение следующей команды от рута[5]:
prosodyctl --root cert import /etc/letsencrypt/live
В дальнейшем эту команду можно использовать после каждого обновления сертификатов - например, указав ее в качестве deploy hook для certbot.
Установка и настройка Prosody
Все подготовительные процедуры завершены, теперь можно приступать непосредственно к установке и настройке своего jabber-сервера. Для поддержки звонков потребуется еще STUN/TURN-сервер - в качестве него будем использовать Coturn. В Debian установить Prosody с поддержкой MySQL и 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 к такому виду:
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'у, например, раз в неделю).
Теперь переходим к настройке 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_http_upload # Поддержка файлообмена через HTTP Upload prosodyctl install --server=https://modules.prosody.im/rocks/ mod_register_web # Поддержка регистрации через веб-страницу prosodyctl install --server=https://modules.prosody.im/rocks/ mod_muc_hats_adhoc # Указание дополнительных ролей в конференциях prosodyctl install --server=https://modules.prosody.im/rocks/ mod_muc_hats_api # См. выше prosodyctl install --server=https://modules.prosody.im/rocks/ mod_mam_adhoc # Возможность управлять настройками MAM-архива из jabber-клиента
Конфигурационный файл у Prosody состоит из нескольких секций: общие параметры, параметры виртуал-хоста и параметры сервисов. Для удобства то, что относится к виртуал-хосту и его сервисом, вынесено в отдельный файл.
-- 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 --"invites"; -- Create and manage invites --"invites_adhoc"; -- Allow admins/users to create invitations via their client --"invites_register"; -- Allows invited users to create accounts "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 } -- 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 = "prosody_EXAMPLE.COM", username = "prosodyuser", password = "3zEROPqJhF.tk", 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 = "6BuWNTSPL0$5IYM0FKdAJu6ZG7ep8sFHzAZUr4PNO6IKzwp1Vxb4wD" -- 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
-- 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" } 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", "muc_hats_adhoc" } 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_upload" ssl = { key = "/etc/prosody/certs/upload.EXAMPLE.COM.key"; certificate = "/etc/prosody/certs/upload.EXAMPLE.COM.crt"; options = { "no_sslv2", "no_sslv3" } } http_upload_file_size_limit = 1024*1024*10 -- 10 MB -- http_max_content_size = 1024*1024*30 http_upload_quota = 1024*1024*250 -- 250 MB http_upload_expire_after = 60*60*24*7 -- 1 week 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" } }
Сноски
- ↑ Да, если планируется использовать, например, конференции исключительно локально, то можно обойтись и без DNS-записей - сервер и так знает, куда ему подключаться, так как он этот сервис и предоставляет. Но если хочется полноценный сервис, с которым смогут взаимодействовать и другие сервера - то все же потребуются указанные записи в DNS.
- ↑ https://prosody.im/doc/turn
- ↑ В таком случае ему нужно обеспечить доступ к каталогу /var/lib/prosody/http_upload/ - а лучше указать опцию http_upload_path с путем за пределами домашнего каталога Prosody, плюс обеспечить нужные права веб-серверу, чтобы он мог читать файлы, загруженные через jabber-сервер. Такое решение имеет еще одно преимущество: разнообразные клиенты (не только Jabber) будут гораздо охотнее показывать превью для обычных HTTP/HTTPS-ссылок (т.е., на 80 или 443-м порту), а не тех, где контент отдается на "необычном" порту - вроде 5281 в данном примере.
- ↑ Более подробно можно почитать тут: Свой сервер: подготовка веб-сервера и сертификатов
- ↑ https://prosody.im/doc/letsencrypt
Ссылки
- https://prosody.im - домашняя страница ejabberd