С уходом привычных мессенджеров я задумался о собственном чате для локальной сети. Мой выбор пал на XMPP: это открытый протокол, сервер можно развернуть внутри организации. В качестве сервера я выбрал ejabberd 24.12: он умеет авторизовывать пользователей по доменным учётным записям Active Directory. Ещё один плюс XMPP — большой выбор готовых клиентов. Но у многих из них есть общий минус: интерфейс выглядит как у программ начала 2000-х. Поэтому позже я написал собственный локальный клиент для Windows; о нём расскажу в конце статьи. А сначала покажу, как я развернул сервер ejabberd.

Выбор бесплатного сервера для чата в корпоративной сети
Я посмотрел разные варианты и в итоге остановился на старом добром, проверенном временем протоколе XMPP. В качестве сервера выбрал ejabberd 24.12. У XMPP много готовых клиентов для Windows, Linux и Android, а сам сервер гибко настраивается. Особенно важной для меня была возможность авторизовывать пользователей по доменным учётным записям Active Directory. Единственный минус готовых клиентов — дизайн из начала нулевых и ограниченный привычный функционал. Этот вопрос я решил по-своему — об этом расскажу ниже.
Что получилось
Итоговая схема выглядит так:
- Debian 12 с актуальными версиями Docker Engine и Docker Compose;
- ejabberd 24.12 в контейнере ejabberd/ecs;
- XMPP-домен chat.example.local;
- клиентские подключения на TCP 5222;
- обязательный STARTTLS;
- авторизация пользователей через LDAP в Active Directory;
- общий список сотрудников, сгруппированный по подразделениям;
- хранение истории сообщений через MAM;
- групповые чаты MUC;
- передача служебных XMPP-сообщений, статусов и предложений файлов;
- локальный Windows-клиент Volna Chat;
- резервное копирование конфигурации и базы Mnesia.
В примерах используются следующие условные значения:
Сервер ejabberd: 192.0.2.34
Контроллер домена: 192.0.2.11
XMPP-домен: chat.example.local
AD-домен: example.local
LDAP bind-пользователь: svc_xmpp@example.local
Почему ejabberd
ejabberd — зрелый XMPP-сервер на Erlang. Для локального корпоративного чата важны несколько его возможностей:
- LDAP-аутентификация без создания отдельной базы паролей;
- STARTTLS и работа с собственным сертификатом;
- MAM для архива сообщений;
- MUC для групповых комнат;
- shared roster для автоматического списка сотрудников;
- HTTP API и веб-интерфейс администрирования;
- официальный Docker-образ;
- штатное резервное копирование Mnesia без остановки сервиса.
Подготовка сервера
Сервер я разворачивал на Debian 12. Установил актуальные версии Docker Engine и плагина Docker Compose, после чего создал для проекта отдельный каталог:
mkdir -p /opt/ejabberd
cd /opt/ejabberd
Перед запуском нужно проверить:
- Сервер имеет постоянный IP-адрес.
- Клиентские компьютеры видят сервер по сети.
- Сервер может обращаться к контроллерам домена по TCP 389.
- Время синхронизировано через NTP.
- Имя XMPP-сервера разрешается через корпоративный DNS либо клиенты настроены на прямой IP-адрес.
Для проверки LDAP-порта:
nc -vz 192.0.2.11 389
Docker Compose
Минимальный docker-compose.yml может выглядеть так:
services:
ejabberd:
image: ejabberd/ecs:24.12
container_name: ejabberd
restart: unless-stopped
environment:
- EJABBERD_MACRO_LDAP_BIND_PASSWORD=${LDAP_BIND_PASSWORD}
ports:
- "5222:5222" # XMPP-клиенты
- "5269:5269" # Server-to-server, если потребуется
- "5280:5280" # HTTP/Web Admin
- "5443:5443" # HTTPS/API/Upload
volumes:
- ejabberd-conf:/home/ejabberd/conf
- ejabberd-db:/home/ejabberd/database
- ejabberd-logs:/home/ejabberd/logs
- ejabberd-upload:/home/ejabberd/upload
volumes:
ejabberd-conf:
ejabberd-db:
ejabberd-logs:
ejabberd-upload:
Я предпочитаю фиксировать версию образа, а не использовать плавающий latest. Это уменьшает риск получить несовместимое обновление при очередном запуске.
Первый запуск:
docker compose up -d
docker ps
docker logs --tail 100 ejabberd
Проверка состояния:
docker exec ejabberd ejabberdctl status
Базовая конфигурация ejabberd
Основной файл — /home/ejabberd/conf/ejabberd.yml внутри контейнера. Упрощённый пример:
hosts:
- chat.example.local
loglevel: info
certfiles:
- /home/ejabberd/conf/server.pem
listen:
-
port: 5222
ip: "0.0.0.0"
module: ejabberd_c2s
starttls_required: true
max_stanza_size: 262144
-
port: 5269
ip: "0.0.0.0"
module: ejabberd_s2s_in
-
port: 5280
ip: "0.0.0.0"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
-
port: 5443
ip: "0.0.0.0"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/upload: mod_http_upload
Главный параметр здесь — starttls_required: true. Без TLS клиент не сможет перейти к авторизации. Это особенно важно при SASL PLAIN: пароль передаётся внутри защищённого TLS-канала, а не открытым текстом по сети.
После изменения конфигурации проверяем её до перезапуска:
docker exec ejabberd ejabberdctl check_config
docker restart ejabberd
docker logs --tail 100 ejabberd
Подключение Active Directory по LDAP
Для LDAP лучше создать отдельную сервисную учётную запись с минимальными правами: ей достаточно читать нужные атрибуты пользователей и подразделений. Не следует использовать учётную запись администратора домена.
Пример:
auth_method: ldap
ldap_servers:
- 192.0.2.11
ldap_backups:
- 192.0.2.12
ldap_port: 389
ldap_rootdn: "CN=svc_xmpp,OU=Service Accounts,DC=example,DC=local"
ldap_password: LDAP_BIND_PASSWORD
ldap_base: "OU=Employees,DC=example,DC=local"
ldap_uids:
- sAMAccountName
ldap_filter: "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
Что означает LDAP-конфигурация
Доменная авторизация оказалась для меня самой сложной частью настройки. Чтобы потом не разбирать этот фрагмент заново, я записал назначение каждого параметра.
| Параметр | Для чего нужен |
|---|---|
auth_method: ldap |
ejabberd не хранит отдельные пароли, а проверяет учётные данные через каталог Active Directory. |
ldap_servers |
Основной контроллер домена, к которому ejabberd подключается сразу. |
ldap_backups |
Резервный контроллер домена. Он используется, если основной LDAP-сервер недоступен. |
ldap_port |
Порт подключения к LDAP. В примере используется 389; защиту соединения ejabberd с контроллером домена нужно настраивать отдельно. |
ldap_rootdn |
Полное DN сервисной учётной записи, от имени которой сервер читает каталог. |
ldap_password |
Пароль сервисной учётной записи. В конфиге используется макрос LDAP_BIND_PASSWORD, значение которого контейнер получает из EJABBERD_MACRO_LDAP_BIND_PASSWORD. |
ldap_base |
Подраздел каталога, внутри которого ejabberd ищет сотрудников. Это ограничивает область поиска. |
ldap_uids: sAMAccountName |
Атрибут AD, который становится логином пользователя в чате. |
ldap_filter |
Оставляет обычные пользовательские объекты и исключает отключённые доменные учётные записи. |
В рабочей конфигурации пароль нельзя публиковать в репозитории. Варианты хранения:
- Docker Secret;
- файл с правами 600, доступный только администратору;
- подстановка переменной окружения средствами развёртывания;
- внешнее хранилище секретов.
Пользователь входит как username@chat.example.local. Клиент может автоматически добавлять XMPP-домен, если сотрудник вводит только username.
Какие атрибуты AD пригодятся
Для корпоративного адресного справочника полезны:
sAMAccountName — логин
displayName — отображаемое имя
department — подразделение
title — должность
mail — электронная почта
telephoneNumber — рабочий телефон
thumbnailPhoto — фотография
Автоматический список сотрудников
Чтобы пользователи не добавляли друг друга вручную, можно использовать mod_shared_roster_ldap и группировать сотрудников по атрибуту department:
modules:
mod_shared_roster_ldap:
ldap_base: "OU=Employees,DC=example,DC=local"
ldap_rfilter: "(&(objectClass=user)(department=*))"
ldap_groupattr: "department"
ldap_groupdesc: "department"
ldap_memberattr: "sAMAccountName"
ldap_useruid: "sAMAccountName"
ldap_userdesc: "displayName"
В итоговом файле конфигурации должен быть только один верхнеуровневый блок modules. Настройки mod_shared_roster_ldap я добавляю в общий блок модулей, а не создаю второй modules ниже по файлу.
Перед внедрением нужно проверить заполненность department. Если поле пустое, сотрудник может попасть в условную группу «Без списка» или вообще не появиться в сформированном roster — это зависит от фильтра и клиентской логики.
История, группы и остальные модули
Пример набора модулей:
modules:
mod_adhoc: {}
mod_avatar: {}
mod_blocking: {}
mod_bosh: {}
mod_caps: {}
mod_carboncopy: {}
mod_client_state: {}
mod_disco: {}
mod_fail2ban: {}
mod_http_api: {}
mod_http_upload: {}
mod_last: {}
mod_mam: {}
mod_muc: {}
mod_offline: {}
mod_ping: {}
mod_privacy: {}
mod_private: {}
mod_pubsub: {}
mod_roster: {}
mod_shared_roster_ldap: {}
mod_stream_mgmt: {}
mod_vcard: {}
mod_vcard_xupdate: {}
Не стоит включать все модули без необходимости. Каждый дополнительный интерфейс нужно ограничивать ACL и сетевым экраном.
Сертификат и STARTTLS
Для закрытой сети можно использовать сертификат внутреннего центра сертификации. Самоподписанный сертификат тоже работает, но тогда клиент должен либо доверять этому сертификату, либо проверять заранее заданный SHA-256 fingerprint.
PEM-файл обычно содержит сертификат и приватный ключ:
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Права должны быть минимальными:
chmod 600 server.pem
Проверка STARTTLS с другого компьютера:
openssl s_client -connect 192.0.2.34:5222 -starttls xmpp -xmpphost chat.example.local
Нужно проверить имя сертификата, срок действия, цепочку доверия и SHA-256 fingerprint. Приватный ключ никогда не копируют в статью, журнал или пользовательский дистрибутив.
Сетевой экран сервера
Минимально необходимые порты:
| Порт | Протокол | Назначение |
|---|---|---|
| 5222 | TCP | подключения XMPP-клиентов с STARTTLS |
| 5269 | TCP | XMPP server-to-server, если используется |
| 5280 | TCP | HTTP/Web Admin, желательно только из администраторской сети |
| 5443 | TCP | HTTPS, API, BOSH и HTTP Upload |
Если федерация с другими XMPP-серверами не нужна, 5269 можно не публиковать. Административные порты нельзя без необходимости открывать всей корпоративной сети.
Резервное копирование
Конфигурацию недостаточно просто скопировать: база пользователей и сообщений ejabberd может находиться в Mnesia. Для неё есть штатная команда:
STAMP=$(date +%Y%m%d-%H%M%S)
docker exec ejabberd ejabberdctl backup \
"/home/ejabberd/database/ejabberd-${STAMP}.backup"
Затем копируем файл из контейнера и архивируем конфигурацию:
mkdir -p "/var/backups/ejabberd/${STAMP}"
docker cp \
"ejabberd:/home/ejabberd/database/ejabberd-${STAMP}.backup" \
"/var/backups/ejabberd/${STAMP}/mnesia.backup"
docker cp ejabberd:/home/ejabberd/conf \
"/var/backups/ejabberd/${STAMP}/conf"
cp docker-compose.yml \
"/var/backups/ejabberd/${STAMP}/"
tar -C /var/backups/ejabberd -czf \
"/var/backups/ejabberd/${STAMP}.tar.gz" "${STAMP}"
sha256sum "/var/backups/ejabberd/${STAMP}.tar.gz" \
> "/var/backups/ejabberd/${STAMP}.tar.gz.sha256"
В резервной копии находятся секреты и приватные ключи. Архив должен храниться с ограниченными правами и, желательно, в зашифрованном виде. Копию нужно переносить на отдельный носитель или сервер — архив на том же диске не защищает от отказа диска.
Восстановление
Перед аварийным восстановлением нужно проверить версию ejabberd и сохранить текущее состояние. Общая последовательность:
- Развернуть тот же образ ejabberd.
- Восстановить каталог конфигурации и сертификаты.
- Запустить контейнер и проверить конфигурацию.
- Скопировать Mnesia backup внутрь контейнера.
- Выполнить штатное восстановление:
docker exec ejabberd ejabberdctl restore \
/home/ejabberd/database/mnesia.backup
- Перезапустить контейнер.
- Проверить ejabberdctl status, журналы, LDAP-вход и историю тестового пользователя.
Резервная копия считается рабочей только после тестового восстановления на отдельном стенде.
Как я написал самописный локальный Windows-клиент Volna Chat
Когда сервер уже работал, остался один заметный минус: большинство готовых XMPP-клиентов выглядят как программы начала 2000-х. Поэтому я написал для рабочих мест самописный локальный Windows-клиент Volna Chat.
Зачем понадобился собственный клиент
Когда серверная часть заработала, я начал подбирать клиент для Windows. Большинство XMPP-клиентов будто застряли в нулевых. Единственным действительно годным вариантом оказался Gajim, но и в нём не было привычного вайба Telegram: современного интерфейса, простого обмена файлами, голосовых сообщений и звонков. Поэтому я решил написать свой локальный клиент Volna Chat.
- Вход под учётной записью Active Directory без отдельного пароля мессенджера.
- Обязательное шифрование STARTTLS и возможность закрепить корпоративный сертификат.
- Личные, групповые и недавние чаты; закрепление важных собеседников и выделение непрочитанных.
- Файлы, изображения, снимки из буфера обмена, голосовые сообщения и видеокружки.
- Прямые звонки и голосовые конференции.
- Диагностика сети, аудио и передачи файлов, ориентированная на службу поддержки.

Рисунок 1. Основное окно публикационной сборки; имена сотрудников заменены вымышленными.
Как устроена система
Параметры подключения к XMPP-серверу я задаю в файле appsettings.json, в разделе Volna. Здесь находятся адрес сервера, XMPP-домен, порт, WebSocket-адрес, обязательное TLS-соединение и отпечаток сертификата.
Где находятся настройки подключения
{
"Volna": {
"XmppDomain": "chat.example.local",
"XmppHost": "192.0.2.34",
"XmppPort": 5222,
"WebSocketUri": "wss://chat.example.local:5443/ws",
"RequireTls": true,
"TlsCertificateSha256": "SHA-256-ОТПЕЧАТОК-СЕРТИФИКАТА"
}
}
В конфигурации ejabberd.yml отдельно настраиваются слушатели XMPP, STARTTLS и серверные модули. Само разделение трафика на управляющие сообщения XMPP и прямую передачу файлов или голосового потока не включается отдельной строкой конфигурации: эта логика реализована внутри клиента Volna Chat. Клиент отправляет через ejabberd предложение и служебные данные, после чего два компьютера устанавливают прямое соединение. Поэтому для файлов и звонков важны двусторонняя доступность рабочих станций и разрешение Volna.Chat.exe в сетевых экранах.
Подготовка единой сборки
Для пользователей следует готовить одну эталонную сборку. В неё заранее записываются адрес сервера, XMPP-домен, порт, требование STARTTLS и отпечаток сертификата. Тогда сотрудник вводит только короткий логин, например ivanov, а клиент сам формирует полный JID вида ivanov@chat.example.local.
Что задаётся заранее
- Адрес сервера: DNS-имя или корпоративный IP.
- XMPP-домен: единый домен пользователей.
- Клиентский порт: обычно 5222.
- Автоматическое добавление домена к короткому логину.
- STARTTLS и доверенный отпечаток сертификата.
- Единый каталог установки, например C:\VolnaChat. Тогда в политиках Windows Firewall, Kaspersky Endpoint Security и других средств защиты проще разрешить все необходимые действия именно для Volna.Chat.exe из этого каталога, а не открывать отдельные динамические порты.
Параметры доступны в «Настройки → Подключение». Для обычного пользователя поля можно заполнить до распространения сборки. Раздел «Дополнительно: сеть и брандмауэр» оставляет администратору тест системы, команды для правил и быстрый переход к журналам.
Установка на рабочее место
- Скопировать дистрибутив из доверенного корпоративного источника в локальный каталог. Не запускать приложение постоянно из сетевой папки: обновление или обрыв сети не должны повреждать рабочую копию.
- Запустить установочный BAT от имени администратора. Он копирует файлы в фиксированный каталог и регистрирует интеграцию с Проводником.
- Создать правила Windows Firewall для конкретного исполняемого файла Volna.Chat.exe.
- Добавить тот же EXE в доверенные приложения корпоративного антивируса и разрешить сетевую активность, микрофон и камеру.
- Запустить клиент, проверить вход, тест системы, микрофон, файл и звонок между двумя реальными подсетями.
Интерфейс и работа с контактами
После подключения клиент открывается на вкладке «Личные». Закреплённые контакты располагаются сверху, остальные личные чаты — по времени последнего сообщения. Включение «Списки» показывает корпоративные отделы и пользовательские группы. Вкладки «Группы» и «Все» дают отдельные режимы просмотра.
- До пяти закреплённых контактов сохраняют верхнюю позицию во всех режимах.
- Непрочитанный чат выделяется и показывает индикатор.
- Контекстное меню позволяет закреплять и перемещать контакты в пользовательские списки.
- Ширина карточек подстраивается под контактную область; длинные строки сокращаются, а не раздвигают окно.

Рисунок 2. Личные контакты, поиск, состояние собеседника и панель сообщений. Персональные данные обезличены.
Сообщения и вложения
Чат поддерживает обычный текст, цветные эмодзи, стикеры, хэштеги, копирование сообщения по правой кнопке, вставку изображения из буфера обмена после Print Screen и предварительный просмотр вложения перед отправкой. Изображение можно отправить как изображение или как обычный файл.
Передача через скрепку и отправка из Проводника должны пользоваться одной подсистемой: одинаково нормализовать JID получателя, выбирать сетевой адрес и регистрировать результат. Историческое вложение может быть удалено с диска; в этом случае клиент должен показать «Файл не найден или удалён», а не завершаться аварийно.
На иллюстрациях для публикации я сознательно заменил реальные имена и внутренние идентификаторы вымышленными. Рабочая сборка отображает настоящие сведения из корпоративного каталога.
Главная особенность: отправка из Проводника
Интеграция «Отправить по Волне» сокращает передачу документа до двух действий: щёлкнуть файл правой кнопкой и выбрать получателя из списка пользователей в сети. Окно чата при этом не обязано открываться. Результат показывается системным уведомлением, которое можно отключить в настройках.

Рисунок 3. Отправка файла из контекстного меню Проводника; имена и JID заменены демонстрационными.
Windows 11
Классическое shell-расширение автоматически попадает в меню «Показать дополнительные параметры». Чтобы команда находилась сразу в основном меню Windows 11, нужен современный пакетированный обработчик контекстного меню. В ближайших версиях Volna Chat я обязательно допилю этот обработчик. Пока отправка работает через классическое меню Windows 11.
Куда складываются полученные файлы
Полученные данные сохраняются по отправителям: Загрузки\VolnaChat\Имя пользователя. Такая структура предотвращает смешивание документов от разных сотрудников и упрощает поиск. Путь к конкретному вложению хранится в истории; перенос или удаление файла не должен ломать чат.
Имена папок совпадают с отображаемыми именами отправителей. Для публичной статьи я не показываю реальные каталоги сотрудников.
Голос, видеокружки и конференции
Голосовое сообщение записывается выбранным микрофоном, сохраняется во временный аудиофайл и передаётся как медиасообщение. Для него не показывается уведомление «Файл отправлен»: результат остаётся внутри чата. Видеокружок одновременно использует камеру и микрофон; предпросмотр и готовое сообщение отображаются в круглой маске.
Обычный звонок использует XMPP для приглашения и прямой медиаканал для звука. В окно разговора выведены выбор устройств, шумоподавление, усиление тихого микрофона и добавление участника. При добавлении третьего собеседника создаётся голосовая конференция.

Рисунок 4. Окно звонка: настройки звука и добавление участника для голосовой конференции. Имена обезличены.
Какие порты и разрешения нужны
Если сообщения проходят, но не отправляются файлы или не устанавливается звонок, я на несколько минут отключаю Windows Defender Firewall только на доменном и частном профилях. Такой тест выполняю только в доверенной локальной сети. Публичный профиль не отключаю.
Set-NetFirewallProfile -Profile Domain,Private -Enabled False
Сразу после проверки включаю сетевой экран обратно:
Set-NetFirewallProfile -Profile Domain,Private -Enabled True
Если при отключённом сетевом экране файлы и звонки заработали, добавляю саму программу в разрешённые. Открывать отдельные порты бессмысленно: для прямой передачи файлов и голоса Volna Chat использует динамические соединения.
New-NetFirewallRule -DisplayName "Volna Chat — входящие" `
-Direction Inbound `
-Program "C:\VolnaChat\Volna.Chat.exe" `
-Action Allow `
-Profile Domain,Private
New-NetFirewallRule -DisplayName "Volna Chat — исходящие" `
-Direction Outbound `
-Program "C:\VolnaChat\Volna.Chat.exe" `
-Action Allow `
-Profile Domain,Private
Команды запускаю в PowerShell от имени администратора. Они разрешают сетевую работу только конкретному файлу Volna.Chat.exe из фиксированного каталога и только в доменной или частной сети.
Если клиент вообще не получает звук с микрофона, отдельно проверяю разрешение на микрофон в параметрах конфиденциальности Windows и правила HIPS в Kaspersky Endpoint Security. Windows Firewall влияет на передачу звука по сети, но не выдаёт приложению доступ к самому микрофону.
Kaspersky Endpoint Security
На практике причина сбоя почти всегда находится в одном из двух независимых уровней: либо соединение блокирует родной Windows Defender Firewall, либо его блокирует сетевой экран/HIPS антивируса. Разрешение в Windows не отменяет запрет антивируса, и наоборот. В Kaspersky Security Center я добавляю хэш/путь Volna.Chat.exe в доверенную зону, разрешаю входящий и исходящий TCP/UDP в корпоративной сети и отдельно проверяю HIPS/контроль программ. Именно HIPS может пропускать сеть, но блокировать захват микрофона или камеры. После изменения любой политики я полностью завершаю Volna через трей и запускаю снова.
Диагностика, встроенная в клиент
Нижняя строка состояния показывает не только «В сети», а реальный этап: подключение, STARTTLS, вход, загрузку контактов, ожидание получателя, передачу, сбой маршрута или устройства. При ошибке появляется кнопка «Тест системы». После теста программа открывает папку с журналами и подсказывает, какие файлы посмотреть системному администратору или передать ИИ для разбора.
Расширенное логирование включается галочкой только на время тестирования. В журнал не попадают пароли, LDAP-секреты, приватные ключи и полный медиаконтент. Базовый путь журналов: %LOCALAPPDATA%\VolnaChat\logs.
Папка help и BAT-сценарии
В корне дистрибутива служебные BAT-файлы собраны в отдельной папке help. Рядом лежит текстовая памятка, чтобы администратор мог восстановить работоспособность без поиска старой переписки.
С какими трудностями я столкнулся при разработке клиента
- Несколько сетевых адаптеров: VPN-адрес объявлялся вместо физического Ethernet, и получатель не мог подключиться обратно.
- Правило на один порт не помогало, потому что P2P использует свободный динамический порт.
- Антивирус пропускал XMPP, но блокировал входящий медиаканал или захват микрофона.
- После изменения правил приложение продолжало работать со старым состоянием до полного перезапуска.
- Передача из Проводника работала, а скрепка использовала другой путь формирования адреса получателя; оба сценария пришлось унифицировать.
- Старый файл в истории был удалён локально и попытка открыть его приводила к падению; обработку заменили понятным сообщением.
- На Windows 11 классическое расширение оказалось во вложенном меню.
- Микрофоны поддерживали разные частоты и режимы; потребовался перебор WaveIn/WASAPI и диагностика устройства.
Порядок проверки после установки
- Войти коротким логином и убедиться, что домен добавился автоматически.
- Проверить статус STARTTLS, загрузку списка контактов и обмен обычными сообщениями.
- Отправить небольшой файл через скрепку и тот же файл через Проводник.
- Принять файл на втором ПК и проверить папку отправителя.
- Проверить микрофон, голосовое сообщение и видеокружок.
- Выполнить входящий и исходящий звонок, затем добавить третьего участника.
- Повторить тест между разными VLAN/подсетями и при активных корпоративных средствах защиты.
- При сбое запустить тест системы и сохранить только свежий комплект журналов.
Что получилось в итоге
В итоге у меня получился полноценный чат для локальной сети: с общей адресной книгой, текстовыми и голосовыми сообщениями, звонками, видеокружками, смайлами, стикерпаками и отправкой файлов прямо из контекстного меню Проводника. Единственный минус — настройка сетевых экранов. Открывать отдельные порты для файлов и звонков бесполезно: программа использует динамические соединения. Поэтому я разрешил сетевую работу для Volna.Chat.exe целиком, но ограничил правило доменным и частным профилями Windows и адресами корпоративной сети.
Volna Chat 0.40.42 для Windows
Публичная сборка не содержит рабочих паролей и приватных ключей. Перед запуском нужно указать адрес своего ejabberd-сервера, XMPP-домен и отпечаток сертификата.
ZIP: 169,1 МБ. SHA-256: 6DF37441A597C0378621655D10F60E58C2332F74E704CF2A22931A2DB39D31AD
Тестовый комментарий: проверяю, как работает обсуждение и отображаются ответы на сайте.