TLS (ang. Transport Layer Security) jest rozwinięciem protokołu SSL (ang. Secure Socket Layer), który jest dodatkową warstwą zabezpieczenia bezpieczeństwa dla stron www. Wykorzystuje się dla szyfrowania ruchu sieciowego.
Wykorzystując tą technologię, serwery mogą śmiało wysyłać zapytania i dane pomiędzy serwerem i klientami bez możliwości przechwycenia danych przez osoby trzecie. System certyfikacji także pomaga użytkownikom sprawdzić tożsamości strony internetowej do której on jest podłączony.
W tym poradniku pokażemy Ci, jak utworzyć samopodpisany (self-signed) certyfikat SSL dla wykorzystania z serwerem www Nginx w Ubuntu 16.04.
Uwaga: samopodpisany certyfikat zabezpieczy szyfrowaną komunikację pomiędzy serwerem, a klientem. Jednak, przez to, że on nie został podpisany przez żaden z autoryzowanych centrum certyfikacji, użytkownicy nie mogą zweryfikować tożsamości Twojego serwera.
Taki certyfikat można użyć w przypadku braku powiązanej z serwerem domeny internetowej i kiedy strona niedostępna innym użytkownikom. Jeżeli nie masz domeny – lepiej wykupić podpisany CA certyfikat. Jak skorzystać z darmowego certyfikatu SSL od Lets Encrypt – opisaliśmy tutaj.
Zaczniemy
Przed rozpoczęciem procesu tworzenia certyfikatu musisz posiadać użytkownika z uprawnieniami sudo. Jak utworzyć takiego użytkownika – opisaliśmy w artykule o Wstępnej konfiguracji serwera.
Również pasowałoby mieć zainstalowany serwer WWW Nginx. Jeżeli chcesz zainstalować cały zestaw LEMP (Linux, Nginx, MySQL, PHP) na serwerze VPS możesz użyć tej instrukcji.
W przypadku spełnienia poprzednich warunków możemy rozpocząć.
Tworzenie certyfikatu SSL
Protokół TLS/SSL działa z wykorzystaniem połączonych publicznych i prywatnych kluczy. Klucz SSL jest przechowywany na serwerze w tajemnice. Jest on używany do szyfrowania wysylającej treści do klientów/użytkowników. Certyfikat SSL jest publicznie dostępny i przekazuje się podczas żądania treści. On może być wykorzystany do odszyfrowania przekazanych zapytań, które były podpisane właściwym certyfikatem SSL.
Możemy utworzyć samopodpisany (self-signed) klucz oraz certyfikat przy pomocy OpenSSL jednym poleceniem:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
Zostaniesz poproszony o odpowiedzi na kilku zapytań. Zanim przejdziemy dalej, rzućmy okiem na to, co oznacza to górne polecenie:
- openssl: jest podstawowym narzędziem do tworzenia i zarządzania certyfikatami OpenSSL, kluczami i innymi plikami.
- req: to polecenie wyznacza rodzaj podpisanego certyfikatu, w naszym przypadku X.509. X.509 jest standardem kluczy publicznych .
- -x509: wskazuje dla poprzedniego polecenia to, że certyfikat będzie podpisany własnym podpisem.
- -nodes: ta opcja mówi, że nie będziemy zabezpieczać wygenerowany OpenSSL certyfikat dodatkowym hasłem.
- -days 365: ta opcja określa czas, w ciągu jakiego certyfikat będzie ważnym. Ustawiamy go na 1 rok.
- -newkey rsa:2048: to oznacza, że chcemy utworzyć nowy certyfikat i klucz jednocześnie.
- -keyout: ten wiersz określa OpenSSL, gdzie umieścić nasz generowany klucz prywatny.
- -out: tutaj określamy gdzie umieścić certyfikat, który zostanie stworzony.
Jak już wspomnieliśmy wcześniej to polecenie utworzy i klucz prywatny i certyfikat.
Dalej należy odpowiedzieć na wszystkie zapytania. W polu Common Name (e.g. server FQDN or YOUR name)
należy podać nazwę domeny, związanej z serwerem, albo jego publiczny adres IP.
Country Name (2 letter code) [AU]:PL
State or Province Name (full name) [Some-State]:Rzeszow
Locality Name (eg, city) []:Rzeszow
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Hostovita sp. z o.o.
Organizational Unit Name (eg, section) []:Hostovita
Common Name (e.g. server FQDN or YOUR name) []:adres_ip_serwera
Email Address []:admin@hostovita.pl
Aba utworzone pliki będą umieszczone w podkatalogach w /etc/ssl
.
Następnie za pomocą OpenSSL utwórzmy grupę Diffie-Hellman dla jeszcze większego bezpieczeństwa.
Możemy to zrobić wpisując:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Ten proces może potrwać kilka minut, ale jak on się skończy będziesz miał silną grupę DH w folderze /etc/ssl/certs/dhparam.pem
, którą wykorzystamy w naszej konfiguracji.
Konfiguracja Nginx dla wykorzystania SSL
Stworzyliśmy nasz klucz oraz certyfikat w katalogu /etc/ssl. Teraz musimy zmienić naszą konfigurację Nginx, aby korzystać z tego protokołu.
Dokonamy kilku zmian w konfiguracji:
- Stworzymy fragment konfiguracji z użyciem naszego certyfikatu SSL i lokalizacją naszego klucza.
- Stworzymy fragment konfiguracji, zawierający mocne ustawienia SSL, który może być wykorzystany dla jakiegokolwiek certyfikatu w przyszłości.
- Zmienimy nasze server bloki w Nginx dla obsługi SSL i skorzystamy z dwóch wcześniejszych fragmentów.
Ta metoda konfiguracji Nginx pozwoli nam zachować czytelność pliku konfiguracyjnego i umieścić wspólne ustawienia w moduły wielokrotnego użytku.
Tworzenie fragmentu wskazującego na klucz i certyfikat SSL
Po pierwsze, stwórzmy nowy plik z ustawieniami Nginx w katalogu /etc/nginx/snippets.
Aby poprawnie zlokalizować ten plik, nazwiemy go self-signed.conf
:
sudo nano /etc/nginx/snippets/self-signed.conf
W tym pliku ustawimy folder ssl_certificate z naszym certyfikatem i ssl_certificate_key dla klucza. W naszym przypadku plik będzie wyglądał następująco:
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
Po dodaniu tych linii – zapisz i zamknij plik.
Tworzenie fragmentu z mocną konfiguracją szyfrowania
Następnie tworzymy jeszcze jeden fragment, który pozwoli nam określić niektóre parametry SSL. Pozwoli to nam ustawić Nginx w taki sposób, żeby serwer był bardziej zabezpieczony od ataków.
Parametry, które ustawimy, mogą być wykorzystane również w przyszłych konfiguracjach Nginx i dla tego damy właściwą nazwę plikowi:
sudo nano /etc/nginx/snippets/ssl-params.conf
Dodamy do pliku następną informację z lokalizacją pliku Diffie-Hellman ssl_dhparam
:
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
Zapisz i zamknij plik.
Konfiguracja Nginx dla SSL
Teraz już posiadamy fragmenty kodu za pomocą których możemy zmodyfikować konfigurację Nginx, aby włączyć SSL.
Liczymy, że korzystasz z default server block w pliku konfiguracyjnym w folderze /etc/nginx/sites-available
. Jeżeli używasz innego server bloku, należy zamienić go w następujących poleceniach.
Zanim przejdziemy dalej, zrobimy kopie zapasową naszego pliku konfiguracyjnego:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
Otwórzmy plik z server block:
sudo nano /etc/nginx/sites-available/default
Plik będzie się zaczynał z podobnego do tego kodu:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .
Będziemy wprowadzać zmiany w tej konfiguracji, aby niezaszyfrowane zapytania HTTP automatycznie się przekierowywali na szyfrowany protokół HTTPS. To zapewnia maksymalne bezpieczeństwo dla naszych stron internetowych. Jeśli chcesz zezwolić HTTP i HTTPS, skorzystaj z alternatywnej konfiguracji.
Podzielimy bloki z konfiguracją na dwa bloki. Po pierwszych dwóch listen
dodajmy server_name
, i ustawmy na domenę naszego serwera albo adresu IP. Następnie ustawimy przekierowanie na drugi blok.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name domena_czy_adres_IP;
return 302 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .
Następnie musimy dodać nowy blok Server zawierający resztę konfiguracji. Można odkomentować dwie liste
n dyrektywy, które wykorzystują port 443. Możemy dodać HTTP2 do tych linii, aby włączyć HTTP/2 w tym bloku. Po tym, trzeba tylko włączyć dwa fragmenty plików konfiguracyjny:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .
Zapisz i zamknij plik jak skończysz.
(Konfiguracja alternatywna) włączamy ruch przez HTTP i HTTPS
Jeżeli chcesz lub musisz mieć przekazywanie zaszyfrowanej i niezaszyfrowanej treści, musisz skonfigurować Nginx trochę inaczej. Wcale nie polecamy tego robić, jeżeli można tego uniknąć.
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name domena_czy_adres_IP_serwera;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .
Zapisz i zamknij plik.
Konfiguracja zapory sieciowej
Jeżeli masz włączoną zaporę ufw, jak to było wskazane w poprzednich artykułach, musisz zmienić jej ustawienia, aby włączyć ruch przez SSL. Na szczęście, Nginx rejestruje kilka profili ufw podczas instalacji.
Możemy zobaczyć dostępne profile wpisując:
sudo ufw app list
Dostaniesz podobną listę:
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
Można wyświetlić bieżące ustawienia przy pomocy polecenia:
sudo ufw status
Odpowiedź będzie wyglądała następująco, co oznacza, że tylko ruch poprzez HTTP jest dozwolony:
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
Dodatkowo udostępnimy możliwość ruchu przez HTTPS, więc zostawimy profil “Nginx Full” i usuniemy profil “Nginx HTTP”:
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
Teraz status musi wyglądać następująco:
sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
Włączamy zmiany w Nginx
Teraz jak dokonaliśmy zmian w serwerze www i firewallu, możemy zresetować Nginx dla wprowadzenia naszych zmian.
Po pierwsze, musimy sprawdzić poprawność zmian na błędy syntaktyczne. Możemy zrobić to przy pomocy:
sudo nginx -t
Jeżeli wszystko przeszło pomyślnie, dostaniesz wynik:
nginx: [warn] "ssl_stapling" ignored, issuer certificate not found
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Należy zwrócić uwagę na ostrzeżenie na początku. Jak wspomnialiśmy wcześniej, to ostrzeżenie wyświetla się, ponieważ nasz certyfikat jest samopodpisanym nie może korzystać z protokołu SSL do bindowania danych.
Jeżeli dostałeś taki wynik, jak wyżej – to znaczy że nie masz błędów w nim i możesz ponownie uruchomić Nginx:
sudo systemctl restart nginx
Testowanie szyfrowania
Teraz możemy sprawdzić SSL na naszym serwerze.
Otwórz przeglądarkę i wpisz https:// i następnie domenę czy adres IP serwera:
https://domena_czy_adres_IP
Przez to, zę nasz certyfikat nie został podpisany przez żadną instytucję, otrzymamy takie ostrzeżenie:
Jest to normalnie, teraz musimy przejść do Zaawansowanych (Advanced) i kliknąć w link:
Ustawienie stałego przekierowania
Jeżeli kod działa poprawnie i jesteś pewien w tym, żeby przepuścić cały ruch przez zaszyfrowany protokół musisz zmienić rodzaj przekierowania na stałe.
Otwórz plik konfiguracyjny i znajdź server block
sudo nano /etc/nginx/sites-available/default
Znajdź return 302
i zmień na return 301
:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 301 https://$server_name$request_uri;
}
. . .
Zapisz i zamknij plik.
Sprawdź plik na możliwe błędy:
sudo nginx -t
Uruchom ponownie Nginx dla zmiany przekierowania:
sudo systemctl restart nginx
Wnioski
Skonfigurowałeś serwer www Nginx dla wykorzystania bezpiecznego połączenia HTTPS, co pozwoli bezpiecznie obsługiwać żądania użytkowników strony.