Для начала нам нужно прописать DNS записи для домена у вашего регистратора домена 4 А-записи: conference proxy pubsub upload 2 SRV записи: _xmpp-client._tcp.example.com. example.com. 5 0 5222 _xmpp-server._tcp.example.com. example.com. 5 0 5269 2 TXT записи: _xmppconnect "_xmpp-client-websocket=wss://example.com/xmpp-websocket" _xmppconnect "_xmpp-client-xbosh=https://example.com/http-bind" Следом добавим репозиторий Prosody в систему, чтобы всегда иметь свежую версию серверной части: echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/prosody.list -- определяем дистрибутив и добавляем репозиторий Prosody sudo wget https://prosody.im/files/prosody-debian-packages.key -O/etc/apt/trusted.gpg.d/prosody.gpg -- копируем ключ из репозитория и доверяем ему sudo apt update и всё, теперь Prosody будет устанавливаться из репозитория разработчиков. Установка NGINX и модуль загрузки файлов sudo apt install nginx libnginx-mod-http-perl Создадим технические домены и заполним mkdir /var/www/tech chown -R www-data:www-data /var/www/tech sudo nano /etc/nginx/sites-enabled/example.com server { server_name example.com; location / { root /var/www/tech; #proxy_pass http://localhost:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_buffering off; # proxy_protocol: on; tcp_nodelay on; } location /http-bind { proxy_pass http://localhost:5280/http-bind; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_buffering off; tcp_nodelay on; } location /xmpp-websocket { proxy_pass http://localhost:5280/xmpp-websocket; proxy_http_version 1.1; proxy_set_header Connection "Upgrade"; proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_read_timeout 900s; } location /register_web { proxy_pass http://localhost:5280/register_web; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_buffering off; tcp_nodelay on; auth_basic "Private area"; auth_basic_user_file /var/www/protect/.htpasswd; } location /web { proxy_pass http://localhost:5280/conversejs; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_buffering off; tcp_nodelay on; } Технические домены: sudo nano /etc/nginx/sites-enabled/upload.example.com server { listen 80; server_name upload.example.com; root /upload; location / { perl upload::handle; } } nano /etc/nginx/sites-enabled/pubsub.example.com server { listen 80; server_name pubsub.example.com; root /var/www/tech; index index.html; location / { try_files $uri $uri/ =404; } } nano /etc/nginx/sites-enabled/proxy.example.com server { listen 80; server_name proxy.example.com; root /var/www/tech; index index.html; location / { try_files $uri $uri/ =404; } } nano /etc/nginx/sites-enabled/conference.example.com server { listen 80; server_name conference.example.com; root /var/www/tech; index index.html; location / { try_files $uri $uri/ =404; } } Создаем пароль для закрытой регистрации пользователей perl -le 'print crypt("пароль_для_регистрации", "любые_символы_для_хэширования")' Далее записываем сгенерированный пароль и вписываем его в /var/www/protect/.htpasswd в формате login:password mkdir /var/www/protect nano /var/www/protect/.htpasswd login:password Включаем модуль upload для NGINX mkdir /upload chown -R www-data:www-data /upload/ mkdir -p /usr/local/lib/perl wget -O /usr/local/lib/perl/upload.pm https://git.io/fNZgL Добавим модуль в конфиг nano /etc/nginx/nginx.conf perl_modules /usr/local/lib/perl; perl_require upload.pm; client_max_body_size 4096m; Впишем пароль в конфиг perl sudo nano /usr/local/lib/perl/upload.pm CTRL+W external_secret ENTER и вписываем пароль $external_secret = 'ПАРОЛЬ' Перезапускаем NGINX и проверяем его работу: sudo systemctl restart nginx.service sudo systemctl status nginx.service Если стартанул без ошибок жмем CTRL+C и едем дальше Получим сертификаты Let's Encrypt на все домены sudo apt install python3-certbot-nginx certbot --nginx --rsa-key-size 4096 -d example.com certbot --nginx --rsa-key-size 4096 -d upload.example.com certbot --nginx --rsa-key-size 4096 -d conference.example.com certbot --nginx --rsa-key-size 4096 -d proxy.example.com certbot --nginx --rsa-key-size 4096 -d pubsub.example.com После этого можно зайти на домены и посмотреть, работают ли сертификаты Далее устанавливаем БД и редактируем конфиг sudo apt install postgresql postgresql-contrib nano /etc/postgresql/14/main/postgresql.conf (внимание, версия Postgesql может быть иная, от этого зависит расположение конфига в цифре, вместо 14 может быть например 10 или 16) и там вписываем listen_addresses = '127.0.0.1' Перезапускаем БД sudo systemctl restart postgresql.service Создаем пользователя БД su - postgres createuser --pwprompt prosodyuser Создаем саму БД psql и вставляем это CREATE DATABASE prosodyuser OWNER prosodyuser; Выходим из БД \q Устанавливаем Prosody sudo apt install prosody lua-event lua-dbi-postgresql Устанавливаем модули (в версии 12 модули вроде как ставятся по умолчанию, но я не разбирался в таких тонкостях) cd /opt sudo apt install mercurial hg clone https://hg.prosody.im/prosody-modules/ prosody-modules chown -R prosody:prosody /opt/prosody-modules Создадим директорию для PID файла mkdir /var/run/prosody chown -R prosody:prosody /var/run/prosody Создаем ключ Диффи-Хелмана cd /etc/prosody/certs/ openssl dhparam -out dh-2048.pem 2048 chown prosody:prosody dh-2048.pem chmod u=rw,go= dh-2048.pem Установим пакет для импорта сертификатов Prosody sudo apt install lua-sec Теперь переходим к настройке конфига самого Prosody sudo nano /etc/prosody/prosody.cfg.lua И туда вставляем следующий конфиг: pidfile = "/var/run/prosody/prosody.pid"; ---администраторы сервера--- admins = { "user@example.com" } --для веб реги это можно отключить--- allow_registration = false ----------------------------------- ------------Хранить всё в БД--------------------- default_storage = "sql" sql = { driver = "PostgreSQL"; database = "prosodyuser"; host = "127.0.0.1"; port = 5432; username = "prosodyuser"; password = "ПАРОЛЬ_ОТ_ПОЛЬЗОВАТЕЛЯ_БД"; } sql_manage_tables = true -------------------------------- ---Сертификаты--- certificates = "/etc/prosody/certs" --http http_host = "127.0.0.1" http_ports = { 5280 } https_ports = { } http_interfaces = { "127.0.0.1" } trusted_proxies = { "127.0.0.1" } --Методы шифрования--- ssl = { --key = "/etc/prosody/certs/example.com.key"; --certificate = "/etc/prosody/certs/example.com.crt"; options = { "no_sslv3", "no_sslv2", "no_ticket", "no_compression", "cipher_server_preference", "single_dh_use", "single_ecdh_use" }; ciphers="EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:AES256-GCM-SHA384"; protocol = "tlsv1_1+"; dhparam = "/etc/prosody/certs/dh-2048.pem"; } --Обязательное шифрование Клиент сервер и Сервер и сервер c2s_require_encryption = true; s2s_require_encryption = true; s2s_secure_auth = true; ---Модули--- plugin_paths = { "/opt/prosody-modules/" } --Глобальные модули--- modules_enabled = { -- Wichtige Module "roster"; "saslauth"; "tls"; "dialback"; "disco"; -- Empfohlene Module "private"; "profile"; "offline"; "admin_adhoc"; "admin_telnet"; --"http_files"; "legacyauth"; "version"; "uptime"; "time"; "ping"; "register"; "posix"; "bosh"; "announce"; -- "proxy65"; "pep"; "smacks"; "carbons"; "blocklist"; "csi"; "csi_battery_saver"; "mam"; "lastlog"; "list_inactive"; "cloud_notify"; "compat_dialback"; "throttle_presence"; "log_auth"; "server_contact_info"; "websocket"; "bookmarks"; "privacy_lists"; --"pubsub"; "filter_chatstates"; "vcard_legacy"; "pinger"; -- "turncredentials"; "http_upload_external"; "register_web"; "http_altconnect"; "conversejs"; "turn_external"; }; --------------------------------- ---Выключаем логи--- ---------------------------------- log = { --debug = "/var/log/prosody/debug.log"; --info = "/var/log/prosody/info.log"; --warn = "/var/log/prosody/warn.log"; --error = "/var/log/prosody/error.log"; } ------------------------------------ -- ---Настройка архива сообщений, можно выставить в днях, или отключить вовсе--- ---------------------------- default_archive_policy = true; archive_expires_after = "1d"; ---EXTERNAL HTTP UPLOAD--- http_upload_external_base_url = "https://upload.example.com/" http_upload_external_secret = "ПАРОЛЬ_ОТ_UPLOAD" http_upload_external_file_size_limit = 536870912 --4Gb -------------------------------- ---шаблон для веб регистрации--- register_web_template = "/etc/prosody/register-templates/Prosody-Web-Registration-Theme" ---Websocket--- consider_websocket_secure = true; --cross_domain_websocket = true; --настройки веб клиента--- conversejs_options = { debug = false; view_mode = "fullscreen"; } conversejs_tags = { -- Load libsignal-protocol.js for OMEMO support (GPLv3; be aware of licence implications) [[]]; } ---------------------------------- ---------------------------------- --cross_domain_bosh = true; consider_bosh_secure = true; ---TURN STUN для звонков--- turn_external_host = "example.com" turn_external_port = 3478 turn_external_secret = "ПАРОЛЬ" contact_info = { abuse = { "mailto:user@example.com", "xmpp:user@example.com" }; admin = { "mailto:user@example.com", "xmpp:user@example.com" }; feedback = { "mailto:user@example.com", "xmpp:user@example.com" }; sales = { "mailto:user@example.com", "xmpp:user@example.com" }; security = { "mailto:user@example.com", "xmpp:user@example.com" }; support = { "mailto:user@example.com", "xmpp:user@example.com" }; }; -------------------------domain----------------------- c2s_direct_tls_ports = { 5223 } c2s_direct_tls_ssl = { certificate = "/etc/prosody/certs/example.com.crt"; key = "/etc/prosody/certs/example.com.key"; } VirtualHost "example.com" http_host = "example.com" http_external_url = "https://example.com/" authentication = "internal_hashed" Component "conference.example.com" "muc" name = "example.com chatrooms" restrict_room_creation = "local" muc_room_default_public = false muc_room_default_members_only = true muc_room_default_language = "ru" max_history_messages = 500 modules_enabled = { "muc_mam", "vcard_muc", "muc_cloud_notify"; } muc_log_by_default = true disco_items = { { "conference.example.com", "example.com MUC" }; } Component "pubsub.example.com" "pubsub" Component "proxy.example.com" "proxy65" proxy65_acl = { "example.com" } После изменения конфига перезапускаем Prosody sudo systemctl restart prosody.service sudo systemctl status prosody.service Импортируем сертификаты, которые создали с помощью Let's Encrypt sudo prosodyctl --root cert import /etc/letsencrypt/live Создаем веб интерфейс для регистрации mkdir /etc/prosody/register-templates/ cd /etc/prosody/register-templates git clone https://github.com/xshadow/Prosody-Web-Registration-Theme Установка Coturn для звонков через Conversation и Dino sudo apt install coturn Далее правим конфиг sudo nano /etc/turnserver.conf use-auth-secret static-auth-secret=ПАРОЛЬ_ДЛЯ_КОТЮРНА realm=example.com # VoIP traffic is all UDP. There is no reason to let users connect to arbitrary TCP endpoints via the relay. no-tcp-relay # don't let the relay ever try to connect to private IP address ranges within your network (if any) # given the turn server is likely behind your firewall, remember to include any privileged public IPs too. denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=192.168.0.0-192.168.255.255 denied-peer-ip=172.16.0.0-172.31.255.255 # special case the turn server itself so that client->TURN->TURN->client flows work allowed-peer-ip=10.0.0.1 # consider whether you want to limit the quota of relayed streams per user (or total) to avoid risk of DoS. user-quota=12 # 4 streams per video call, so 12 streams = 3 simultaneous relayed calls per user. total-quota=1200 nano /etc/default/coturn расскоментируйте строчку enable 1 sudo systemctl enable --now coturn sudo systemctl restart coturn sudo systemctl status coturn sudo crontab -e 0 5 * * 1 /usr/bin/certbot renew --renew-hook "prosodyctl --root cert import /etc/letsencrypt/live" --quiet Включаем файрволл sudo ufw allow 3478 sudo ufw allow 5222 sudo ufw allow 5000 sudo ufw allow 5269 sudo ufw allow ssh sudo ufw allow 443 sudo ufw allow 80 sudo ufw enable Удаление файлов пользователей Так как автоочистки файлов нет, можно удалять их по через Cron в зависимости от времени sudo nano /etc/cron.daily/deletefiles Вставляем #!/bin/sh find /upload/ -type f -mtime +30 -exec rm -v {} \; После этого скрипт будет проверять даты файлов и удалять все что старше 30 дней Делаем файл исполняемым chmod +x deletefiles Регистрация пользователей происходит на странице https://example.com/register_web, если вы предварительно выслали им логин и пароль для захода Веб клиент Converse.js находится тут https://example.com/web Клиенты Клиенты для смартфонов: Conversations https://conversations.im/ Android Blabber https://blabber.im/en.html Android Monal https://monal.im/ iOS Siskin https://siskin.im/ iOS Клиенты для ПК: Gajim https://gajim.org/ GNU/Linux и Windows DINO https://dino.im/ GNU/Linux Web клиент: https://conversejs.org/ Инструкция распространяется под лицензией GNU FDL 1.3, полный текст лицензии доступен на https://www.gnu.org/licenses/fdl-1.3.html