Jabber Prosody установка на Ubuntu 18.04 с работающими звонками под Conversations

xmpp prosody сервер на максималках с блек-джеком и мадмуазелями

Jabber Prosody установка на Ubuntu 18.04 с работающими звонками под Conversations

Прошёл год, после того как я написал предыдущий мануал и много чего изменилось, главное: это в Conversations подключили поддержку звонков, а по старому мануалу она не работала да и пора отвязаться от dovecot со всеми вытекающими. Думал сделаю за 2 часа, провозился все выходные. И так вашему вниманию мануал по установке своего собственного jabber сервера в 2020 году. И да Matrix до сих пор в топку, с его непонятным сервером идентификации, который до сих пор не сделали для селф-хост размещения, такие танцы нам не интересны, хотя по-умолчанию отключили его использование, если не вводить почты и телефона.

По ману получим:

  • Prosody + модули + OMEMO естественно
  • Conversejs на главной сайта с работающим OMEMO
  • Регистрацию через веб-морду по закрытой паролем ссылке для своих, кому дадим этот пароль
  • Загрузку файлов через http_upload_external на perl модуле nginx
  • Reverse proxy nginx для всего, что торчит наружу у Prosody
  • Работающие звонки видео и аудио в Conversations и везде, где они поддерживаются клиентами, поставим Cortun сервер для этого
  • Как всегда лучшее шифрование и 100% покрытие комплайнса конверсейшн, кроме открытой регистрации и старого 5223 порта
  • xmpp.net - AA уровня

Понеслась.

DNS

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

Список поддоменов запись типа А:
conference
proxy
pubsub
upload

Служебные записи:
SRV _xmpp-client._tcp.example.com. example.com. 5 0 5222
SRV _xmpp-server._tcp.example.com. example.com. 5 0 5269
TXT _xmppconnect "_xmpp-client-websocket=wss://example.com/xmpp-websocket"
TXT _xmppconnect "_xmpp-client-xbosh=https://example.com/http-bind"

Для GoDaddy выглядит так

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

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 upgrade -y && reboot

Установим nginx и модуль для upload файлов клиентами

apt -y install nginx libnginx-mod-http-perl

Создадим виртуальные хосты для домена и поддоменов, что бы сертификаты получали автоматом при обновлении их, кроме как единой точки входа и завязкой на ngnix с созданием всех поддоменов с заглушками другого решения я не нашел, стендалон вариант не прокатывает при работающем веб-сервере, 80 порт занят и проверка letscrypt не проходит. Если знаете как обойти напишите в комментариях.

Создадим общий каталог с заглушкой для всех ненужных доменов:

mkdir /var/www/staff
touch /var/www/staff/index.html
chown -R www-data:www-data /var/www/staff

nano /etc/nginx/sites-enabled/example.com

server {

       server_name example.com;

       location / {
            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;
        }

       
		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 /.well-known {
       proxy_pass  http://localhost:5280/.well-known;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_buffering off;
            tcp_nodelay on;
  }
		
	}

Хост для аплоуда:

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/staff;
       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/staff;
       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/staff;
       index index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

Хосты созданы, сертификаты чуть позже автоматом пропишет certbot.

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

perl -le 'print crypt("ПарольДляДоступакВебРеги", "ЛюбойНаборСимволовдляхеша")'

Запоминаем сгенеренный пароль и записываем в файл в формате.
логин:пароль

mkdir /var/www/protect
nano /var/www/protect/.htpasswd

Подключим к нжинксу модуль, для аплоада файлов

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 

В отдел http добавьте:

perl_modules /usr/local/lib/perl; # Path to upload.pm.
perl_require upload.pm;
client_max_body_size 4096m;

Отредактируем сам модуль настроим его:

nano /usr/local/lib/perl/upload.pm
Найдите строчку my $external_secret = 'Итутвпишитеогромныйпаоль'

Нужно заполнить секретный пароль  сделайте набор из 40-50 разных символов. Его потом надо будет вставлять в конфиг prosody.

Рестарт nginx и проверяем, работает ли.

systemctl restart nginx.service
systemctl status nginx.service

Дальше установим сертбот и запросим сертификаты на все домены. При вопросе ставить ли редирект отвечаем 2 да, ставить.

apt install -y 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-get install postgresql postgresql-contrib

В конфиге ставим слушать только 127.0.0.1

nano /etc/postgresql/10/main/postgresql.conf
listen_addresses = '127.0.0.1'

service postgresql restart

Делаем пользака для БД:

su - postgres
createuser --pwprompt prosodyuser

Создаем БД

psql

Втыкаем команды ему:

CREATE DATABASE prosodyuser
 OWNER prosodyuser;

Ctrl+z, exit, exit.
Не забываем пароль, он нужен будет для конфига сервера.

Установка Prosody

Теперь   можно устанавливать Prosody и пакеты для работы с  БД

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

Установим модули в папку /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
sudo -u prosody hg pull -u

Создадим папку для пид файла и дадим права:

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

Установим еще пакет для работы импорта сертификатов серваком

sudo apt-get install lua-sec

Теперь надо отрихтовать конфиг просоди. в этот раз все одним файлом.

----служебное барахло для запуска---
daemonize = true;
pidfile = "/var/run/prosody/prosody.pid";

---админы---
admins = { "admin@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

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

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

--http server--
http_host = "127.0.0.1"
http_ports = { 5280 }
https_ports = { }
http_interfaces = { "127.0.0.1" }
trusted_proxies =  "127.0.0.1"

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

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

---------------------------------
--
-- Включаем логи, после отладки закоментить все кроме 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 = "1w";

---EXTERNAL HTTP UPLOAD -
--Путь до файла share_v2 URL должен быть обязательно с / на конце!
http_upload_external_base_url = "https://upload.example.com/"
http_upload_external_secret = "ВАШ БОЛЬШОЙ СЕКРЕТНЫЙ КЛЮЧ ИЗ ФАЙЛА АПЛОАДА"
http_upload_external_file_size_limit = 4294967296 --4Gb
--------------------------------

--шаблон для веб реги---
register_web_template = "/etc/prosody/register-templates/prosody_web_registration_theme"

--настройки веб клиента + подключим что бы OMEMO работало скрипт---
conversejs_options = {
    debug = false;
    view_mode = "fullscreen";
}
conversejs_tags = {
        -- Load libsignal-protocol.js for OMEMO support (GPLv3; be aware of licence implications)
        [[<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>]];
}


-- Websocket нужен для того, что бы через веб-клиенты можно было подключаться
consider_websocket_secure = true;
cross_domain_websocket = 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

---TURN STUN для звонков с conversations---
turncredentials_host = "example.com"
turncredentials_secret = "БОЛЬШОЙПАРОЛЬИЗТУРНСЕРВЕРА"


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

-------------------------Настройка доменов-----------------------


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

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", "The example.com MUC" };
}

Component "pubsub.example.com" "pubsub"
Component "proxy.example.com" "proxy65"
proxy65_acl = { "example.com" }

Все поправили под себя в плане домена, а теперь мы готовы импортировать сертификаты, но сначала рестартнем просоди для надежности.

systemctl restart prosody.service
systemctl status prosody.service

Импортируем:

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

Добавим красивую морду для регистрации:

mkdir /etc/prosody/register-templates/ 
cd /etc/prosody/register-templates 
git clone https://github.com/crypto-world/prosody_web_registration_theme

По адресу: https://example.com/register_web будет регистрация. Логин и пароль вы вводили, когда генерили его перлом и создавали файл .htpasswd

Cortun для звонков

sudo apt install coturn

Геренируем секретный ключ который вставите потом в конфиг просоди и турна

pwgen -s 64 1

сохранить код в блокнот.

Правим конфиг

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

Включаем TURN

nano /etc/default/coturn
расскоментируйте срочку енабле 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
sudo ufw status

У модуля аплоада пока нет в реализации удаления старых файлов,  которые были  переданы пользаками, они хранятся вечно, но место  не резиновое,  приходится удалять руками, поэтому сделаем скрипт.

cd /etc/cron.daily/
nano deloldfiles

Втыкаем (удаляеет старее 30 дней)

#!/bin/sh
find /upload/ -type f -mtime +30 -exec rm -v {} \;

Делаем файл исполняемым

chmod +x deloldfiles

Всё. Теперь у нас есть:

Регистрация пользователей по адресу: https://example.com/register_web

Веб-клиент: https://example.com

Ну и полностью рабочий сервер с хорошими результатами.

+Бонус, сообщение которое можете отправлять друзьям:

Давай общаться с реальным e2e шифрованием (видео,звук, чаты)

Регистрация:
https://example.com/register_web
логин:
пароль:

Android:
https://play.google.com/store/apps/details?id=de.pixart.messenger&hl=ru
или
https://play.google.com/store/apps/details?id=eu.siacs.conversations&hl=en_US
iOS: https://apps.apple.com/ru/app/chatsecure-messenger/id464200063
Linux: https://dino.im
Mac: https://monal.im
Windows: https://gajim.org/
Web: https://example.com

Для авторизации вводите полный jid вида: логин@example.com
0 Комментарии
Загрузка...