ERR_SSL_PROTOCOL_ERROR: co oznacza i jak naprawić
ERR_SSL_PROTOCOL_ERROR oznacza, że sam handshake TLS zawiódł, zanim przeglądarka w ogóle otrzymała certyfikat do oceny. To rozróżnienie ma znaczenie: cokolwiek jest nie tak, siedzi poniżej warstwy certyfikatu, w negocjacji protokołu, na porcie albo w samym połączeniu, więc wymiana certyfikatu tego nie naprawi.
Co oznacza ERR_SSL_PROTOCOL_ERROR
Połączenie TLS zaczyna się od handshake'u: klient wysyła ClientHello z listą wersji protokołu i zestawów szyfrów, które obsługuje, a serwer ma odpowiedzieć ServerHello, wybierając jedną z nich, a następnie swoim certyfikatem. ERR_SSL_PROTOCOL_ERROR pojawia się, gdy ta wymiana załamuje się, zanim dojdzie do etapu certyfikatu, najczęściej dlatego, że cokolwiek odpowiedziało na porcie w ogóle nie mówiło TLS, albo obie strony nie mogły uzgodnić, jak się nim posługiwać. To najczęściej wyszukiwany kod błędu w Chrome, a ta liczba odzwierciedla, jak wiele różnych pierwotnych przyczyn zapada się w ten sam ogólny komunikat, zamiast jednej wspólnej awarii.
Jak pojawia się błąd
Chrome i Edge pokazują ERR_SSL_PROTOCOL_ERROR bez żadnych szczegółów certyfikatu, bo żaden certyfikat nigdy nie został zaprezentowany do pokazania. Firefox zwykle pokazuje "Secure Connection Failed" z kodem takim jak SSL_ERROR_RX_MALFORMED_HANDSHAKE albo SSL_ERROR_PROTOCOL_VERSION_ALERT, zależnie od tego, jak załamał się handshake.
Z linii poleceń zarówno curl, jak i openssl precyzyjnie identyfikują awarię, co jest najszybszym sposobem, żeby wyjść poza zgadywanie:
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" niemal zawsze oznacza, że port 443 odpowiedział czystym HTTP, nie TLS, bo pierwsze bajty odpowiedzi HTTP wyglądają jak śmieci dla parsera TLS oczekującego ServerHello. Połączenie, które wisi i przekracza limit czasu bez żadnego błędu, zamiast szybko zawieść, zwykle oznacza, że zapora albo proxy po cichu porzuca pakiety, zamiast serwer aktywnie je odrzucał.
Co powoduje ERR_SSL_PROTOCOL_ERROR
- Port 443 serwuje czysty HTTP albo zupełnie inną usługę. Źle skonfigurowane reverse proxy, zawieszona usługa, która zostawiła po sobie zapasowy listener, albo reguła NAT wskazująca na zły backend, wszystkie produkują odpowiedź bez TLS na porcie TLS.
- Niedopasowanie wersji TLS albo szyfru. Serwer zablokowany na TLS 1.0 albo 1.1 dla zgodności wstecznej nie ma żadnego wspólnego protokołu z przeglądarką wymagającą TLS 1.2 lub wyższego, więc handshake całkowicie zawodzi.
- Server Name Indication (SNI) brakuje albo jest źle skonfigurowane. Na serwerze hostującym kilka certyfikatów na jednym IP, brakujące dopasowanie SNI może sprawić, że zaprezentuje zły certyfikat albo odmówi handshake'u.
- Eksperymenty QUIC i HTTP/3. Chrome czasem próbuje najpierw QUIC, a potem cofa się do TLS przez TCP; sieć, która źle obsługuje ruch UDP QUIC, może wyprodukować błąd protokołu przy próbie fallbacku.
- Skanowanie HTTPS przez antywirus albo firmowe proxy. Oprogramowanie, które przechwytuje TLS, żeby sprawdzić ruch, zaczyna własny handshake w miejsce prawdziwego, a zepsuty certyfikat przechwytywania psuje ten substytut.
- HSTS wymuszające HTTPS na hoście, którego TLS jest zepsute. Gdy przeglądarka już zapisała w pamięci politykę HSTS dla domeny, nie spróbuje czystego HTTP, więc host, który kiedyś elegancko się cofał, teraz od razu twardo zawodzi.
- Stary albo zepsuty łańcuch certyfikatów na starym kliencie. Bardzo stare systemy operacyjne i przeglądarki sprzed nowszego roota albo pośredniego mogą zawieść handshake w sposób nieodróżnialny od niedopasowania wersji.
- Zegar klienta jest mocno błędny. Zegar odstający na tyle daleko może sprawić, że klient w ogóle odmówi negocjacji sesji, nie tylko odrzuci certyfikat po fakcie.
Jak rozpoznać, kto zawinił
Uruchom to samo żądanie z drugiej sieci, na przykład telefon na danych mobilnych zamiast biurowego Wi-Fi. Jeśli witryna ładuje się tam czysto, problem jest lokalny: firmowe proxy, przechwytywanie przez antywirus albo captive portal w pierwszej sieci. Jeśli handshake zawodzi identycznie wszędzie, gdzie próbujesz, przyczyną jest konfiguracja TLS serwera. Kontrola SSL uruchomiona z kilku lokalizacji naraz odpowiada na to w jednym żądaniu zamiast pożyczać drugie urządzenie, i raportuje dokładny protokół i szyfr, jaki serwer wynegocjował (albo odrzucił) z każdego punktu obserwacji.
Jak naprawić ERR_SSL_PROTOCOL_ERROR
Jeśli jesteś odwiedzającym
- Wyczyść stan TLS Chrome pod
chrome://net-internals/#hstsichrome://restart, albo po prostu wyczyść dane przeglądania dla "obrazów i plików w pamięci podręcznej" oraz "plików cookie i danych witryn" dla dotkniętej witryny, co czyści też zapisany stan HSTS i sesji SSL. - Wyłącz eksperyment QUIC pod
chrome://flags/#enable-quic, ustaw na Disabled i uruchom przeglądarkę ponownie. Jeśli witryna potem się ładuje, przyczyną była sieć albo proxy nieprzyjazne QUIC. - Sprawdź datę i godzinę systemową i ustaw automatyczną synchronizację; zegar odstający wystarczająco daleko może całkowicie zepsuć handshake, nie tylko następującą po nim kontrolę certyfikatu.
- Wyłącz skanowanie HTTPS w antywirusie (zwykle pod ustawieniem "ochrona sieci" albo "skanowanie SSL/TLS") i spróbuj ponownie. Jeśli to naprawia problem, zaktualizuj antywirus albo dodaj witrynę do listy wyjątków zamiast zostawiać skanowanie całkiem wyłączone.
- Wypróbuj inną sieć, na przykład dane mobilne. Firmowe proxy albo zepsuty element sprzętu sieciowego, który dotyka tylko jednego połączenia, to częsta przyczyna niemająca nic wspólnego z samą witryną.
Jeśli prowadzisz witrynę
- Potwierdź, że port 443 to faktycznie TLS, powyższym poleceniem openssl. "Wrong version number" albo odpowiedź czystym tekstem oznacza, że na tym porcie jest przypięta zła usługa; napraw konfigurację proxy albo listenera, zanim w ogóle zajmiesz się certyfikatami.
- Ustaw jawnie obsługiwane wersje protokołu. Na nginx:
Porzucenie TLS 1.0 i 1.1 naprawia handshake'i nowoczesnych klientów, ale zepsuje dostęp z bardzo starych klientów wciąż na nich polegających; podejmij tę decyzję świadomie, nie przypadkiem.ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; - Potwierdź, że blok serwera faktycznie nasłuchuje TLS na oczekiwanym porcie:
listen 443 ssl;(albolisten 443 ssl http2;) i że dyrektywy certyfikatu i klucza wskazują na pliki, które istnieją i do siebie pasują. - Sprawdź kolejność łańcucha certyfikatów. Certyfikat liścia musi być pierwszy, a po nim certyfikaty pośrednie w kolejności aż do (ale nie włącznie z) roota; łańcuch serwowany w złej kolejności albo bez pośredniego certyfikatu powoduje awarie handshake'u na niektórych klientach, a na innych, które gdzieś cache'ują brakujący pośredni, działa.
- Jeśli domena stoi za Cloudflare, sprawdź tryb SSL/TLS. Tryb Flexible terminuje TLS na brzegu i mówi czystym HTTP do serwera źródłowego, co całkowicie zawodzi, jeśli serwer źródłowy akceptuje tylko HTTPS; tryb Full wymaga dowolnego certyfikatu na serwerze źródłowym; Full (strict) wymaga ważnego, zaufanego certyfikatu na serwerze źródłowym i sam wyprodukuje awarię handshake'u, jeśli certyfikat serwera źródłowego jest samopodpisany albo wygasły.
- Przeładuj, nie tylko edytuj, po dowolnej zmianie konfiguracji:
nginx -t && systemctl reload nginxwaliduje konfigurację przed jej zastosowaniem.
ERR_SSL_PROTOCOL_ERROR kontra podobnie wyglądające błędy
- ERR_CERT_DATE_INVALID zdarza się po otrzymaniu i odczytaniu certyfikatu; handshake zaszedł tak daleko, a potem zawiódł na porównaniu dat. ERR_SSL_PROTOCOL_ERROR w ogóle tak daleko nie dochodzi.
- ERR_CERT_AUTHORITY_INVALID również zdarza się po otrzymaniu certyfikatu; przeglądarka go odczytała i nie zaufała temu, kto go podpisał. Znowu, błąd protokołu oznacza, że żaden certyfikat nigdy nie został oceniony.
- ERR_SSL_VERSION_OR_CIPHER_MISMATCH to bardziej konkretny odpowiednik tego błędu: pojawia się, gdy handshake faktycznie zaszedł na tyle daleko, żeby porównać obsługiwane wersje i szyfry, i nie znalazł żadnego pokrycia, zwykle stary serwer oferujący tylko SSLv3 albo TLS 1.0 wobec nowoczesnej przeglądarki, która je odrzuca. ERR_SSL_PROTOCOL_ERROR to szersza, mniej konkretna awaria obejmująca wszystko inne, w tym odpowiedź bez TLS na porcie, wadliwe dane handshake'u i oprogramowanie przechwytujące, które poszło źle.
Jak zapobiec ERR_SSL_PROTOCOL_ERROR
Awaria handshake'u wprowadzona przez zmianę konfiguracji, aktualizację proxy albo przełączenie trybu SSL w Cloudflare nie objawi się w zwykłej kontroli statusu HTTP, bo połączenie nigdy nie zachodzi na tyle daleko, żeby ją wyprodukować. Dedykowana kontrola SSL czyta wynegocjowany protokół i szyfr bezpośrednio i, uruchamiana z ponad 300 punktów kontrolnych w 158 miastach, pokazuje, czy handshake zawodzi wszędzie, czy tylko z jednej sieci - dokładnie ten sam podział, który ten poradnik przechodzi ręcznie. Uruchom kontrolę certyfikatu SSL wobec domeny i skonfiguruj ciągłe monitorowanie SSL i wygaśnięcia domeny, żeby zepsuty handshake alarmował, zanim zgłoszą go odwiedzający.
Najczęściej zadawane pytania
Czy ERR_SSL_PROTOCOL_ERROR oznacza, że mój certyfikat jest zły?
Niekoniecznie. Błąd pojawia się, zanim przeglądarka dotrze do certyfikatu, więc sam certyfikat może być całkowicie w porządku, podczas gdy leżąca u podstaw negocjacja TLS wciąż zawodzi.
Dlaczego dzieje się to tylko na jednym komputerze albo w jednej sieci?
Skanowanie HTTPS przez antywirus, firmowe proxy albo zepsuta ścieżka QUIC w tej konkretnej sieci to zwykłe powody, dla których handshake zawodzi w jednym miejscu, a udaje się wszędzie indziej. Testowanie z drugiej sieci to najszybszy sposób, żeby to potwierdzić.
Właśnie przeniosłem witrynę za Cloudflare i teraz odwiedzający widzą ten błąd. Co się zmieniło?
Sprawdź tryb SSL/TLS w panelu. Tryb Flexible oczekuje, że serwer źródłowy zaakceptuje czysty HTTP, i zawodzi, jeśli serwuje tylko HTTPS; Full (strict) oczekuje ważnego, zaufanego certyfikatu serwera źródłowego i zawodzi na samopodpisanym albo wygasłym.
Czy wyłączenie TLS 1.0 i 1.1 na moim serwerze coś zepsuje?
Może, dla odwiedzających na bardzo starych przeglądarkach, które nigdy nie dostały aktualizacji do TLS 1.2. Dla większości aktualnego ruchu naprawia więcej handshake'ów, niż psuje, ale najpierw sprawdź własny miks klientów.
Dlaczego curl powiedział "wrong version number"?
Ten komunikat oznacza, że curl wysłał ClientHello TLS i dostał w odpowiedzi bajty, które nie parsują się jako ServerHello TLS, niemal zawsze dlatego, że port serwuje czysty HTTP albo inny protokół bez TLS.