ERR_SSL_PROTOCOL_ERROR: що означає і як виправити
ERR_SSL_PROTOCOL_ERROR означає, що саме TLS-рукостискання провалилося ще до того, як браузер узагалі отримав сертифікат для оцінки. Ця відмінність важлива: те, що зламане, лежить нижче за рівень сертифіката - в узгодженні протоколу, порту чи самому з'єднанні, тож заміна сертифіката цього не виправить.
Що означає ERR_SSL_PROTOCOL_ERROR
TLS-з'єднання починається з рукостискання: клієнт надсилає ClientHello зі списком версій протоколу й наборів шифрів, які він підтримує, а сервер має відповісти ServerHello, обравши один із них, а тоді своїм сертифікатом. ERR_SSL_PROTOCOL_ERROR виникає, коли цей обмін зривається ще до того, як дійшло до кроку з сертифікатом, найчастіше тому, що те, що відповіло на порту, взагалі не говорило TLS, або обидві сторони не змогли домовитися, як саме ним говорити. Це найпопулярніший пошуковий запит серед кодів помилок Chrome, і цей обсяг відображає те, скільки різних першопричин зливаються в одне й те саме загальне повідомлення, а не одну спільну проблему.
Як з'являється помилка
Chrome й Edge показують ERR_SSL_PROTOCOL_ERROR без деталей сертифіката, бо жоден сертифікат так і не був представлений, щоб його показати. Firefox зазвичай показує "Secure Connection Failed" із кодом на кшталт SSL_ERROR_RX_MALFORMED_HANDSHAKE чи SSL_ERROR_PROTOCOL_VERSION_ALERT, залежно від того, як саме зірвалося рукостискання.
З командного рядка і curl, і openssl точно визначають збій, що є найшвидшим способом перейти від здогадки до фактів:
curl -v https://example.com/
...
* TLSv1.3 (OUT), TLS handshake, Client hello
* OpenSSL/3.x: error:0A000126:SSL routines::unexpected eof while reading
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL
openssl s_client -connect example.com:443 -servername example.com
...
140... error:1408F10B:SSL routines:ssl3_get_record:wrong version number
"Wrong version number" майже завжди означає, що порт 443 відповів звичайним HTTP, а не TLS, оскільки перші байти HTTP-відповіді виглядають для TLS-парсера, що очікує ServerHello, як сміття. З'єднання, що зависає й завершується тайм-аутом узагалі без помилки, а не провалюється швидко, зазвичай означає, що брандмауер чи проксі мовчки відкидає пакети замість того, щоб сервер активно їх відхиляв.
Що спричиняє ERR_SSL_PROTOCOL_ERROR
- Порт 443 віддає звичайний HTTP чи взагалі не той сервіс. Неправильно налаштований зворотний проксі, служба, що впала й лишила по собі резервний слухач, чи правило NAT, спрямоване не на той бекенд, - усе це дає не-TLS відповідь на TLS-порту.
- Невідповідність версії TLS чи набору шифрів. Сервер, прив'язаний до TLS 1.0 чи 1.1 заради застарілої сумісності, не має спільного протоколу з браузером, що вимагає TLS 1.2 чи вищої версії, тож рукостискання просто провалюється.
- Server Name Indication (SNI) відсутній чи неправильно налаштований. На сервері, що хостить кілька сертифікатів на одній IP-адресі, відсутність збігу за SNI може змусити його показати не той сертифікат чи взагалі відмовити в рукостисканні.
- Експерименти з QUIC і HTTP/3. Chrome іноді спершу пробує QUIC, а тоді відкочується на TLS через TCP; мережа, що неправильно обробляє UDP-трафік QUIC, може проявитися як помилка протоколу вже на резервній спробі.
- Сканування HTTPS антивірусом чи корпоративним проксі. Програмне забезпечення, що перехоплює TLS для перевірки трафіку, починає власне рукостискання замість справжнього, а зламаний сертифікат перехоплення ламає й цю заміну.
- HSTS нав'язує HTTPS хосту, чий TLS зламаний. Щойно браузер закешував політику HSTS для домену, він більше не пробуватиме звичайний HTTP, тож хост, що раніше м'яко відкочувався, тепер жорстко провалюється.
- Старий чи зламаний ланцюжок сертифікатів на старому клієнті. Дуже старі операційні системи й браузери, що з'явилися до новішого кореневого чи проміжного сертифіката, можуть провалювати рукостискання так, що це неможливо відрізнити від невідповідності версії.
- Годинник клієнта суттєво неправильний. Годинник, зсунутий достатньо сильно, може змусити клієнта взагалі відмовитися узгоджувати сесію, а не просто відхилити сертифікат уже потім.
Як зрозуміти, хто винен
Запустіть той самий запит з іншої мережі, наприклад із телефону на мобільному інтернеті замість офісного Wi-Fi. Якщо сайт там завантажується чисто, проблема локальна: корпоративний проксі, перехоплення антивірусом чи captive-портал у першій мережі. Якщо рукостискання провалюється однаково скрізь, де ви пробуєте, причина - конфігурація TLS сервера. SSL-перевірка, запущена з кількох локацій одночасно, відповідає на це за один запит замість позичання другого пристрою, і повідомляє точний протокол і шифр, які сервер узгодив (чи відхилив) з кожної точки спостереження.
Як виправити ERR_SSL_PROTOCOL_ERROR
Якщо ви відвідувач
- Очистіть стан TLS у Chrome на сторінці
chrome://net-internals/#hstsіchrome://restart, чи просто очистіть дані перегляду для "cached images and files" плюс "cookies and site data" для постраждалого сайту, що також очищає закешований стан HSTS і сесії SSL. - Вимкніть експеримент QUIC на
chrome://flags/#enable-quic, встановіть Disabled і перезапустіть браузер. Якщо після цього сайт завантажується, причиною була мережа чи проксі, що погано працюють із QUIC. - Перевірте системну дату й час і налаштуйте автоматичну синхронізацію; годинник, зсунутий достатньо сильно, може зламати саме рукостискання, а не лише перевірку сертифіката, що йде після нього.
- Вимкніть сканування HTTPS у своєму антивірусі (зазвичай у налаштуванні на кшталт "web protection" чи "SSL/TLS scanning") і повторіть спробу. Якщо це допомагає, або оновіть антивірус, або додайте сайт до списку винятків, а не залишайте сканування вимкненим повністю.
- Спробуйте іншу мережу, наприклад мобільний інтернет. Корпоративний проксі чи зламане мережеве обладнання, що впливає лише на одне з'єднання, - поширена причина, яка не має жодного стосунку до самого сайту.
Якщо ви керуєте сайтом
- Підтвердьте, що порт 443 справді TLS, командою openssl вище. "Wrong version number" чи відповідь звичайним текстом означає, що на цьому порту не той сервіс; спершу виправте конфігурацію проксі чи слухача, а вже тоді торкайтеся сертифікатів.
- Явно встановіть підтримувані версії протоколу. На nginx:
Вимкнення TLS 1.0 і 1.1 виправляє рукостискання для сучасних клієнтів, але зламає доступ для дуже старих клієнтів, що досі на них покладаються; свідомо зважте цей компроміс, а не робіть це випадково.ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; - Підтвердьте, що блок сервера справді слухає TLS на очікуваному порту:
listen 443 ssl;(чиlisten 443 ssl http2;) і що директиви сертифіката й ключа вказують на файли, які існують і збігаються один з одним. - Перевірте порядок ланцюжка сертифікатів. Кінцевий сертифікат має йти першим, за ним - проміжні по порядку аж до (але не включно з) кореневого; ланцюжок, наданий не по порядку чи без проміжного сертифіката, спричиняє збій рукостискання на одних клієнтах, тоді як на інших, що кешують відсутній проміжний деінде, усе працює.
- Якщо домен за Cloudflare, перевірте режим SSL/TLS. Режим Flexible завершує TLS на edge-вузлі й говорить із origin-сервером звичайним HTTP, що взагалі провалюється, якщо origin-сервер приймає лише HTTPS; режим Full вимагає будь-якого сертифіката на origin-сервері; Full (strict) вимагає чинного, довіреного сертифіката на origin-сервері й сам спричинить збій рукостискання, якщо сертифікат origin-сервера самопідписаний чи прострочений.
- Перезавантажуйте, а не просто редагуйте, після будь-якої зміни конфігурації:
nginx -t && systemctl reload nginxперевіряє конфігурацію, перш ніж застосувати її.
ERR_SSL_PROTOCOL_ERROR порівняно зі схожими помилками
- ERR_CERT_DATE_INVALID трапляється вже після того, як сертифікат отримано й прочитано; рукостискання дійшло аж туди, а тоді провалило порівняння дати. ERR_SSL_PROTOCOL_ERROR узагалі до цього не доходить.
- ERR_CERT_AUTHORITY_INVALID також трапляється вже після отримання сертифіката; браузер прочитав його й не довіряв тому, хто його підписав. Знову ж таки, помилка протоколу означає, що жоден сертифікат так і не оцінили.
- ERR_SSL_VERSION_OR_CIPHER_MISMATCH - конкретніший родич цієї помилки: вона виникає, коли рукостискання таки просунулося достатньо далеко, щоб порівняти підтримувані версії й шифри, і не знайшло жодного збігу, зазвичай старий сервер, що пропонує лише SSLv3 чи TLS 1.0, проти сучасного браузера, що їх відхиляє. ERR_SSL_PROTOCOL_ERROR - ширша, менш конкретна помилка, що покриває все інше, включно з не-TLS відповіддю на порту, зіпсованими даними рукостискання й програмним перехопленням, що пішло не так.
Як запобігти ERR_SSL_PROTOCOL_ERROR
Збій рукостискання, спричинений зміною конфігурації, оновленням проксі чи перемиканням режиму SSL у Cloudflare, не проявиться у звичайній перевірці статусу HTTP, оскільки з'єднання так і не просувається достатньо далеко, щоб дати результат. Спеціальна SSL-перевірка напряму читає узгоджений протокол і шифр і, виконана з понад 300 контрольних точок у 158 містах, показує, чи рукостискання провалюється всюди, чи лише з однієї мережі - той самий поділ, який цей посібник розбирає вручну. Запустіть перевірку SSL-сертифіката для домену й налаштуйте постійний моніторинг SSL і терміну дії домену, щоб зламане рукостискання сповіщало ще до того, як про нього повідомлять відвідувачі.
Часті запитання
Чи означає ERR_SSL_PROTOCOL_ERROR, що мій сертифікат поганий?
Не обов'язково. Помилка виникає ще до того, як браузер доходить до сертифіката, тож сам сертифікат може бути цілком у порядку, поки саме узгодження TLS усе одно провалюється.
Чому це трапляється лише на одному комп'ютері чи в одній мережі?
Сканування HTTPS антивірусом, корпоративний проксі чи зламаний шлях QUIC саме в тій мережі - зазвичай причина, чому рукостискання провалюється в одному місці й проходить успішно скрізь. Тестування з другої мережі - найшвидший спосіб це підтвердити.
Я щойно переніс свій сайт за Cloudflare, і тепер відвідувачі бачать цю помилку. Що змінилося?
Перевірте режим SSL/TLS у панелі керування. Режим Flexible очікує, що origin-сервер прийматиме звичайний HTTP, і провалюється, якщо той приймає лише HTTPS; Full (strict) очікує чинного, довіреного сертифіката на origin-сервері й провалюється на самопідписаному чи простроченому.
Чи ламає щось вимкнення TLS 1.0 і 1.1 на моєму сервері?
Може, для відвідувачів на дуже старих браузерах, які так і не отримали оновлення до TLS 1.2. Для більшості поточного трафіку це виправляє більше рукостискань, ніж ламає, але спершу перевірте власний склад клієнтів.
Чому curl сказав "wrong version number"?
Це повідомлення означає, що curl надіслав TLS ClientHello й отримав у відповідь байти, що не парсяться як TLS ServerHello, майже завжди тому, що порт віддає звичайний HTTP чи інший не-TLS протокол.