72

Бесплатный чат для локальной сети

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

Схема локального чата Volna Chat: ejabberd, Active Directory и XMPP
Схема моего локального чата: ejabberd работает на Linux, проверяет доменные учётные записи в Active Directory, а клиенты подключаются по XMPP с обязательным STARTTLS.

Выбор бесплатного сервера для чата в корпоративной сети

Я посмотрел разные варианты и в итоге остановился на старом добром, проверенном временем протоколе 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

Перед запуском нужно проверить:

  1. Сервер имеет постоянный IP-адрес.
  2. Клиентские компьютеры видят сервер по сети.
  3. Сервер может обращаться к контроллерам домена по TCP 389.
  4. Время синхронизировано через NTP.
  5. Имя 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 и сохранить текущее состояние. Общая последовательность:

  1. Развернуть тот же образ ejabberd.
  2. Восстановить каталог конфигурации и сертификаты.
  3. Запустить контейнер и проверить конфигурацию.
  4. Скопировать Mnesia backup внутрь контейнера.
  5. Выполнить штатное восстановление:
docker exec ejabberd ejabberdctl restore \
  /home/ejabberd/database/mnesia.backup
  1. Перезапустить контейнер.
  2. Проверить ejabberdctl status, журналы, LDAP-вход и историю тестового пользователя.

Резервная копия считается рабочей только после тестового восстановления на отдельном стенде.

Как я написал самописный локальный Windows-клиент Volna Chat

Когда сервер уже работал, остался один заметный минус: большинство готовых XMPP-клиентов выглядят как программы начала 2000-х. Поэтому я написал для рабочих мест самописный локальный Windows-клиент Volna Chat.

Зачем понадобился собственный клиент

Когда серверная часть заработала, я начал подбирать клиент для Windows. Большинство XMPP-клиентов будто застряли в нулевых. Единственным действительно годным вариантом оказался Gajim, но и в нём не было привычного вайба Telegram: современного интерфейса, простого обмена файлами, голосовых сообщений и звонков. Поэтому я решил написать свой локальный клиент Volna Chat.

  • Вход под учётной записью Active Directory без отдельного пароля мессенджера.
  • Обязательное шифрование STARTTLS и возможность закрепить корпоративный сертификат.
  • Личные, групповые и недавние чаты; закрепление важных собеседников и выделение непрочитанных.
  • Файлы, изображения, снимки из буфера обмена, голосовые сообщения и видеокружки.
  • Прямые звонки и голосовые конференции.
  • Диагностика сети, аудио и передачи файлов, ориентированная на службу поддержки.
Скриншот Volna Chat

Рисунок 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 из этого каталога, а не открывать отдельные динамические порты.

Параметры доступны в «Настройки → Подключение». Для обычного пользователя поля можно заполнить до распространения сборки. Раздел «Дополнительно: сеть и брандмауэр» оставляет администратору тест системы, команды для правил и быстрый переход к журналам.

Установка на рабочее место

  1. Скопировать дистрибутив из доверенного корпоративного источника в локальный каталог. Не запускать приложение постоянно из сетевой папки: обновление или обрыв сети не должны повреждать рабочую копию.
  2. Запустить установочный BAT от имени администратора. Он копирует файлы в фиксированный каталог и регистрирует интеграцию с Проводником.
  3. Создать правила Windows Firewall для конкретного исполняемого файла Volna.Chat.exe.
  4. Добавить тот же EXE в доверенные приложения корпоративного антивируса и разрешить сетевую активность, микрофон и камеру.
  5. Запустить клиент, проверить вход, тест системы, микрофон, файл и звонок между двумя реальными подсетями.

Интерфейс и работа с контактами

После подключения клиент открывается на вкладке «Личные». Закреплённые контакты располагаются сверху, остальные личные чаты — по времени последнего сообщения. Включение «Списки» показывает корпоративные отделы и пользовательские группы. Вкладки «Группы» и «Все» дают отдельные режимы просмотра.

  • До пяти закреплённых контактов сохраняют верхнюю позицию во всех режимах.
  • Непрочитанный чат выделяется и показывает индикатор.
  • Контекстное меню позволяет закреплять и перемещать контакты в пользовательские списки.
  • Ширина карточек подстраивается под контактную область; длинные строки сокращаются, а не раздвигают окно.
Скриншот Volna Chat

Рисунок 2. Личные контакты, поиск, состояние собеседника и панель сообщений. Персональные данные обезличены.

Сообщения и вложения

Чат поддерживает обычный текст, цветные эмодзи, стикеры, хэштеги, копирование сообщения по правой кнопке, вставку изображения из буфера обмена после Print Screen и предварительный просмотр вложения перед отправкой. Изображение можно отправить как изображение или как обычный файл.

Передача через скрепку и отправка из Проводника должны пользоваться одной подсистемой: одинаково нормализовать JID получателя, выбирать сетевой адрес и регистрировать результат. Историческое вложение может быть удалено с диска; в этом случае клиент должен показать «Файл не найден или удалён», а не завершаться аварийно.

На иллюстрациях для публикации я сознательно заменил реальные имена и внутренние идентификаторы вымышленными. Рабочая сборка отображает настоящие сведения из корпоративного каталога.

Главная особенность: отправка из Проводника

Интеграция «Отправить по Волне» сокращает передачу документа до двух действий: щёлкнуть файл правой кнопкой и выбрать получателя из списка пользователей в сети. Окно чата при этом не обязано открываться. Результат показывается системным уведомлением, которое можно отключить в настройках.

Скриншот Volna Chat

Рисунок 3. Отправка файла из контекстного меню Проводника; имена и JID заменены демонстрационными.

Windows 11

Классическое shell-расширение автоматически попадает в меню «Показать дополнительные параметры». Чтобы команда находилась сразу в основном меню Windows 11, нужен современный пакетированный обработчик контекстного меню. В ближайших версиях Volna Chat я обязательно допилю этот обработчик. Пока отправка работает через классическое меню Windows 11.

Куда складываются полученные файлы

Полученные данные сохраняются по отправителям: Загрузки\VolnaChat\Имя пользователя. Такая структура предотвращает смешивание документов от разных сотрудников и упрощает поиск. Путь к конкретному вложению хранится в истории; перенос или удаление файла не должен ломать чат.

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

Голос, видеокружки и конференции

Голосовое сообщение записывается выбранным микрофоном, сохраняется во временный аудиофайл и передаётся как медиасообщение. Для него не показывается уведомление «Файл отправлен»: результат остаётся внутри чата. Видеокружок одновременно использует камеру и микрофон; предпросмотр и готовое сообщение отображаются в круглой маске.

Обычный звонок использует XMPP для приглашения и прямой медиаканал для звука. В окно разговора выведены выбор устройств, шумоподавление, усиление тихого микрофона и добавление участника. При добавлении третьего собеседника создаётся голосовая конференция.

Скриншот Volna Chat

Рисунок 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 и диагностика устройства.

Порядок проверки после установки

  1. Войти коротким логином и убедиться, что домен добавился автоматически.
  2. Проверить статус STARTTLS, загрузку списка контактов и обмен обычными сообщениями.
  3. Отправить небольшой файл через скрепку и тот же файл через Проводник.
  4. Принять файл на втором ПК и проверить папку отправителя.
  5. Проверить микрофон, голосовое сообщение и видеокружок.
  6. Выполнить входящий и исходящий звонок, затем добавить третьего участника.
  7. Повторить тест между разными VLAN/подсетями и при активных корпоративных средствах защиты.
  8. При сбое запустить тест системы и сохранить только свежий комплект журналов.

Что получилось в итоге

В итоге у меня получился полноценный чат для локальной сети: с общей адресной книгой, текстовыми и голосовыми сообщениями, звонками, видеокружками, смайлами, стикерпаками и отправкой файлов прямо из контекстного меню Проводника. Единственный минус — настройка сетевых экранов. Открывать отдельные порты для файлов и звонков бесполезно: программа использует динамические соединения. Поэтому я разрешил сетевую работу для Volna.Chat.exe целиком, но ограничил правило доменным и частным профилями Windows и адресами корпоративной сети.

Volna Chat 0.40.42 для Windows

Публичная сборка не содержит рабочих паролей и приватных ключей. Перед запуском нужно указать адрес своего ejabberd-сервера, XMPP-домен и отпечаток сертификата.

Скачать Volna Chat 0.40.42

ZIP: 169,1 МБ. SHA-256: 6DF37441A597C0378621655D10F60E58C2332F74E704CF2A22931A2DB39D31AD

Получилось или остались вопросы?

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

Обсуждение

  1. Тестовый читатель:

    Тестовый комментарий: проверяю, как работает обсуждение и отображаются ответы на сайте.

Напишите комментарий

Опишите проблему и укажите, какое решение вы уже проверили. Адрес электронной почты на сайте не публикуется.