Zalecenia dot. wersji protokołu TLS
11 Feb 2020
best-practices http https nginx ssl tls
Istnieje wiele potencjalnych zagrożeń podczas wdrażania protokołu TLS. Każda konfiguracja wykorzystująca ten protokół powinna spełniać zalecenia poprawnej implementacji i być zgodna ze standardami branżowymi. Wydawać by się mogło, że konfiguracja TLS jest czynnością bardzo prostą, a samo wdrożenie nie powinno być wymagającym procesem. Nic bardziej mylnego.
W tym wpisie chciałbym poruszyć kwestię obsługiwanych wersji TLS, na przykładzie serwera NGINX. Przedstawię także, na co powinniśmy zwracać uwagę oraz dlaczego określenie zalecanych wersji tego protokołu jest tak ważne.
Na wstępie, zapoznaj się z tabelą opisującą pokrótce wszystkie dostępne wersje SSL/TLS:
PROTOCOL | RFC | PUBLISHED | STATUS |
---|---|---|---|
SSL 1.0 | Unpublished | Unpublished | |
SSL 2.0 | 1995 | Depracated in 2011 (RFC 6176) [IETF] | |
SSL 3.0 | 1996 | Depracated in 2015 (RFC 7568) [IETF] | |
TLS 1.0 | RFC 2246 [IETF] | 1999 | Deprecation in 2020 |
TLS 1.1 | RFC 4346 [IETF] | 2006 | Deprecation in 2020 |
TLS 1.2 | RFC 5246 [IETF] | 2008 | Still secure |
TLS 1.3 | RFC 8446 [IETF] | 2018 | Still secure |
TLS w wersji 1.2 i 1.3 #
Zaleca się, aby włączenie wersji TLSv1.2 oraz TLSv1.3 było najwyższym priorytetem dla każdej organizacji. Co więcej, należy całkowicie wyłączyć SSLv2, SSLv3, TLSv1.0 i TLSv1.1, które mają słabości protokołu i używają starszych zestawów szyfrów (nie zapewniają żadnych nowoczesnych trybów szyfrowania), których tak naprawdę nie powinniśmy obecnie używać.
Największą zaletą pełnego przejścia na wersje TLSv1.2 oraz TLSv1.3 jest zapewnienie pełnego wsparcia dla nowoczesnych zestawów szyfrów AEAD. Jednocześnie porzucenie TLSv1.0 a także TLSv1.1 powoduje pozbycie się wielu podatności odkrytych w tych protokołach.
TLSv1.2 jest obecnie najczęściej używaną wersją TLS i wprowadza kilka ulepszeń w zakresie bezpieczeństwa w porównaniu do starszych wersji. Zdecydowana większość witryn obsługuje TLSv1.2, ale wciąż istnieją takie, które tego nie robią (co więcej, wciąż nie wszyscy klienci są kompatybilni z każdą wersją).
Oba wykresy pochodzą z serwisu SSL Pulse firmy Qualys.
Bardzo podobnie przedstawiają się dane, które można wyciągnąć z poziomu Shodana:
To, co rzuca się w oczy to ciągłe wsparcie dla starszych i niezalecanych wersji protokołu TLS oraz ok. 10% (według Shodana) i prawie 30% (według SSL Pulse) obecność protokołu TLSv1.3 w skali całego zmierzonego ruchu.
Protokół TLSv1.3 jest najnowszą i znacznie bezpieczniejszą wersją wprowadzającą wiele poprawek bezpieczeństwa, a także takich, które poprawiają wydajność komunikacji TLS (polecam artykuł TLS 1.3: Everything you need to know). Najważniejszymi założeniami wersji TLSv1.3 było usunięcie wszystkich funkcji, które osłabiały protokół w wersjach wcześniejszych oraz zmniejszenie jego ogólnej złożoności — co w wyniku miało wyeliminować potencjalne wektory ataku. Moim zdaniem, najnowsza wersja powinna być używany tam, gdzie to możliwe i tam, gdzie nie jest wymagana kompatybilność wsteczna.
Szyfry AEAD #
Szyfry AEAD dostarczają specjalne tryby działania szyfru blokowego zwane szyfrowaniem uwierzytelnionym z powiązanymi/dodatkowymi danymi (ang. Authenticated Encryption with Associated Data). Łączą one funkcje trybów gwarantujących poufność i sprawdzanie integralności w jednym algorytmie. Poza tym zapewniają także silne uwierzytelnianie oraz wymianę kluczy z funkcją utajniania z wyprzedzeniem (ang. forward secrecy), a także gwarantują odporność na ponowne użycie wartości początkowej/jednorazowej (aby zachować nieprzewidywalność).
Szyfrowanie z uwierzytelnieniem jest rodzajem szyfrowania symetrycznego, które zwraca tzw. wskaźnik/znacznik uwierzytelniania (będący krótkim ciągiem znaków) zapewniający integralność wiadomości i dostarczający dowód, że otrzymana zaszyfrowana wiadomość jest identyczna jak ta wysłana przez upoważniony do tego podmiot.
Potrzeba ich użycia wynika ze słabości wcześniejszych schematów szyfrowania. Szyfry te są jedynymi obsługiwanymi szyframi w TLSv1.3. Powinniśmy z nich korzystać także w przypadku TLSv1.2, włączając tylko te szyfry wykorzystujące algorytmy AES-GCM i ChaCha20-Poly1305.
Jedynym szyfrem z funkcją uwierzytelniania zgodnym z normą NIST SP 800-38D [NIST, PDF] jest AES-GCM.
Jeżeli chodzi o ten typ szyfrów, to pozwolę sobie zacytować pewną wypowiedź znalezioną na Stack Exchange:
AEAD stands for "Authenticated Encryption with Additional Data" meaning there is a built-in message authentication code for integrity checking both the ciphertext and optionally additional authenticated (but unencrypted) data, and the only AEAD cipher suites in TLS are those using the AES-GCM and ChaCha20-Poly1305 algorithms, and they are indeed only supported in TLS 1.2. This means that if you have any clients trying to connect to this system that don't support either TLS 1.2, or even those that do support TLS 1.2 but not those specific cipher suites (and they're not mandatory... Only TLS_RSA_WITH_AES_128_CBC_SHA is mandatory, and it isn't an AEAD cipher suite) then those clients will not be able to connect at all. - Xander
Polecam także TLS 1.3 (with AEAD) and TLS 1.2 cipher suites demystified: how to pick your ciphers wisely.
Dlaczego powinniśmy wyłączyć starsze wersje SSL/TLS? #
TLSv1.0 i TLSv1.1 nie powinny być używane (patrz Deprecating TLSv1.0 and TLSv1.1 [IETF]) i zostały zastąpione przez TLSv1.2, który sam został zastąpiony przez TLSv1.3 (powinien zostać dołączony do każdej konfiguracji do 1 stycznia 2024 r.). Te wersje TLS są również aktywnie wycofywane zgodnie z wytycznymi agencji rządowych (np. NIST Special Publication (SP) 800-52 Revision 2 [NIST, PDF]) i konsorcjów branżowych, takich jak Payment Card Industry Association (PCI-TLS - Migrating from SSL and Early TLS (Information Suplement) [PDF]).
Moim zdaniem, trzymanie się TLSv1.0 to bardzo zły i dość niebezpieczny pomysł. Ta wersja może być podatna na ataki POODLE, BEAST, a także padding-Oracle. Nadal obowiązuje wiele innych słabości posiadających identyfikatory CVE (niektóre zostały opisane w dokumencie TLS Security 6: Examples of TLS Vulnerabilities and Attacks), których nie można naprawić, chyba że przez wyłączenie TLSv1.0.
Obsługa wersji TLSv1.1 jest tylko złym kompromisem, chociaż ta wersja jest w połowie wolna od problemów TLSv1.0. Z drugiej strony czasami jej stosowanie jest nadal wymagane w praktyce (do obsługi starszych klientów). Istnieje wiele innych zagrożeń bezpieczeństwa spowodowanych wykorzystywaniem TLSv1.0 lub TLSv1.1, dlatego zdecydowanie zalecam aktualizację oprogramowania, usług i urządzeń w celu obsługi min. TLSv1.2.
Także przeglądarki podchodzą do tematu obsługiwanych wersji TLS dosyć restrykcyjnie. Na przykład w marcu 2020 r. Mozilla wyłączy obsługę TLSv1.0 i TLSv1.1 w najnowszych wersjach przeglądarek Firefox. Podobnie Chrome, co zostało opisane w dokumencie Google Chrome 72 deprecates support for TLS 1.0, TLS 1.1.
Usunięcie starszych wersji SSL/TLS jest często jedynym sposobem zapobiegania atakom na obniżenie wersji, które polegają na wymuszeniu przez atakującego korzystanie ze słabszej wersji SSL/TLS. Google zaproponowało rozszerzenie protokołu o nazwie TLS_FALLBACK_SCSV, które ma na celu zapobieganie wymuszonym obniżeniom wersji SSL/TLS (rozszerzenie zostało przyjęte jako RFC 7507 [IETF] w kwietniu 2015 r.).
W tym wypadku sama aktualizacja nie jest wystarczająca. Musisz wyłączyć SSLv2 i SSLv3 - więc jeśli twój serwer nie zezwala na połączenia z tymi wersjami protokołu, atak typu downgrade nie zadziała. Technicznie SCSV jest nadal przydatny przy wyłączonych wersjach SSL (nie TLS), ponieważ pomaga uniknąć obniżenia połączenia do TLS <1.2. Aby przetestować to rozszerzenie, przeczytaj ten świetny artykuł.
Czy TLSv1.2 jest w pełni bezpieczny? #
Jeżeli chodzi o najnowsze wersje TLS, to jedynie TLSv1.3 nie ma problemów z bezpieczeństwem a TLSv1.2 tak naprawdę dopiero po spełnieniu określonych warunków, np. wyłączenie szyfrów CBC. Tylko te wersje zapewniają nowoczesne algorytmy kryptograficzne, dostarczają bezpieczne zestawy szyfrów oraz dodają wiele rozszerzeń poprawiających wydajność i bezpieczeństwo. TLSv1.2 dostarcza zestawy szyfrów, które zmniejszają zależność od szyfrów blokowych, które to zostały wykorzystane przez wymienione wcześniej ataki typu BEAST oraz POODLE.
Co ciekawe, Craig Young, badacz bezpieczeństwa w zespole firmy Tripwire, znalazł luki w TLSv1.2, które pozwalają na ataki podobne do POODLE ze względu na ciągłe wsparcie w protokole TLSv1.2 dla dawno przestarzałych metod kryptograficznych, tj. szyfrów blokowych CBC. Znalezione słabości umożliwiają ataki typu man-in-the-middle na zaszyfrowane sesje użytkownika.
Używanie szyfrów CBC (ang. Cipher Block Chaining) nie stanowi samo w sobie luki, którymi de facto są luki w zabezpieczeniach, takie jak Zombie POODLE, GOLDENDOODLE, 0-Length OpenSSL i Sleeping POODLE. Luki te mają zastosowanie tylko wtedy, gdy serwer używa TLSv1.0, TLSv1.1 lub TLSv1.2 z trybami szyfrowania blokowego
CBC
. Spójrz na Zombie POODLE, GOLDENDOODLE, & How TLSv1.3 Can Save Us All [PDF] z Black Hat Asia 2019. Na TLSv1.0 i TLSv1.1 mogą mieć wpływ luki, takie jak FREAK, POODLE, BEAST i CRIME.
Oprócz tego TLSv1.2 wymaga starannej konfiguracji i przerzuca całą odpowiedzialność jej poprawnej implementacji na administratora, w celu zapewnienia, m.in. że przestarzałe zestawy szyfrów ze zidentyfikowanymi podatnościami nie będą używane. TLSv1.3 eliminuje potrzebę podejmowania tych decyzji i nie wymaga żadnej konkretnej konfiguracji, ponieważ wszystkie szyfry są bezpieczne, a domyślnie OpenSSL włącza tylko tryby GCM i Chacha20/Poly1305 dla TLSv1.3, bez włączania CCM, który zarezerwowany jest dla urządzeń charakteryzujących się słabszą konfiguracją sprzętową.
Czy włączenie TLSv1.3 ma sens? #
TLSv1.3 to nowa wersja TLS, która zapewnia szybszą i bezpieczniejszą komunikację przez kilka następnych lat (poprawia także bezpieczeństwo, prywatność i wydajność TLSv1.2). Co więcej, TLSv1.3 jest dostarczany bez wielu rzeczy (zostały usunięte): renegocjacji, kompresji oraz wielu starych i słabych szyfrów, tj. DSA, RC4 SHA1, MD5 i CBC.
TLSv1.3 rozwiązuje wiele problemów pojawiających się we wcześniejszych wersjach. Jeszcze bardziej przyspiesza komunikację dzięki takim rozszerzeniom, jak TLS False Start (patrz: RFC 7918 [IETF]) czy 0-RTT opisany w artykule Introducing Zero Round Trip Time Resumption (0-RTT).
W przypadku TLSv1.2 potrzebne były dwa przejścia w celu dokończenia uzgadniania TLS. Wersja TLSv1.3 wymaga tylko jednej operacji w obie strony, co z kolei zmniejsza opóźnienie szyfrowania o połowę.
Jak już wspomniałem wyżej, TLSv1.3 eliminuje wiele problemów występujących w starszych wersjach. Usuwa stare i podatne zestawy szyfrów, rozwiązuje wiele krytycznych podatności, tj. OpenSSL Key Recovery Attack on DH small subgroups (CVE-2016-0701) czy atak FREAK.
Jednak moim zdaniem, co najważniejsze, rozwiązuje w pełni największy problem związany z TLSv1.2 — jego odpowiednią konfigurację. Dzięki temu nie naraża aplikacji na wiele wcześniejszych ataków, ponieważ protokół jest w pewnym sensie znacznie prostszy, przez to administratorzy i programiści mają mniejszą możliwość jego błędnej konfiguracji.
Oczywiście, najnowsza wersja protokołu nie ma niezniszczalnego pancerza i nadal może zostać skompromitowana, ponieważ jej bezpieczeństwo oparte jest na założeniu, że wszystkie strony komunikacji, tj. klient, serwer oraz CA będą przestrzegać zasad „dobrego zachowania”. Pojawia się pytanie, skąd mamy pewność, że przynajmniej jedna ze stron nie będzie stosowała się do tych zasad lub jej implementacja nie będzie zawierała słabych punktów?
Niestety wersja TLSv1.3 nie jest jeszcze w pełni wspierana przez wszystkich klientów:
Cloudflare udostępnił świetny artykuł na temat tego, dlaczego TLS 1.3 nie jest jeszcze dostępny we wszystkich przeglądarkach oraz dlaczego cały proces trwa tak długo.
NGINX wspiera TLSv1.3 od wersji 1.13.0 wydanej w kwietniu 2017 r., pod warunkiem, że obsługiwaną wersją biblioteki OpenSSL jest min. 1.1.1 (lub nowszy).
Zalecenia #
Myślę, że najlepszym sposobem na wdrożenie bezpiecznej i zgodnej z zaleceniami konfiguracji jest:
- włączenie TLSv1.2 (jako minimalnej obsługiwanej wersji)
- bez szyfrów CBC
- z jawnym wskazaniem szyfrów AES/GCM i ChaCha20-Poly1305 jako priorytetowych
- włączenie TLSv1.3
- który jest bezpieczniejszy ze względu na poprawę obsługi i wykluczenie wszystkiego, co stało się przestarzałe od czasu pojawienia się TLSv1.2
Zatem odpowiednia konfiguracja oraz uczynienie TLSv1.2 „minimalnym poziomem protokołu” to solidny wybór i najlepsza praktyka w branży (wszystkie standardy branżowe, takie jak PCI-DSS, HIPAA, NIST, zdecydowanie sugerują stosowanie TLSv1.2, rezygnując całkowicie ze starszych wersji). Jeżeli interesuje Cię status konfiguracji TLS u dużych organizacji tj. PayPal, GitHub czy Twitter, zerknij na Who’s quit TLS 1.0?.
Oto przykład zalecanych konfiguracji:
# 1) ssllabs score: 100%
ssl_protocols TLSv1.3 TLSv1.2;
# 2) ssllabs score: 100%
ssl_protocols TLSv1.2;
Należy mieć jednak świadomość, że TLSv1.2 jest prawdopodobnie niewystarczający do obsługi starszego klienta. Wytyczne NIST nie mają zastosowania do wszystkich przypadków użycia i zawsze należy przeanalizować bazę użytkowników (na przykład poprzez dodanie do formatu dziennika logowania wersji TLS i szyfrów) przed podjęciem decyzji, które protokoły mają być obsługiwane, a które nie.
W przypadku TLSv1.3 zastanów się nad użyciem ssl_early_data, aby zezwolić na uzgadnianie TLSv1.3 0-RTT.
Jeżeli masz wątpliwości związane z wyłączeniem starszych wersji TLS, np. jak wspomniałem, wyłączenie TLSv1.1 może uniemożliwić komunikację starszym klientom, zastanów się, jaki jest sens stosowania protokołów niezapewniających odpowiedniego poziomu bezpieczeństwa? Zwłaszcza jeżeli dostępne są znacznie lepsze (pod każdym względem) wersje?
Skoro mamy możliwość skonfigurowania naszych serwerów do obsługi protokołów technicznie przewyższających ich starsze odmiany, i to bardzo niskim kosztem, nie powinniśmy zastanawiać się ani chwili. Myślę, że jest to całkiem sensowny argument, mimo że nie kluczowy.
Oczywiście jest wiele opinii na ten temat. Powinniśmy mieć także świadomość, że ew. podatność nie zawsze jest prosta do wykonania i bardzo często musi zostać spełnionych kilka dodatkowych warunków, aby możliwe było jej wykorzystanie. Nie powinien to być jednak argument za pozostawieniem lub odwlekaniem wyłączenia wątpliwych wersji TLS.
Tymczasowe wykorzystanie TLSv1.1 nie oznacza od razu końca świata — jednak jego wyłączenie powinno być jednym z etapów planowania strategii obsługi TLS przez nasze serwery, w której niewątpliwie powinno znaleźć się także odpowiednie uświadomienie klientów o możliwych konsekwencjach jego pozostawienia.
Dodatkowe zasoby #
- The Transport Layer Security (TLS) Protocol Version 1.2 [IETF]
- The Transport Layer Security (TLS) Protocol Version 1.3 [IETF]
- TLS1.2 - Every byte explained and reproduced
- TLS1.3 - Every byte explained and reproduced
- TLS1.3 - OpenSSLWiki
- TLS v1.2 handshake overview
- An Overview of TLS 1.3 - Faster and More Secure
- A Detailed Look at RFC 8446 (a.k.a. TLS 1.3)
- Differences between TLS 1.2 and TLS 1.3
- TLS 1.3 in a nutshell
- TLS 1.3 is here to stay
- TLS 1.3: Everything you need to know
- TLS 1.3: better for individuals - harder for enterprises
- How to enable TLS 1.3 on Nginx
- How to deploy modern TLS in 2019?
- Deploying TLS 1.3: the great, the good and the bad
- Why TLS 1.3 isn’t in browsers yet
- Downgrade Attack on TLS 1.3 and Vulnerabilities in Major TLS Libraries
- How does TLS 1.3 protect against downgrade attacks?
- Phase two of our TLS 1.0 and 1.1 deprecation plan
- Deprecating TLSv1.0 and TLSv1.1 (IETF) [IETF]
- Deprecating TLS 1.0 and 1.1 - Enhancing Security for Everyone
- End of Life for TLS 1.0/1.1
- Legacy TLS is on the way out: Start deprecating TLSv1.0 and TLSv1.1 now
- TLS/SSL Explained – Examples of a TLS Vulnerability and Attack, Final Part
- A Challenging but Feasible Blockwise-Adaptive Chosen-Plaintext Attack on SSL
- TLS/SSL hardening and compatibility Report 2011 [PDF]
- This POODLE bites: exploiting the SSL 3.0 fallback
- New Tricks For Defeating SSL In Practice [PDF]
- Are You Ready for 30 June 2018? Saying Goodbye to SSL/early TLS
- What Happens After 30 June 2018? New Guidance on Use of SSL/Early TLS
- Mozilla Security Blog - Removing Old Versions of TLS
- Google - Modernizing Transport Security
- These truly are the end times for TLS 1.0, 1.1
- Who’s quit TLS 1.0?
- Recommended Cloudflare SSL configurations for PCI compliance
- Cloudflare SSL cipher, browser, and protocol support
- SSL and TLS Deployment Best Practices
- What level of SSL or TLS is required for HIPAA compliance?
- AEAD Ciphers - shadowsocks
- Building a faster and more secure web with TCP Fast Open, TLS False Start, and TLS 1.3
- SSL Labs Grade Change for TLS 1.0 and TLS 1.1 Protocols
- ImperialViolet - TLS 1.3 and Proxies