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-редакции продукта, которая уже была передана на сертификацию ФСТЭК России. Выяснить причину неисправности предстояло мне и моему коллеге Василию Волкову.

Push-уведомления в Linux не работают: история одного багрепорта - 1

Версия первая. Возможная ошибка в коде

Прежде всего мы проверили базовый пользовательский сценарий. Я открыла документацию и развернула 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+

Дополнительно стоит убедиться в поддержке уведомлений браузером:

Push-уведомления в Linux не работают: история одного багрепорта - 2

Здесь выяснилась важная деталь: 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-сервере, техподдержка передала инструкцию заказчику.

Выводы:

  1. Нарушения в работе браузерных функций не всегда связаны с ошибками в коде. На поведение браузерных API влияют настройки веб-сервера и контекст безопасности: Service Workers и Push API требуют HTTPS — это жёсткое ограничение стандарта W3C Push API.

  2. Тестовые окружения должны воспроизводить конфигурацию продуктивной среды. Тестирование на HTTPS при HTTP-развёртывании у пользователей маскирует системные ограничения браузера.

  3. Требования к протоколу необходимо явно фиксировать в документации на этапе разработки функциональности. Документация к web-редакции Pilot была дополнена явным указанием на то, что для работы push-уведомлений в браузере обязательно наличие HTTPS.

  4. Чтобы упростить настройку для администраторов, в поставку был включён предустановленный 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 гарантирует, что этот идентификатор передаётся только владельцу сайта.

Ссылки:

  1. MDN Web Docs — Push API

  2. MDN Web Docs — Service Workers API

  3. MDN Web Docs — Using Service Workers

  4. OpenSSL — официальная документация

  5. OpenSSL — команда req (генерация сертификатов)

Автор: ASCONDev

Источник

Оставить комментарий