
Один и тот же красный экран предупреждения покрывает как минимум пять совершенно разных проблем. В этом вся сложность экрана «Подключение не защищено»: пользователь видит одну и ту же страницу независимо от того, истёк ли ваш сертификат вчера ночью, его ноутбук уверен, что сейчас 2019 год, или его работодатель читает его трафик.
Экран прячет единственное, что отличает эти случаи друг от друга, и находится это за ссылкой
«Дополнительно»: код, начинающийся с NET::ERR_CERT_. Всё полезное содержится именно в этом
коде, и почти ни один баг-репорт его не содержит.
Что браузер делает на самом деле
Прежде чем отправить хоть один запрос, браузер проверяет сертификат, который прислал сервер. Три из этих проверок проваливаются достаточно часто, чтобы получить собственные коды ошибок, и собственный список сетевых ошибок Chromium описывает каждую из них одной строкой.
ERR_CERT_COMMON_NAME_INVALID в формулировке Chromium означает следующее: «сервер ответил
сертификатом, чьё общее имя (common name) не совпадает с именем хоста». Сертификат настоящий и
действительный, просто выписан на другое имя. Кто-то обратился к www.example.com, а сертификат
покрывает example.com, голый IP-адрес или тестовый (staging) хост, который так и не добавили в
список имён.
ERR_CERT_DATE_INVALID интереснее прочих, и формулировку стоит прочитать дважды: «сервер
ответил сертификатом, который, по нашим часам, ещё не вступил в силу или уже истёк».
По нашим часам. Браузер сравнивает даты сертификата с часами устройства, на котором он запущен. Абсолютно валидный сертификат провалит эту проверку на устройстве с неверными часами, а неверные часы на устройстве встречаются отнюдь не редко: ноутбук, который месяцами пролежал в ящике стола, телефон, потерявший синхронизацию времени, виртуальная машина, поднятая из снапшота, десктоп, на котором дату выставили вручную. У вас страница открывается, а у них нет, и ошибка ничего не говорит о том, чьи именно часы тут виноваты.
ERR_CERT_AUTHORITY_INVALID означает: «сервер ответил сертификатом, подписанным центром
сертификации, которому мы не доверяем». К этой ошибке приводят три совершенно разные ситуации, и
их стоит различать, чем мы и займёмся ниже.
ERR_CERT_REVOKED означает: «сервер ответил сертификатом, который был отозван». Кто-то
отозвал его до истечения срока действия, обычно из-за утечки закрытого ключа. Этот случай
касается именно вас, и действовать нужно срочно.
Числовые коды тоже не меняются, если вам придётся читать логи, а не экраны: -200, -201, -202 и -206 соответственно.
Три из пяти причин не имеют отношения к вашему серверу
Именно это превращает ошибку сертификата в проблему баг-репортов, а не в эксплуатационную проблему.
Часы. Об этом уже сказано выше. С вашим сертификатом всё в порядке, просто устройство пользователя не согласно с тем, какое сегодня число. Воспроизвести это невозможно, исправить со своей стороны тоже нельзя, и никакой повторный деплой ничего не изменит.
Сеть читает их трафик. Корпоративный прокси, некоторые антивирусы и большинство
captive-порталов публичного Wi-Fi работают так: подсовывают собственный сертификат для каждого
сайта и подписывают его корневым сертификатом, который сами же устанавливают на устройство. Пока
это работает как задумано, пользователь ничего не замечает. Если корневой сертификат не
установлен, или устройство не корпоративное, каждый сайт в этой сети показывает
ERR_CERT_AUTHORITY_INVALID. Верный признак: проблема привязана к сети, а не к сайту. У того же
человека на мобильном интернете всё нормально.
Отсутствующий промежуточный сертификат. Доверие к сертификату строится через цепочку: ваш
сертификат подписан промежуточным, а тот подписан корневым, которому браузер уже доверяет. Ваш
сервер должен отдавать промежуточный сертификат вместе со своим. Если он этого не делает, часть
посетителей всё равно увидит страницу нормально, потому что их браузер уже знает этот
промежуточный сертификат из другого источника или подгружает его на лету, а у других посетителей
появится ERR_CERT_AUTHORITY_INVALID.
Последний случай заслуживает отдельной фразы, потому что это самая неправильно диагностируемая ошибка конфигурации в вебе: цепочка без промежуточного сертификата работает на машине того, кто её настраивал, и отказывает у доли незнакомых пользователей. Это действительно вина вашего сервера, и именно ваш собственный браузер меньше всего годится для того, чтобы это обнаружить.
- Слабо
- Клиент говорит, что сайт небезопасен. Проверили в Chrome и Safari у себя, замочек в порядке. Посоветовали почистить кеш.
- Лучше
- NET::ERR_CERT_AUTHORITY_INVALID, только в их офисном Wi-Fi, на мобильном интернете работает. У нас та же страница открывается без проблем. Прокси или отсутствующий промежуточный сертификат, проверили цепочку снаружи, прежде чем винить их сеть.
Как отличить причины за одну минуту
Код сужает круг до одной из трёх причин. Три вопроса завершают дело.
Который час, по мнению устройства пользователя? Спрашивайте про часы, а не про дату. В
некоторых случаях важны минуты, но здесь типичным случаем оказывается расхождение на целый год, и
оно сразу бросается в глаза. Если часы врут, ERR_CERT_DATE_INVALID полностью объясняется этим и
дальше расследовать нечего. Именно из-за того, что часы устройства могут незаметно разойтись на
месяцы, фраза «сломалось где-то около трёх» способна отправить вас не в тот час логов, так что это
стоит знать не только ради этой одной ошибки.
Руководство по написанию баг-репортов
включает описание окружения в шаблон не просто так.
Проблема привязана к сети или к сайту? Один вопрос: происходит ли то же самое на мобильном интернете? Если проблема с сертификатом исчезает, стоит пользователю выйти из Wi-Fi, значит, свой сертификат подсовывает сеть, и чинить это должны они сами или их IT-отдел.
Возникает ли это у кого-то за пределами вашего офиса? Проверьте цепочку с устройства, которое ни разу не заходило на ваш сайт, именно этим и является внешний SSL-чекер: он подключается заново и показывает, что реально прислал ваш сервер, а не то, что успел доучить ваш собственный браузер. Если он сообщает об отсутствующем промежуточном сертификате, дело в вашем деплое, и, скорее всего, он сломан для части посетителей с момента последнего продления сертификата.
Продление, которое сработало наполовину
Стоит знать этот сценарий отдельно, потому что именно он порождает самую запутанную версию проблемы.
Сегодня сертификаты обычно продлеваются автоматически, и если при продлении установили новый сертификат, но не новый промежуточный, или перезапустили один процесс, а не другой, сервер оказывается корректным с одной точки входа и некорректным с другой. Пользователи за балансировщиком нагрузки попадают то на исправленный узел, то на устаревший, случайным образом. Половина репортов говорит, что всё сломано, половина, что всё в порядке, и обе половины говорят правду, а час уходит на поиск закономерности в пользователях, хотя закономерность на самом деле в серверах.
Выход один: перестать тестировать из браузера, который может незаметно вам подыгрывать. Проверяйте эндпоинт снаружи, и делайте это регулярно.
Session Replay
Бесплатное расширение для Chrome. Один клик на странице, которая ведёт себя не так, как нужно, и вы получаете скриншот, консоль и сетевой лог, а также ссылку, которую можно вставить в тикет.
Что автор репорта реально может вам прислать
Вот честная граница возможностей, и она касается нас точно так же, как и всех остальных. Предупреждение о сертификате означает, что страница вообще не загрузилась. Нет ни консоли, ни сетевого лога, и инструменту захвата нечего записывать, потому что браузер отказал ещё до того, как ваш сайт успел хоть что-то выполнить. Всё, на что вы обычно полагаетесь, чтобы увидеть сбой чужими глазами, для этого случая недоступно.
Так что всё снова сводится к вопросам, и важно спросить именно три нужные вещи:
-
Код целиком, из-за ссылки «Дополнительно».
NET::ERR_CERT_AUTHORITY_INVALID, а не просто «предупреждение о безопасности». - Дата и время на устройстве пользователя, снятые с его собственных часов.
- Сеть, и ведёт ли себя иначе мобильный интернет.
Три ответа, и причина обычно ясна ещё до того, как кто-то заглянул на сервер. Это куда более высокий процент попаданий, чем дают большинство других ошибок, и доступен он только потому, что браузер уже провёл диагностику сам и спрятал её за ссылкой, на которую никто не нажимает.
Одна вещь, которую точно не стоит советовать: нажать «продолжить» и пройти через предупреждение. Это рефлекторное действие, кнопка прямо перед глазами, а при настоящем перехвате трафика это отдаёт его прямо в руки тому, кто его перехватывает. Если причина в часах, их исправление занимает те же тридцать секунд и не ломает проверку для следующего сайта.
Что из этого стоит запомнить
Красный экран является категорией, а не диагнозом. Диагнозом служит код за ссылкой «Дополнительно», и он прилагается бесплатно к каждому случаю.
Три причины из пяти живут на машине пользователя или в его сети, так что воспроизвести их у себя в принципе невозможно. А единственная причина, которая действительно ваша, отсутствующий промежуточный сертификат, это именно то, что ваш собственный браузер покажет вам с наименьшей вероятностью. Обе половины этой картины ведут к одному выводу: при ошибках сертификата сначала спрашивайте код, а уже потом проверяйте всё снаружи, именно в таком порядке.
Собственный список этих ошибок Chromium, с однострочным определением каждой, называется net_error_list.h. Именно из этого файла генерируются страницы ошибок, и он разрешает споры быстрее, чем любая статья.