Jak utworzyć certyfikaty SSL dla serwera, którym przeglądarka będzie ufać
Czego można oczekiwać po pracy administratora? Wielu wyzwań, ślęczenia na tyłku nad różnymi problemami, które – jak pech chciał – jakimś cudem nagle i nieoczekiwanie się pojawiły i – pewnie w podobny sposób, w jaki rozpoczęły swój byt – należy je rozwiązać.
Praca administratora to również ciągła nauka i bezustanne siedzenie z nosem w dokumentacji lub szukanie u wujka Google, czy też w innej ulubionej wyszukiwarce sloganów, aby znaleźć solucję problemu, który akurat nas nurtuje. Niekiedy jest to dochodzenie do rozwiązania, którego nie powstydziłby się Sherlock Holmes. Często wiąże się to też z frustrującymi sytuacjami gdzie siedzimy już naście godzin i nie możemy wpaść na to, gdzie jest diabeł pogrzebany. Takich sytuacji jest bez liku, stąd pomysł na #AdminCases czyli jak nie otwierać drzwi, które już są otwarte – innymi słowy, pokazać gotowe rozwiązania problemów, które zdarzyło się już pokonać.
Nie wiem, czy tylko ja mam takie wrażenie, ale patrząc na wiodące przeglądarki internetowe na rynku i ich ciągłe aktualizacje w kierunku zabezpieczeń obsługa lokalnych aplikacji, dla przykładu na środowiskach developerskich czy testowych zaczyna lekko irytować (pomijając oczywiście słowo lekko lub zastępując je czymś bardziej dosadnym). Ciągłe komunikaty o potencjalnym zagrożeniu i tym podobne, które kiedyś dawało się obejść bezproblemowo, bo wystarczyło zmienić parametr lub też wyłączyć w inny prosty sposób, teraz atakują użytkownika bez ustanku. A dlaczego? Ponieważ przeglądarka stała się mądrzejsza i bardziej uważna od użytkownika – przynajmniej można dojść do takiego wniosku, gdy przez chwilę korzysta się z niej w środowiskach, którym owa przeglądarka nie ufa.
No to teraz przechodzimy do meritum, czyli do problemu, nad którym się pochylimy: jak utworzyć certyfikaty SSL dla serwera, którym przeglądarka będzie ufać.
Serwerów, na których wystawiamy różne aplikacje WWW jest naprawdę dużo i standardem jest połączenie szyfrowane. Jakie są sposoby uzyskania takiego połączenia, które zarazem będzie połączeniem zaufanym. Pierwszym ze sposobów, aby to uczynić, to uzyskanie poświadczenia oficjalnego urzędu certyfikacji. Innymi słowy zgłosić się do takowego, zapłacić i otrzymać to czego potrzebujemy. Można również skorzystać z możliwości, jakie daje nam na przykład letsencrypt.org. Wtedy będzie za darmo, ale takie rozwiązanie ma swoje wady.
Zatem w jaki sposób my to chcemy zrobić? Ano mówiąc kolokwialnie i krótko, można to określić w następujący sposób: Zaufaj mi …UF UF bez udziału oficjalnego CA, czyli wygenerujemy sobie własne CA, którym podpiszemy wygenerowany przez nas certyfikat.
Czyli znamy już całościowo problem, z którym będziemy się zmagać, więc zabierzmy się do pracy. Postaram się opowiedzieć o tym w krótkich, żołnierskich słowach. Na początek wypadałoby posiadać certyfikat własnego CA. Tworzymy to w dwóch krokach:
1. Generujemy klucz prywatny naszego CA:
openssl genpkey -algorithm RSA -out testkey.pem -pkeyopt rsa_keygen_bits:4096
2. Generujemy certyfikat root CA:
openssl req -x509 -new -nodes -key testkey.pem -sha256 -days 365 -out test.pem
Tutaj zostaniemy poproszeni o wypełnienie kilku pól. Zasadniczo można wypełnić je różnymi bzdurami. Dla przykładu:
No i jesteśmy szczęśliwymi posiadaczami certyfikatu CA.
Co dalej? Teraz musimy utworzyć certyfikat dla serwera i go podpisać przy użyciu certyfikatu własnego CA, które przed chwilą wygenerowaliśmy. Krok po kroku wygląda to tak:
- Tworzymy klucz serwera
openssl genrsa -out server.key 2048
- Tworzymy plik z dodatkowymi ustawieniami serwera zawierającymi nazwę i ip adres. Dla przykładu plik będzie się nazywał server.ext. Format pliku jest następujący:
subjectAltName = @alt_names
[alt_names]
DNS.1 = aciekpc
IP.1 = 192.168.0.51
- Generujemy żądanie podpisania certyfikatu
openssl req -new -key server.key -out server.csr
I znowu zostaniemy poproszeni o wypełnienie kilku pól.
- Podpisujemy certyfikat używając swojego CA.
openssl x509 -req -in server.csr -CA test.pem -CAkey testkey.pem -
CAcreateserial -out server.crt -days 365 -sha256 -extfile server.ext
Efektem powinno być wyświetlenie komunikatu o prawidłowej operacji.
Możemy dokonać podpisu bez używania dodatkowych ustawień z pliku podanego w atrybucie -extfile, jednak tak utworzony certyfikat będzie funkcjonował tak jak sobie życzymy, tylko w przeglądarce Firefox.
Udało się stworzyć podpisany certyfikat serwera. No dobra, pocieszyliśmy się, ale starczy już tego dobrego, bo jesteśmy w połowie drogi do osiągnięcia sukcesu. Teraz w pierwszej kolejności należy zaimplementować certyfikat po stronie serwera WWW.
Co należy zrobić na serwerze:
- Wkopiować klucz serwera i podpisany certyfikat
- Zmienić konfigurację serwera ze wskazaniem na wkopiowane pliki.
W przypadku nginx musimy wypełnić dla połączeń SSL ssl_certificate oraz ssl_certificate_key wskazaniami na wkopiowane pliki. Przykładowa konfiguracja może wyglądać:
Teraz wystarczy zrestartować serwer WWW. No gładko idzie, ale jednak przy próbie zalogowania się na stronę naszego serwera WWW mamy nadal komunikat z cyklu „ja Ci nadal nie ufam i nic na to nie poradzę”. Oczywiście to wersja komunikatu mniej oficjalna. Bo ta oficjalna brzmi chociażby: Ostrzeżenie: potencjalne zagrożenie bezpieczeństwa… Dla przykładu:
Znaczy się, że to jednak nie koniec naszej pracy. Jest jeszcze jedna rzecz do zrobienia. Należy zaimportować nasz CA jako Zaufany główny urząd certyfikacji na stacjach, które będą korzystały z tego serwera. Dla tych, którzy nie lubią czytać, a są wzrokowcami kilka obrazków jak to zrobić na różnych systemach operacyjnych i w różnych przeglądarkach, ale chyba większość z nas spokojnie sobie z tym da radę.
I teraz właściwie można ogłosić sukces o ile po zrestartowaniu przeglądarki i wpisaniu naszego URL z SSL otrzymamy obrazek, gdzie kłódeczka nie jest przekreślona, brak komunikatu o niebezpieczeństwie i tym bardziej o braku zaufania.
Jednak czasami nasze przeglądarki internetowe nadal stawiają opór i parafrazując cytat jednego z kultowych polskich filmów mówią: Nie będę Ci ufał i tak będę leżał. Co należy w takim przypadku zrobić – oczywiście będąc pewnym, że wszystkie kroki, które robiliśmy dotychczas uczyniliśmy z bardzo dobrym skutkiem. Trzeba wyczyścić dane przeglądania – historię, cookie, cache. Dobrze jest też zresetować uprawnienia dla tej witryny. Dla przykładu w Chrome robimy to w następujący sposób: kliknąć w kłódkę, wejść w Ustawienia witryn, przejść w Prywatność i bezpieczeństwo i tam mamy menu o nazwie Wyczyść dane przeglądania i zaznaczyć wszystko. Następnie jeszcze raz kliknąć w kłódkę na naszej stronie i Ustawienia witryn i w menu Uprawnienia mamy przycisk Zresetuj uprawnienia. Teraz wystarczy zresetować przeglądarkę. Po powtórnym jej uruchomieniu i wejściu na naszą stronę ta odpowie pełnym zaufaniem.
Prawda, że proste? :) Teraz możemy się cieszyć na serwerach testowych czy developerskich z tego, że nie będzie nas opluwało komunikatami. Oczywiście nie róbcie tego na produkcji.