Nikogo nie trzeba przekonywać, że czasy stron internetowych dostępnych tylko przez nieszyfrowany, niezabezpieczony protokół HTTP powoli odchodzą do lamusa. Najnowsze wersje popularnych przeglądarek oznaczają dość jednoznacznie strony internetowe, które nie posiadają wersji szyfrowanej. Tak zwany mixed-content czyli zasoby na stronie dostępne przez różne protokoły (w ramach tej samej witryny) https i http są blokowane lub oznaczane, wyświetlane są ostrzeżenia.

Tym samym producenci popularnych przeglądarek wychodzą niejako naprzeciw bezpieczeństwu surfowania po sieci, albowiem spora część administratorów i stron wciąż jest dostępna tylko nieszyfrowanym protokołem. Jakie zagrożenia się z tym wiążą nie trzeba pewnie większości przedstawiać. Te najbardziej oczywiste to możliwość ataku typu MITM, jak podsłuchiwanie sesji, przechwycenie sesji, a w konsekwencji przejęcie danych wrażliwych jak dane kart płatniczych itd. Możnaby mnożyć, ale nie o tym jest ten artykuł.

Wiemy już, że stronę WWW trzeba odpowiednio dobrze zabezpieczać, ale nie wszyscy wiedzą, że zabezpieczenie zabezpieczeniu nie jest równe i nawet przy szyfrowanym protokole można wykraść dane, jeśli obsługujemy i udostępniamy ruch poprzez słabe wersje protokołów szyfrujących.

W dzisiejszym artykule pokażę Wam, jak zrobić bezpieczne połączenie, a w konsekwencji podnieść bezpieczeństwo stronie internetowej i uzyskać w testerze SSL’a wynik na poziomie przynajmniej A. Skorzystamy przy tym z darmowego certyfikatu Let’s Encrypt i open source’owego serwera WWW Nginx.

Instalacja Nginx’a

apt-get update

apt-get -y upgrade

echo „deb http://nginx.org/packages/debian `lsb_release -cs` nginx” | tee /etc/apt/sources.list.d/nginx.list

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add –

apt-get update

apt-get install –install-recommends –install-suggests -y nginx

Instalacja Let’s Encrypt

cd /tmp

wget https://dl.eff.org/certbot-auto

chmod +x certbot-auto

./certbot-auto –install-only

Odpowiadamy “y” i naciskamy “Enter”.

Kiedy instalacja się zakończy pomyślnie otrzymamy na wyjściu komunikat:

mv certbot-auto /usr/local/bin/

Konfiguracja Nginx’a

Konfigurujemy Vhost’a, wyłączając zbędne protokoły, przestarzałe i podatne na zagrożenia.

Sekcja konfiguracyjna dla portu niezaszyfrowanego – 80.

server {

                listen      80;

                server_name  test.hosterion.pl;

                return 302 https://$server_name$request_uri;

}

W powyższym przykładzie ustawiamy redirect do SSL wszystkiego co nie jest wyświetlane po porcie 443 HTTPS. Dzięki temu, z pewnością cała komunikacja będzie bezpieczna na naszej stronie.

Sekcja konfiguracyjna dla szyfrowanego portu 443 SSL:

server {

                listen      443 ssl;

                server_name  test.hosterion.pl;

                access_log  /var/log/nginx/test.hosterion.pl-ssl_access.log combined;

                error_log /var/log/nginx/test.hosterion.pl-ssl_error.log;

                root /var/www/html;

                index index.php index.html index.htm;

                ssl_protocols TLSv1.2 TLSv1.3;

                ssl_certificate /etc/letsencrypt/live/test.hosterion.pl/fullchain.pem;

                ssl_certificate_key /etc/letsencrypt/live/test.hosterion.pl/privkey.pem;

                ssl_session_timeout  5m;

                ssl_ciphers „ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384”;

                location / {

               try_files $uri $uri/ /index.php?$query_string;

                }

                ssl_prefer_server_ciphers   on;

                ssl_session_cache shared:SSL:10m;

                ssl_session_tickets off;

                ssl_dhparam /etc/ssl/test.hosterion.pl/dhparam.pem;

                ssl_stapling on;

                ssl_stapling_verify on;

                resolver 1.1.1.1 9.9.9.9 8.8.4.4 8.8.8.8 valid=300s;

                resolver_timeout 10s;

                location ~ \.php$ {

               try_files $uri =404;

               fastcgi_pass unix:/run/php/php7.3-fpm.sock;

               fastcgi_split_path_info ^(.+\.php)(/.*)$;

               fastcgi_index index.php;

               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

               include /etc/nginx/fastcgi_params;

               fastcgi_param PATH_INFO $fastcgi_script_name;

               fastcgi_buffer_size 128k;

               fastcgi_buffers 256 4k;

               fastcgi_busy_buffers_size 256k;

               fastcgi_temp_file_write_size 256k;

               fastcgi_send_timeout 600;

               fastcgi_read_timeout 600;

                }

}

Generujemy klucz dla protokołu DH:

cd /etc/ssl

mkdir test.hosterion.pl

openssl dhparam -out dhparam.pem 4096

Czym jest protokół DH i dlaczego warto go używać?

Protokół uzgadniania kluczy szyfrujących Diffiego-Hellmana został opracowany już w 1976 roku. Siłą tego protokołu jest trudność w obliczaniu logarytmów dyskretnych w ciałach skończonych. Taki klucz, który został uzgodniony za pomocą tego konkretnego algorytmu jest wykorzystywany do szyfrowania komunikacji. Algorytm ten pozwala nawet w momencie podsłuchiwania sesji na uzgodnienie kluczy w całkowicie bezpieczny sposób. Nie chroni on jednak w przypadku ataków MITM (man in the middle) i nie nadaje się do szyfrowania wiadomości oraz ich deszyfracji. Sprawdzi się natomiast w naszym przypadku, aby spokojnie uzgadniać klucze między dwoma stronami.

Dodanie tej opcji do naszej konfiguracji Vhost’a w Nginx’ie znacząco podnosi bezpieczeństwo komunikacji z naszym serwerem WWW i jest zdecydowanie zalecane do wdrożenia.

Zostawiamy tylko mocne protokoły SSL:

                ssl_protocols TLSv1.2 TLSv1.3;

Zostawiamy tylko mocne algorytmy:

                ssl_ciphers „EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256

-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA2

56:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4″;

Dodanie wpisu CAA do DNS

Aby jeszcze zwiększyć bezpieczeństwo, konieczne jest dodanie wpisu do serwera DNS naszej domeny dodając do niego rekord CAA. W skrócie rekord CAA określa, kto (która firma) może wystawiać certyfikaty SSL dla naszej domeny. Jeśli ktoś będzie chciał wystawić certyfikat SSL dla naszej domeny w innej firmie, niż wskazana nie powinno być to możliwe. Taka prośba o certyfikat powinna zostać odrzucona przez firmę certyfikującą.

Testowanie strony

Za pomocą darmowej strony dostępnej pod adresem: https://www.ssllabs.com/ssltest możemy sprawdzić na ile silne jest nasze połączenie.

Jak widać uzyskujemy ocenę A, który spokojnie możemy uznać za bardzo dobry.

Obsługujemy tylko silne protokoły co jest zalecanym rozwiązaniem w tej chwili.

Podsumowanie

Czy można zrobić coś więcej? Na pewno można kupić płatny certyfikat z dodatkowymi wpisami, określającymi naszą firmę, dzięki czemu będziemy oznaczeni w pasku przeglądarki podobnie jak banki czy instytucje.

Dodatkowo zyskujemy gwarancję wystawcy (finansową), która określa poziom odpowiedzialności wystawcy za ewentualne złamanie certyfikatu i przejęcie komunikacji (oczywiście, jeśli źródłem wycieku lub błędu nie byliśmy my sami).

Z pewnością w dzisiejszych czasach komunikacja po szyfrowanym protokole SSL jest obowiązkowa i większość nowoczesnych przeglądarek oznacza strony, które nie są szyfrowane i komunikacja z nimi odbywa się po niezabezpieczonym protokole.

W przypadku tak zwanego mixed-content, czyli w sytuacji kiedy część komunikacji jest realizowana protokołem szyfrowanym, a część nie to także przeglądarki wyświetlą błąd. W przyszłości niemal pewnym stanie się, że wszystkie strony (zwłaszcza te, w których odbywa się wymiana danych) mogą być blokowane przez przeglądarki, routery, urządzenia i administratorów, dlatego tym bardziej istotnym jest odpowiednie zabezpieczenie komunikacji.