Установка и настройка Jabber сервера Prosody + dovecot + http_upload_external 2019

Подробный мануал по установке и настройке Prosody, конфиг с комментариями версия 2019 года, полная поддержка OMEMO на стороне сервера и клиента Conversetions

Установка и настройка Jabber сервера Prosody + dovecot + http_upload_external 2019

После эксперементов над Matrix, а так же попыткой из сервера  конференций Jitsi превратить его в полноценный jabber сервер для домена  (не удачной), Nextcloud Talk (тоже сырой сильно) я все таки вернулся  к первоначальной мысли о том, что Jabber пока лучшее open-source решение  для безопасного приватного обмена сообщениями на основе своего сервера  и обязательным шифрованием e2e на стороне клиентов.

Потратил я на всю настройку и тестирование около недели, так как  проблем было очень много это в основном касалось того, что бы сервер  на 100% покрывал возможности клиентов, которые на нем будут  использоваться.
А так же полностью покрывал или максимально возможно проходил требования xmpp.net и compliance.conversations.im

Для тех, кто хочет поновее что-то есть Matrix но это шлак.

Требования к клиентам:

  • OMEMO шифрование сквозное и один на один и комнат чатов.
  • Приличный современный дизайн и юзабилити, что бы не гики пользовались, а родственники и друзья.
  • Стабильность, что бы все сообщения доходили
  • Работа приложений в фоне и пуши

Начнем с лучших клиентов, под которые я затачивал сервер.

Android — Conversations, Pix-Art Messeger  (Pix-Art форк  первого, но с небольшой разницей (я заметил, что видеопроигрывать  встроен уже, больше инфы о сервере дает), причем я ставил его  из маркета, а потом он для России пропал, но apk всегда можно скачать  с сайта)
iOS — ChatSecure (без альтернатив, их просто нет с нормально работающим OMEMO шифрованием)
Windows — Gajim, PSI+ (тут вообще все печально с красотой клиентов, ничего с 2010 года не изменилось)
MacOS — Monal, Siskin (Не тестировал еще, но заявлено, что умеют OMEMO на вид ниче такие)

Требования к серверу

  • Стабильность, обновляемость, покрытие XEP для клиентов, модули
  • Простота настройки
  • Наличие мануалов (язык не важен)
  • Ubuntu, Debian
  • Поддержка нескольких виртуальных хостов и простота настройки
  • Аутентификация через IMAP Dovecot сервер.
  • Хранение архива сообщений и всей служебной инфомации в БД
  • Работа на уже установленной VestaCP и отсутствие конфликтов.

Остановился на Prosody, Ejabberd слишком сложен для меня в настройке, несколько раз сталкивался с ним, не зашел.

Сложности, которые возникли при настройке и потребовали времени на решение:

  1. Заморочка с сертификатами, какие куда и вообще нужно ли прописывать.
  2. Push уведомления в ChatSecure не доходили, засыпали клиенты и все, сообщения не доходят.
  3. Обмен файлами между виртуальными хостами, сложность была  в сертификатах, подсовывал одному хосту другой, решено внедрением  http_upload_external
  4. Не отображение аватарок при смене, пропадаение при использовании

Все настройка и установка проходила в следующих реалиях:
Ubuntu 18.04, Prosody 0.11.2 с уже установленной VestaCP + https force  шаблоном (nginx+apache) + dovecot + mysql + postgress + fastcgi.

Вам не обязательно ставить vestacp, это лишь у меня стоит, но тогда  надо будет заморочиться с установкой apache2 для работы external upload  модуля файлов, но если у вас хост всего 1 и не планируете добавлять  домены новые то можно не париться на тему установки веб сервера  и работать со встроенным в prosody и использовать для файлов обычный  http_upload, а не http_upload_external.

Открыть порты в файрволе Vestacp

Порты 5222,5223,5269 — обязательны, через них идет связь c2s, s2s.
Порты 5000,5280,5281 — тут не очень уверен в необходимости, 5000 это  proxy65, остальные для внутреннего http сервера prosody, который  принимает websocket, bosh. Но его я проксирую с nginx поэтому можно  закрывать а в конфиге я потом себе поставлю 127.0.0.1 интерфейс на эти  штуки, это будущая задача, пока вот в таком виде работает.

Установка Prosody + модули

Добавим репозиторий Prosody

echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list
wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add -

Обновим систему и репозитории. В идеале потом ребутнуться.

sudo apt-get update && apt-get upgarde

Теперь  можно устанавливать Prosody и пакеты для epol и для работы с БД вы  можете выбрать свою, какую хотите, оставить одну. У меня все на PG  работает.

sudo apt-get install prosody lua-event lua-dbi-postgresql lua-dbi-mysql

Установим модули в папку /opt скачаем из репозитория свежие:

cd /opt
sudo apt-get install mercurial
hg clone https://hg.prosody.im/prosody-modules/ prosody-modules
chown -R prosody:prosody /opt/prosody-modules

Обновление модулей в будущем делается так:

cd /opt/prosody-modules
hg pull -u

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

apt-get install mc

Следующий  этап это нужно создать сертификаты через VestaCP если она есть если  нет, то сами решите как получите сертификаты Letscrypt  манов в сети  полно. А я буду про весту писать, как чего.

Создали домен в весте, получили на него сертификаты в весте прям  внутри. Дальше нужно создать символические ссылки на файлы сертификатов  из папки (к примеру пользак у вас в весте admin)
из папки /home/admin/conf/web в папку /etc/prosody/certs делаем  сиволическую ссылку, я просто делал через mc а не командами в консоли  и на ссылку поставить права на чтение для всех. Это конечно не совсем  верное решение, надо бы подумать над тем, что бы prosody добавить  в группу пользака admin в будущем, так как это может не заработать,  когда обновится сертификат, vesta может переписать права, тут момент  спорный не спорю, но пока работает. Дальше бы изменил.

Нюанс как называть символические ссылки из весты в prosody, так как  он ищет именно эти названия файлов в своем каталоге с сертификатами:

VestaProsody ссылкаssl.domain.com.pemdomain.com.crtssl.domain.com.keydomain.com.key

Еще для пущей безопасности умные люди советуют
Ключ Диффи-Хеллмана сделать:

cd /etc/prosody/certs/
openssl dhparam -out dh-2048.pem 2048
chown prosody:prosody dh-2048.pem
chmod u=rw,go= dh-2048.pem

Dovecot

Открываем файл /etc/dovecot/conf.d/10-master.conf на редактирование, находим секцию service auth и вписываем в неё:

service auth {
    unix_listener prosody-auth-client {
        mode = 0660
        user = prosody
        group = prosody
    }
}

Альтернативый вариант в файл /etc/dovecot/dovecot.conf это записать до строчки: !include conf.d/*.conf

Пользователь

Создайте в вашем домене почтовый ящик для админа, логин и пароль будут такие же для Jabber как и для почты.

Домен для upload файлов

Что бы нормально работала загрузка файлов, когда у вас несколько  виртуальных хостов, то обязательно нужно использовать  mod_http_upload_external иначе будут проблемы с сертификатами,  и отправка файлов будет работать нормально только на одном  из виртуальных хостов, а другие будут ругаться на ошибочный сертификат,  заставить работать на встроенном в prosody веб сервере загрузку файлов  и привязать к каждому домену свой я так и не смог, просто применил  внешний веб сервер и все.

  1. Создайте в VestaCP домен upload.domain.com и получите на него сертификат.
  2. Из папки /opt/prosody-modules/mod_http_upload_external скопируйте  файл share_v2.php в папку /home/admin/web/upload.domain.com/public_html/
  3. Создайте папку в любом месте удобном на сервере, но не в папке  public_html папку uploads и дайте на него все права пользователю admin  что бы в нее складывались загруженные пользователями файлы.
  4. Сделайте владельцем файла share_v2.php в папке веб сервера пользака  admin (при условии, что сам домен uploads в vestacp создан  под пользователем admin, если вы не используете весту то у вас пользак  www-data это касается прав и п. 3) и поставьте права на исполнение.
  5. В файле  share_v2.php отредактируйте строки:
/* Change this to a directory that is writable by your web server, but is outside your web root */
$CONFIG_STORE_DIR = '/var/lib/prosody/uploads'; 

/* This must be the same as 'http_upload_external_secret' that you set in Prosody's config file */
$CONFIG_SECRET = 'набор символов большой как пароль для просоди он нужен будет в конфиге просоди';

$CONFIG_STORE_DIR — полный путь к папке uploads которую вы сделали в шаге 3.
$CONFIG_SECRET  — Произвольный большой пароль для prosody когда он будет лить файлы

PHP и fcgid

Для загрузки больших файлов и снятия ограничения надо отредактировать файлы конфигов отвечающих за выполнение скриптов

nano /etc/apache2/mods-enabled/fcgid.conf

Добавить:

MaxRequestLen 2000000000

Я  не стал париться и сделал ограничение в 2гб на сервере, вы можете  сделать меньше, этот объем для сервера prosody будет регулироваться еще  и в конфиге.

Так же на всякий случай я сделал следующие изменения в файлах:

/etc/php/7.2/apache2/php.ini
/etc/php/7.2/cgi/php.ini
/etc/php/7.2/cli/php.ini

Установил следующие параметры для загрузки файлов и выполнение скриптов

max_execution_time = 600
max_input_time = 600
post_max_size = 2000M
upload_max_filesize = 2000M
max_file_uploads = 200

В файле /etc/nginx/nginx.conf
Параметр изменить надо тоже, вы можете ставить везде не 2гб как я а скажем 500m как хотите:

client_max_body_size            2000m;

Это сняло ограничение на mod_http_upload_external ну вернее на nginx, который файлы эти закачивал.

Prosody

Я постарался сделать так, что бы лего можно было добавлять новые  virtualhost для обслуживания сервером, что бы не париться  с сертификатами  и работоспособностью загрузки файлов. Для добавления  новых хостов, вам нужно будет только создать домен в vestacp, сделать  символические ссылки на сертификаты как делали выше по инструкции  и добавить новый файл domain.com.cfg.lua в папку /etc/prosody/conf.d/  и он автоматом подключиться и будет работать после рестарта просоди.

Сам конфиг постарался причесать как смог, но в нем есть конечно еще  вопросы у меня о необходимости тех или иных модулей в текущем времени,  например я не уверен в необходимости подключения proxy65  с учетом того,  что вся загрузка практически идет через http. Хз в общем насколько это  актуально.

Большой головной болью для меня на целый день стала плохая работа  ChatSecure вернее push уведомления не приходили, буквально уже через  минуту, как chatsecure уходил в спячку на iPhone, пуши переставали  приходить, я долго рыл форумы, пока не нашел причину, при погоне  за секурностью сертификатов и отличных результатов на xmpp.net я  отключил много вариантов шифрования по рекомендациям на других сайтах,  на этом и погорел, ну я так думаю по крайней мере в результате, что бы  пуши нормально начали доходить, надо было обязательно добавить следующе  вещи в конфиг помимо самого модуля mod_cloud_notify
следующие модули

"filter_chatstates";
 "pinger";
 "throttle_presence";

И добавить в раздел SSL ciphers:

AES256-GCM-SHA384

Ну я так думаю, если бы я не использовал всякие опции для SSL то проблем бы и не было.

Безусловно нужно включить mam, pep и smack и smack_offline это  описано в мануалах тут вопросов не было. Но не очевидные вещи я описал  выше.

Весь конфиг с моими комментариями НЕ КОПИРУЙТЕ БЕЗДУМНО:

/etc/prosody/prosody.cfg.lua

--конфиг взят с  markevich.ru

admins = { "login@domain.ru" }

---Запрещаем регистрацию---
allow_registration = false
-----------------------------------

----служебное барахло для запуска---
--use_libevent = true -- ОТКЛЮЧЕНО, нельзя было авы поставить на чатсекуре, в логах были ошибки с днс связанные косвенно это изза епула, так нарыл в нете, отключил. Более хорошо стал работать на медленных соединениях это у меня субъективно.
daemonize = true;
pidfile = "/var/run/prosody/prosody.pid";

---------------------------------
default_storage = "sql"

-- POSTGRES SQL driver
---------------------------------

sql = {
    driver = "PostgreSQL";
    database = "prosody";
    host = "localhost";
    port = 5432;
    username = "prosody";
    password = "пароль от бд";
}

--Может ли просоди сам управлять своими таблицами и делать ремонт, рекомендовано.
sql_manage_tables = true

--------------------------------

---TLS для сервера--------------
certificates = "/etc/prosody/certs"

--Оставляем только лучшие методы шифрования, очень долго подбирал, искал и получилось почти идеально.

ssl = {
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_encryption_exceptions = {
    "cisco.com",
    "gmail.com",
}

s2s_secure_auth = true;

--Для ботов своих или старых клиентов обычно включают старый вариант авторизации на отдельном порту
legacy_ssl_ports = { 5223 }

-------------------------------
-- Prosody Module 
---------------------------------

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_web";  регистрация отключена, значит не надо.
                        "register";
                        "posix";
                        "bosh";
                        "announce";
                        "proxy65";
                        "pep";
                        "smacks";
                        "smacks_offline";
                        "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";
                        "http_upload_external"; --если нужна загрузка файлов на внешний сервер, вдруг у вас больше 1 домена обслуживается.
                        --"http_upload"; включать вместо пункта выше, все настройки под него так же есть в конфиге.
};
---------------------------------
--
-- Включаем логи, после отладки закоментить все кроме error
----------------------------------

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";
}

------------------------------------
--
-- MAM settings
----------------------------
default_archive_policy = true;
archive_expires_after = "4w";

---------------------------
-- HTTP Upload settings НЕ УВЕРЕН В НЕОБХОДИМОСТИ ЭТОЙ ХРЕНИ в связи с подключением external если что уберу или попробуйте сами убрать
----------------------------
http_max_content_size = 524288000;
http_upload_file_size_limit = 524288000;
http_upload_path = "/var/lib/prosody/http_upload";
http_max_content_size = 7000000000
http_upload_expire_after = 2592000
https_ports = { 5281 }
http_ports = { 5280 }
--------------------------------------

---EXTERNAL HTTP UPLOAD - работающее решение сейчас
--Путь до файла share_v2 URL должен быть обязательно с / на конце!
http_upload_external_base_url = "https://upload.domain.ru/share_v2.php/"
http_upload_external_secret = "тот самый пароль большой из share_v2.php"
http_upload_external_file_size_limit = 2147483648
http_upload_external_protocol = "v2";
--------------------------------

-- Websocket нужен для того, что бы через веб-клиенты можно было подключаться
consider_websocket_secure = true;

------------------------------------
--
-- Bosh config та же песня для веб херни
----------------------------------
cross_domain_bosh = true;
consider_bosh_secure = true;

---------------------------------
--
-- SMACK settings помогает на мобилах не засыпать и пуши сраные что бы работали
----------------------------------

smacks_enabled_s2s = true
smacks_hibernation_time = 86400
smacks_max_unacked_stanzas = 0
smacks_max_ack_delay = 5
smacks_max_hibernated_sessions = 20
smacks_max_old_sessions = 20

--
-- Push fix for ChatSecure настройка пушей, что бы не отправлял на сервер пушей текст, один хрен он шифрованный, а показывал лишь юхав масаж. что бы данные не летали на сервак пушей

push_notification_important_body = "You have new message"
push_notification_with_body = false
push_notification_with_sender = false

-----PINGER переодически опрашиваем серваки и клиенты на жив ли ты бро, в будущем думаю отключить, если не повлияет на пуши и доставку сообщений на мобилы.

c2s_idle_timeout = 30
c2s_ping_timeout = 30

----
--- Contact info - для красоты проверки комплаинсом
---------------------------------
contact_info = {
  abuse         = { "mailto:abuse@domain.com", "xmpp:abuse@domain.com.ru" };
  admin         = { "mailto:abuse@domain.com.ru", "xmpp:abuse@domain.com.ru" };
  feedback      = { "mailto:abuse@domain.com.ru", "xmpp:abuse@domain.com.ru" };
  sales         = { "mailto:abuse@domain.com.ru", "xmpp:abuse@domain.com.ru" };
  security      = { "mailto:abuse@domain.com.ru", "xmpp:abuse@domain.com.ru" };
  support       = { "mailto:abuse@domain.com.ru", "xmpp:abuse@domain.com.ru" };
};

---ПОДГРУЖАЕМ КОНФИГ ДОМЕНОВ---
Include "conf.d/*.cfg.lua"

Конфиг virtualhost

/etc/prosody/conf.d/domain.ru.cfg.lua

plugin_paths = { "/opt/prosody-modules/" }

VirtualHost "domain.ru"
http_host = "domain.ru"

        authentication = "dovecot"
        dovecot_auth_socket = "/var/run/dovecot/prosody-auth-client"
        auth_append_host = true
       

modules_enabled = {
       -- "groups"; если нужен то раскоментить подробности ниже.
}

--файл со списком пользаков, которые добавляются в этом виртуал хосте по умолчанию,
-- это полезно когда делаете виртуал хост для ограниченого числа людей, компании, семью и тп, может быть себя
--во все ростеры хотите включить или поддержку или бота. если надо раскоментите и формат файла такой
--посмотреть на https://prosody.im/doc/modules/mod_groups
--groups_file = "/etc/prosody/share.txt" 

Component "conference.domain.ru" "muc"
        name = "domain.ru 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

Component "pubsub.domain.ru" "pubsub"

disco_items = {
    { "conference.domain.ru", "The domain.ru MUC" };
}
proxy65_acl = { "domain.ru" }

Дальше собственно рестартуем prosody

/etc/init.d/prosody restart

и пробуйем подключаться с учеткой почтовой, все должно взлететь.

Шаги за рамками данного мануала:

  1. Настройка проксирования nginx на bosh и websocket
  2. Настройка meta файлов для альтернативного подключения через nginx
  3. настройка DNS

Даже без этих шагов все и так хорошо, но ДНС бы прописать, что бы получить результаты проверки красоты на комплайнс конференс.

0 Комментарии
Загрузка...