Metronome IM і Jappix: багатофункціональний Jabber, без складнощів у налаштуванні


Що якщо я розповім вам як без особливих зусиль підняти свій власний jabber-сервер зі всіма новомодними фичами, такими як: копіювання, синхронізація повідомлень між клтентами, сповіщення про прочитання, публічні чати і багато іншого…
Так само поділюся з вами чудовим Jabber-клієнт який не менш цікавий, він підтримує аудіо та відео дзвінки, має непоганий інтерфейс і працює прямо з браузера.
Те й інше ви отримаєте абсолютно безкоштовно, так-як і сервер і клієнт ліцензуються за свободнлй ліцензії.

Мова піде про Metronome IM та Jappix.

Варто взяти до уваги те, що обидва проекти можуть працювати незалежно один від одного, до Metronome IM, все так же можна підключатися будь Jabber-клієнтом, а Jappix може використовуватися для будь-якого іншого Jabber-сервера, що підтримує BOSH.

image
Metronome IM
Author: Marco Cirillo
Site: lightwitch.org/metronome
License: MIT
Written in: Lua

І так, почнемо мабуть з серверної частини.

Metronome IM — це Jabber-сервер, форк небезізвестного Prosody IM, про який вже не раз писали на Хабре. На відміну від Prosody, Metronome створений в першу чергу для підтримки різних соціальних фішок, таких як pubsub, user activity, mood, і інших, але не вони в першу чергу нас цікавлять.
Повний список всіх XEP, які працюють з коробки, ви можете знайти на цій сторінці. Погодьтеся, список досить вселяє!

Серед усіх XEP є: і Message archive (архів листів), і Carbons (синхронізація повідомлень між клієнтами), і Offline Messages (офлайнові повідомлення)… Для тих хто не знає, у багатьох інших jabber-серверів, за замовчуванням, все це працює доволі посередньо і вимагає доопрацювання напилком.
У Metronome IM ж, всі XEP працюють коректно відразу з коробки і на більшості Jabber-клієнтів.
З практики можу сказати, що у вас швидше за все більше не буде таких неприємних глюків, коли ваше повідомлення кудись загубиться, продублюється, або буде відображатися на одному клієнті, а інший його навіть не побачить.

Плюс до всього, сервер написаний на lua, має багато модулів і досить простий для розуміння конфіг.
Так само до нього підійде більшість модулів від Prosody IM після невеликого допила, але цього, я впевнений, вам, в більшості випадків, навіть не знадобиться.

Установка
За умолчанмю Metronome IM не поставляється у вигляді готових пакетів, тому будемо збирати його з исходников, ви так само можете встановити його за допомогою Docker

Для початку встановимо залежності:

Ubuntu / Debian:
apt-get update
apt-get -y install libssl-dev libidn11-dev build-essentials lua5.1 liblua5.1-dev liblua5.1-bitop-dev liblua5.1-expat-dev liblua5.1-event-dev lua5.1-posix-dev lua5.1-sec-dev lua5.1-socket-dev lua5.1-filesystem-dev


CentOS:
ням -y install epel-release
yum -y install gcc lua-devel openssl-devel libidn-devel lua-expat lua-socket lua-filesystem lua-sec lua-dbi lua-event

# Install lua-zlib module
curl https://codeload.github.com/brimworks/lua-zlib/tar.gz/v0.4 | tar xzv -C /usr/src/
cd /usr/src/lua-zlib-0.4/
make linux
make install

# Install lua-bitop module
curl http://bitop.luajit.org/download/LuaBitOp-1.0.2.tar.gz | tar xzv -C /usr/src/
cd /usr/src/LuaBitOp-1.0.2
make
make install


Завантажити вихідні коди, зберемо і встановимо їх:
useradd -r -s /sbin/nologin -d /var/lib/metronome metronome
curl -L https://github.com/maranda/metronome/archive/v3.7.tar.gz | tar xz -C /usr/src/
cd /usr/src/metronome*
./configure --prefix=/usr --sysconfdir=/etc/prosody --datadir=/var/lib/prosody --require-config --ostype=debian # --ostype=linux
make && make install
mkdir /var/log/metronome /var/run/metronome
chown metronome: /var/lib/metronome /var/log/metronome /var/run/metronome


Створимо unit для systemd: /etc/systemd/system/metronome.service
[Unit]
Description=XMPP (Jabber Server
After=network.target

[Service]
Type=forking
PIDFile=/run/metronome/metronome.pid
ExecStart=/usr/bin/metronomectl start
ExecStop=/usr/bin/metronomectl stop

[Install]
WantedBy=multi-user.target

Установка завершена

Налаштування
Завантажити конфіг metronome.cfg.lua люб'язно наданий нам сервісом jappix.com

Після незначних правок у мене вийшов приблизно такий конфіг:
metronome.cfg.lua
-- Prosody XMPP Server Configuration
--
-- Information on configuring Prosody can be found on our
-- website at http://metronome.im/doc/configure
--
-- Tip: You can check that the syntax of this file is correct
-- when you have finished by running: metronomectl check config
-- If there are any errors, it will let you know what and where
-- they are, otherwise it will keep quiet.
--
-- 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 http://metronome.im/doc/creating_accounts for info)
-- Example: admins = { "user1@example.com", "user2@example.net" }
admins = { }

-- Required for init scripts and metronomectl
pidfile = "/var/run/metronome/metronome.pid"

-- ulimit
metronome_max_files_soft = 200000
metronome_max_files_hard = 200000


-- HTTP server
http_ports = { 5280 }
http_interfaces = { "0.0.0.0", "::" }

https_ports = { 5281 }
https_interfaces = { "0.0.0.0", "::" }

-- Enable IPv6
use_ipv6 = true

-- This is the list of modules Prosody will load on startup.
-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too.
-- Documentation on modules can be found at: http://metronome.im/doc/modules

modules_enabled = {

-- Generally required
--"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
"dialback"; -- s2s dialback support
"disco"; -- Service discovery
"extdisco"; -- External Service Discovery


-- Not essential, but recommended
--"private"; -- Private XML storage (for room bookmarks, etc.)
--"vcard"; -- Allow users to set vCards

-- These are commented by default as they have a performance impact
"compression"; -- Stream compression (requires the lua-zlib package installed)

-- Nice to have
"version"; -- Replies to server version requests
"uptime"; -- Report how long server has been running
"time"; -- Let others know the time here on this server
"ping"; -- Replies to XMPP pings with pongs
--"pep"; -- Enables users to publish their mood, activity, playing music and more
--"register"; -- Allow users to register on this server using a client and change passwords

-- Admin interfaces
"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
--"admin_telnet"; -- Opens telnet console interface on localhost port 5582

-- HTTP modules
"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
"websocket"; -- Enable WebSocket clients 
--"http_files"; -- Serve static files from a directory over HTTP

-- Other specific functionality
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
"bidi"; -- Bidirectional Streams for S2S connections
"stream_management"; -- Stream Management support
--"groups"; -- Shared roster support
--"announce"; -- Send announcement to all online users
--"welcome"; -- Welcome users who register accounts
--"watchregistrations"; -- Alert admins of registrations
--"motd"; -- Send a message to users when they log in
"legacyauth"; -- Legacy authentication. Only used by some old clients and bots. 
"log_auth";
}

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

-- Discovery items
disco_items = {
{ "muc.example.org" },
{ "proxy.example.org" },
{ "pubsub.example.org" },
{ "vjud.example.org" }
};

-- External Service Discovery (mod_extdisco)
external_services = {
["stun.example.org"] = {
[1] = {
port = "3478",
transport = "udp",
type = "stun"
},

[2] = {
port = "3478",
transport = "tcp",
type = "stun"
}
}
};

-- Bidirectional Streams configuration (mod_bidi)
bidi_exclusion_list = { "jabber.org" }

-- BOSH configuration (mod_bosh)
bosh_max_inactivity = 30
consider_bosh_secure = true
cross_domain_bosh = true

-- WebSocket configuration (mod_websockets)
consider_websockets_secure = true
cross_domain_websockets = true

-- Disable account creation by default, for security
allow_registration = false

-- Ignore priority settings
ignore_presence_priority = true

-- These are the SSL/TLS-related settings. If you don't want
-- to use SSL/TLS, you may or remove this comment
ssl = {
key = "./etc/metronome/certs/localhost.key";
certificate = "./etc/metronome/certs/localhost.cert";
options = {
"no_sslv2",
"no_sslv3",
"no_ticket",
"no_compression",
"cipher_server_preference"
};

}

-- Force clients to use encrypted connections? This option will
-- prevent from clients authenticating unless they are using encryption.

c2s_require_encryption = true

-- Force servers to use encrypted connections? This option will
-- prevent servers from connecting unless they are using encryption.

s2s_require_encryption = true

-- Allow servers to use an unauthenticated encryption channel

s2s_allow_encryption = true

-- Don't require encryption for listed servers
s2s_encryption_exceptions = {
"cisco.com",
"gmail.com"
}

-- Logging configuration
-- For advanced logging see http://metronome.im/doc/logging
log = {
info = "/var/log/metronome/metronome.log"; -- Change 'info' to 'debug' for verbose logging
error = "/var/log/metronome/metronome.err";
-- "*syslog"; -- Uncomment this for logging to syslog
-- "*console"; -- Log to the console, useful for debugging with daemonize=false
}

activity_log_dir = "/var/log/metronome/activity_log"

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

----------- 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 host that.

VirtualHost "example.org"
enabled = true
default_storage = "sql"

modules_enabled = {
-- Generally required
"roster"; -- Allow users to have a roster. Recommended ;)

-- Not essential, but recommended
"private"; -- Private XML storage (for room bookmarks, etc.)
"vcard"; -- Allow users to set vCards

-- These are commented by default as they have a performance impact
"mam"; -- Message Archive Management
"privacy"; -- Support privacy lists

-- Nice to have
"lastactivity"; -- Logs the user last activity timestamp
"pep"; -- Enables users to publish their mood, activity, playing music and more
"message_carbons"; -- Allow clients to keep in sync with send messages on other resources
--"register"; -- Allow users to register on this server using a client and change passwords
--"register_redirect"; -- Redirects users registering to the registration form
"public_service"; -- Provides some information about the server XMPP
--"log_activity"; -- Activity log, module from https://github.com/jappix/jappix-xmppd-modules
"groups"; -- Shared groups

-- Admin interfaces
--"admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
}

groups_file = "./etc/metronome/groups.txt"

resources_limit = 10

no_registration_whitelist = true
registration_url = "https://example.org/"
registration_text = "Please register your account on Jappix itself (open example.org in your Web browser). Then you'll be able to use it anywhere you want."

public_service_vcard = {
name = "Jappix XMPP service",
url = "https://example.org/",
foundation_year = "2010",
country = "RU",
email = "admin@example.org",
admin_jid = "admin@example.org",
geo = "48.87,2.33",
ca = { name = "StartSSL", url = "https://www.startssl.com/" },
oob_registration_uri = "https://example.org/"
}

VirtualHost "anonymous.example.org"
enabled = true
authentication = "anonymous"
allow_anonymous_multiresourcing = true
allow_anonymous_s2s = true
anonymous_jid_gentoken = "Jappix Anonymous User"
anonymous_randomize_for_trusted_addresses = { "127.0.0.1", "::1" }

------ Components ------
-- You can specify components to add hosts that provide special services,
-- like multi-user conferences, and transports.

---Set up a MUC (multi-user chat) room on server muc.example.org:
Component "muc.example.org" "muc"
name = "Jappix Chatrooms"

modules_enabled = {
"muc_limits";
"muc_log";
"muc_log_http";
"pastebin";
}

muc_event_rate = 0.5
muc_burst_factor = 10

muc_log_http_config = {
url_base = "logs";
theme = "metronome";
}

pastebin_url = "https://muc.example.org/paste/"
pastebin_path = "/paste/"
pastebin_expire_after = 0
pastebin_trigger = "!paste"

---Set up a PubSub server
Component "pubsub.example.org" "pubsub"
name = "Jappix Publish/Subscribe"

--unrestricted_node_creation = true -- Anyone can create a PubSub node (from any server)

---Set up a service VJUD
Component "vjud.example.org" "vjud"
ud_disco_name = "Jappix User Directory"
synchronize_to_host_vcards = "example.org"

---Set up a BOSH service ( https://bind.example.org:5281/http-bind )
Component "bind.example.org" "http"
modules_enabled = { "bosh" }

---Set up a service WebSocket
Component "websocket.example.org" "http"
modules_enabled = { "websocket" }

---Set up a BOSH + WebSocket service
Component "me.example.org" "http"
modules_enabled = { "bosh", "websocket" }

---Set up a statistics service
Component "stats.example.org" "http"
modules_enabled = { "server_status" }

server_status_basepath = "/xmppd/"
server_status_show_hosts = { "example.org", "anonymous.example.org" }
server_status_show_comps = { "muc.example.org", "proxy.example.org", "pubsub.example.org", "vjud.example.org" }

-- Set up a SOCKS5 bytestream proxy server for-proxied file transfers:
Component "proxy.example.org" "proxy65"
proxy65_acl = { "example.org", "anonymous.example.org" }

Конфіг дуже добре прокоментирован і я не бачу особливого сенсу залишати додаткові коментарі з мого боку.
Скажу лише те, що якщо ви плануєте установку jappix або будь-якого іншого web-клієнта, то вам буде необхідний компонент BOSH. Саме через нього ваш web-клієнт буде спілкуватися з вашим сервером.

Дізнатися більше про конфігурування сервера і подивитися приклади ви можете на офіційному сайті проекту.

Не забуваємо прописати необхідні DNS-записи на нашому DNS-сервері:
xmpp IN A 1.2.3.4
muc IN CNAME xmpp
pubsub IN CNAME xmpp
vjud IN CNAME xmpp
bind IN CNAME xmpp
websocket IN CNAME xmpp
me IN CNAME xmpp
stats IN CNAME xmpp
proxy IN CNAME xmpp
anonymous IN CNAME xmpp
_xmpp-client._tcp.example.org. IN SRV 0 5 5222 xmpp.example.org.
_xmpp-server._tcp.example.org. IN SRV 0 5 5269 xmpp.example.org. 


Запускаємо сервіс:
systemctl enable metronome
systemctl start metronome

Перевіряємо логи.
Якщо все ок, створюємо користувача:
prosodyctl adduser me@example.com

І пробуємо підключитися.
Наш сервер готовий!

image
Jappix
Author: Valérian Saliou, Julien Barrier
Site: jappix.org
License: AGPL
Written in: JavaScript
Demo: jappix.com

Як я вже говорив Jappix — це Jabber-клієнт, який має досить непоганий інтерфейс, підтримує аудіо та відео дзвінки, так само підтримує більшість популярних XEP і працює прямо з вікна браузера.

Сам клієнт виглядає приблизно так:
Прихований текстimage
Так само він має зменшену версію, для вбудови на сайт:
Прихований текстimageimage

Установка
Настав час для установки нашого клієнта.

Установка не являє ссобой щось нетривіальне. Всі дії зводяться до того, що б скопіювати файли проекту в директорію вашого веб-сервера. Але ви так само можете встановити Jappix використовуючи Docker.

І так приступимо, встановимо залежності:

Debian/Ubuntu:
apt-get install php5-gd php5-curl

CentOS:
yum install php mbstring


Тепер скачаємо jappix-1.1.6-primo.tar.bz2 і распакуем його в /var/www
curl -L https://download.jappix.org/1.1.6/jappix-1.1.6-primo.tar.bz2 | tar xvj -C /var/www


Напишемо конфіг для нашого веб-сервера, наприклад для nginx він буде виглядати приблизно так:
jappix.conf
server {
listen 80;
server_name jappix.example.org;
return 301 https://jappix.example.org$request_uri;
}

server {
listen ssl 443;
server_name jappix.example.org;
root /var/www/jappix;
index index.html index.php;

access_log /var/log/nginx/jappix-access.log;
error_log /var/log/nginx/jappix-error.log;

# Configuration SSL
# Support du HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=315360000; includeSubdomains";

# Configuration SSL
ssl_certificate /etc/nginx/certificates/common-ssl.cert;
ssl_certificate_key /etc/nginx/certificates/common-ssl.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";

location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
try_files $uri =404;
fastcgi_index index.php;
fastcgi_pass php5-fpm-sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 25M \n
post_max_size = 25M \n
max_execution_time = 600";
}

location ~ /(app|i18n|log|test|tmp|tools)/ {
deny all;
}
}

Перезапускаємо веб-сервер.

Більш детальну інформацію про установки ви можете знайти в офіційній wiki проекту.

Налаштування
Jappix має графічний інсталятор. Заходимо за посиланням:
https://jappix.example.org/?m=install

Створюємо адміністратора, відповіді на інші питання, вводимо адреси до нашого сервера.

Ось так виглядає страгичка налаштувань сервера:
Прихований текстimage
Коли інсталяцію буде завершено, вас перекине на вікно логіна.
Прихований текстimage
Надалі ви зможете потрапити в адмінку за наступним посиланням:
https://jappix.example.org/?m=manager


let's Encrypt
Пара слів про сертифікати.

Залишати сервер з самоподписанним сертифікатами не є добре, потрібно встановити хоча б безкоштовний.
Ми зробили доволі багато субдоменів, так що одного безкоштовного сертифікату нам для всіх не вистачить, а отримувати для кожного окремий буде досить накладно. Вихід є — це let's Encrypt.

На хабре MalcolmReynolds вже описував процедуру отримання сертифікатів у let's Encrypt.
Так само є пара класних статей на DigitalOcean — nginx apache

Але, якщо ви використовуєте Docker, то пропоную вам спробувати мій спосіб: kvaps/letsencrypt-webroot

Дякую за увагу!

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.