Push-уведомления в Linux не работают: история одного багрепорта
Меня зовут Олеся Лазарева, я — старший разработчик в команде web-редакции Pilot. Программный продукт входит в семейство программного обеспечения для совместной работы над строительными проектами, сборки и проверки BIM-моделей. На сегодняшний день программный продукт существует в двух редакциях: desktop-приложение и web-приложение (web-редакция). Время от времени в рабочем процессе возникают нетривиальные задачи. Эта статья — об одном из таких случаев: расследование проблемы с push-уведомлениями, которая на первый взгляд казалась очевидной, но потребовала последовательной проверки нескольких гипотез.
Несколько месяцев назад первая линия технической поддержки получила от заказчика сообщение о том, что браузерные push-уведомления не работают в web-редакции Pilot. Специалисты воспроизвели проблему, зафиксировали версию продукта и приложили логи, после чего передали задачу в группу разработки.
Браузерные push-уведомления — это всплывающие кликабельные сообщения, которые поступают от веб-приложения или сайта и отображаются среди системных уведомлений на панели оповещений операционной системы. Большинство современных браузеров реализует эту возможность через Web API. Технология существует с 2013 года: она появилась в Safari для OS X, а затем распространилась на Google Chrome и другие браузеры. При разработке соответствующего функционала в web-редакции Pilot предпосылок для возникновения подобных проблем не наблюдалось.
Перед выпуском в бета-версию и релиз функционал проходил ручное и автоматизированное тестирование на нескольких операционных системах. Поскольку релиз предназначался для версии, сертифицированной ФСТЭК, все сценарии тестировались с повышенной тщательностью. Тем не менее проблема проявилась на стороне уже проверенного функционала.
Неработающие push-уведомления — это функциональный сбой, а не визуальный дефект. Если назначение задачи от руководителя не сопровождается уведомлением, пользователь может его не заметить. Ситуация усугублялась тем, что проблема касалась web-редакции продукта, которая уже была передана на сертификацию ФСТЭК России. Выяснить причину неисправности предстояло мне и моему коллеге Василию Волкову.

Версия первая. Возможная ошибка в коде
Прежде всего мы проверили базовый пользовательский сценарий. Я открыла документацию и развернула Pilot-Server в Docker-контейнере в соответствии с инструкцией из справки. После получаса совместной работы контейнер был успешно поднят. Мы запустили Pilot в браузере на хосте, указанном в конфигурации сервера по протоколу HTTP — push-уведомления не приходили. Таким образом, проблема воспроизводилась в точном соответствии с описанием из обращения.
1. Проверка истории коммитов
Проблема подтверждалась на нескольких уровнях: у заказчика, у сотрудников первой линии поддержки и при нашей ручной проверке. Одной из возможных причин могла быть ошибка в коде, незамеченная автотестами на CI/CD. Это означало бы наличие как минимум двух проблем: неработающий функционал и недостаточное тестовое покрытие.
Мы подняли историю коммитов, вошедших в релиз после выпуска сертифицированной версии. Проверка заняла значительное время, однако не дала результата: изменения, внесённые в кодовую базу, не затрагивали модуль уведомлений — правки туда не вносились, пакеты и библиотеки не обновлялись. Первая версия не подтвердилась.
2. Дальнейшая диагностика
После проверки кодовой базы мы перешли к поиску других решений. Поиск в интернете не принёс конкретных результатов, поэтому я обратилась к инструменту на основе нейросети. Он предложил несколько возможных причин и указал на документацию MDN.
Первым шагом рекомендовалось проверить, поддерживает ли браузер регистрацию Service Workers. Для этого нужно открыть DevTools → Console и выполнить диагностический скрипт:
// Проверить поддержку Service Workers
if ('serviceWorker' in navigator) {
console.log('Service Workers поддерживаются');
} else {
console.log('Service Workers НЕ поддерживаются');
}
// Проверить поддержку Push API
if ('PushManager' in window) {
console.log('Push API поддерживается');
Проверить статус Service Workers также можно на вкладке DevTools → Application → Service workers.
Минимальные версии для поддержки SW (Service Workers):
-
Chrome 40+
-
Firefox 44+
-
Edge 17+
Дополнительно стоит убедиться в поддержке уведомлений браузером:

Здесь выяснилась важная деталь: Service Workers функционируют только при использовании протокола HTTPS.
Это позволило сформулировать ключевое наблюдение: на тестовых агентах был настроен протокол HTTPS, и именно в этом окружении функциональность push-уведомлений проверялась перед бета-релизом. При воспроизведении проблемы Pilot-Server в контейнере запускался по протоколу HTTP. Ошибки в коде не было — проблема заключалась в конфигурации окружения.
Версия вторая. Некорректная настройка у пользователя
На этом этапе картина прояснялась: кодовая база работала корректно, разрешения для браузера были включены. Следующим логичным шагом было настроить протокол HTTPS. Для этого требуется выпустить доверенный SSL-сертификат для хоста. Самый доступный способ — создать самоподписанный сертификат через утилиту OpenSSL:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt
После указания путей до приватного и публичного ключей в конфигурации и перезапуска nginx-сервера командой:
docker restart nginx
Гипотеза не подтвердилась — push-уведомления по-прежнему не работали. Самоподписанный сертификат не решил проблему.
Версия третья. Ограничения протокола и контекста безопасности
Выяснилось, что push-уведомления с самоподписанным сертификатом, как и по протоколу HTTP, работают только на localhost. Для работы в полноценном окружении требуется доверенный SSL-сертификат и конфигурация nginx, выпущенный для реального домена.
Окончательную проверку провёл другой наш коллега: он развернул контейнер с Pilot-Server и настроенным nginx на своём домене — push-уведомления в web-редакции на Linux заработали. Функционал корректно работал на любой операционной системе при наличии доверенного HTTPS.
Задача была закрыта со статусом «Work as Designed» («работает как задумано»): пользователям был описан алгоритм настройки HTTPS в nginx-сервере, техподдержка передала инструкцию заказчику.
Выводы:
-
Нарушения в работе браузерных функций не всегда связаны с ошибками в коде. На поведение браузерных API влияют настройки веб-сервера и контекст безопасности: Service Workers и Push API требуют HTTPS — это жёсткое ограничение стандарта W3C Push API.
-
Тестовые окружения должны воспроизводить конфигурацию продуктивной среды. Тестирование на HTTPS при HTTP-развёртывании у пользователей маскирует системные ограничения браузера.
-
Требования к протоколу необходимо явно фиксировать в документации на этапе разработки функциональности. Документация к web-редакции Pilot была дополнена явным указанием на то, что для работы push-уведомлений в браузере обязательно наличие HTTPS.
-
Чтобы упростить настройку для администраторов, в поставку был включён предустановленный nginx-сервер внутри Docker-контейнера Pilot-Web-Server с готовой конфигурацией. Теперь достаточно указать адрес хоста и веб-сокетов в файле nginx.conf.
Почему push-уведомления не работают по HTTP
Основная причина — требования безопасности. Современные веб-стандарты (W3C Push API) ограничивают использование push-уведомлений: они доступны только в защищённом контексте (HTTPS).
Service Workers:
Push-уведомления функционируют через сервис-воркеры — фоновые скрипты браузера. Браузеры (Chrome, Firefox, Safari и другие) разрешают их регистрацию только на защищённых сайтах, чтобы исключить возможность перехвата управления браузером злоумышленниками.
Защита данных:
Уведомления нередко содержат персональные данные или токены доступа. При передаче по HTTP они открыты для перехвата и подмены (атака «человек посередине», Man-in-the-Middle).
Приватность:
Подписка на push-уведомления создаёт уникальный идентификатор устройства. HTTPS гарантирует, что этот идентификатор передаётся только владельцу сайта.
Ссылки:
Автор: ASCONDev

