Przejdź do treści

Serwer Amazon EC2 i SSL od Let’s encrypt w aplikacji Spring Boot

Szyfrowanie ruchu HTTP jest już standardem. Przeglądarki często blokują dużo funkcji, jeśli nasza aplikacja nie używa SSL do komunikacji pomiędzy frontendem, a backendem. Let’s encrypt pozwala na wygenerowanie takiego certyfikatu całkiem za darmo. Jest on co prawda ważny tylko przez 3 miesiące, ale możemy go bez problemu odnowić. W poście przyjrzymy się jak możemy taki certyfikat wygenerować dla naszej aplikacji w Spring Boocie uruchomionej na serwerze EC2 w AWS.

Aktualizacje

  • 23.12.2023 – Amazon Linux 2023 – poprzednio opisana metoda nie działa z nową wersją Amazon Linuxa, zaktualizowany kod, który to naprawia

Domena

Let’s encrypt nie pozwala na generowanie certyfikatów dla domen amazonowych (tych automatycznie przypisywanych do serwera przy utworzeniu go jak np. ec2-54-221-22-192.compute-1.amazonaws.com). Dlatego musimy mieć własną domenę. Możesz ją wykupić na przykład w OVH.pl, nowa domena .pl kosztuje 10zł, a odnowienie około 50zł. Jeśli potrzebujesz domeny do testów, możesz wykupić rozszerzenie .ovh, rejestracja kosztuje około 12zł, a odnowienie 15zł.

Jeśli już mamy naszą domenę musimy ją skonfigurować. Możemy ją dodać do Route 53 w AWS, niestety tam płacimy $0.5 na miesiąc za domenę. Możemy skorzystać z innego dostawcy serwerów DNS. W OVH mamy możliwość korzystania z ich serwerów w cenie domeny i możemy tam konfigurować dowolnie wpisy DNS.

Aby domena wskazywała na nasz serwer, musimy dodać do domeny rekord A wskazujący na IP naszego serwera. Mój serwer ma adres IP 54.221.22.192, adres możesz sprawdzić w panelu AWS. Użyję domeny subdomeny ec2.loza.ovh w domenie loza.ovh. Dodanie wpisu w panelu administracyjnym OVH będzie wyglądać jak poniżej.

Dodawanie rekordu DNS do domeny

Po konfiguracji trzeba odczekać kilka minut i możemy sprawdzić, czy nasz serwer jest widoczny pod domeną. Moja aplikacja już działa na serwerze, więc mogę otworzyć przeglądarkę i sprawdzić co dostanę w odpowiedzi.

Wyjście z aplikacji, na razie strona bez SSL.

Dostaję odpowiedź z serwera. Jak widzisz, pasek adresu pokazuje, że komunikacja z moją stroną jest niezabezpieczona. Zróbmy coś z tym.

Instalowanie potrzebnych pakietów

Przed przystąpieniem do generowania certyfikatu będziemy musieli zainstalować pipa (jeśli jeszcze go nie masz) oraz certbota.

sudo yum install pip
sudo pip install certbot

Jeśli instalacja się zakończy, możemy przejść do generowania certyfikatu dl naszej aplikacji.

Generowanie certyfikatu

Certyfikat generujemy wydając poniższe polecenie. Jako parametr -d podajemy domenę, dla której chcemy wygenerować certyfikat.

sudo certbot certonly --standalone -d ec2.loza.ovh

Certbot musi wystartować serwer na porcie 80, więc musisz się upewnić, że jest on wolny. Po wpisaniu polecenia musimy podać mail. Na podany adres będą przychodzić przypomnienia o przedłużeniu certyfikatu. Do mnie na razie nie przyszedł żaden inny spam. Następnie musimy zaakceptować regulamin (to jest wymagane) i odpowiedzieć na pytanie, czy chcemy przekazać nasze email do fundacji Electronic Frontier Foundation (jest to opcjonalne i nie musimy się zgadzać).

Po przejściu procedury nasze certyfikaty zostały wygenerowane i zapisane w folderze /etc/letsencrypt/live/ec2.loza.ovh/. Teraz musimy je jeszcze przekonwertować do formatu obsługiwanego przez javę.

Konwersja certyfikatu

Aby dostać się do folderu z certyfikatami, musimy być zalogowani jako root. Następnie zmieniamy katalog na katalog z certyfikatami.

$ sudo su
# cd /etc/letsencrypt/live/ec2.loza.ovh

Teraz możemy przejść do konwersji certyfikatu. Musimy wydać polecenie jak poniżej. Jako name możemy ustawić dowolną wartość, potem musimy ją podać w konfiguracji aplikacji. Podczas konwersji będziemy poproszeni o ustawienie hasła do certyfikatu. Możemy je zostawić puste.

# openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name backend -CAfile chain.pem -caname root

Kopiujemy certyfikat do katalogu z aplikacją i zmieniamy właściciela na naszego użytkownika, tak aby miał on dostęp do certyfikatu. Potem możemy już wyjść z powłoki roota.

# cp keystore.p12 /home/ec2-user/
# cd /home/ec2-user/
# chown ec2-user keystore.p12
# exit

Włączanie SSL w aplikacji Spring Boot

Aby włączyć obsługę SSL w aplikacji Spring Boot, musimy podać kilka parametrów w application.yml. Możemy stworzyć ten plik w katalogu z plikiem jar, zostanie on automatycznie połączony z plikiem znajdującym się w aplikacji. Dodajemy następujące parametry:

server:
  ssl:
    key-store: keystore.p12
    key-store-password:
    key-store-type: pkcs12
    key-alias: backend
    key-password:
  port: 8443

Jako key-alias podajemy wartość, którą ustawiliśmy przy konwersji certyfikatu.

Teraz możemy już uruchomić naszą aplikację. Pamiętaj, że musisz mieć otwarty port 8443 w security grupie w AWS. Gdy aplikacja już wystartuje, wpisujemy adres strony w przeglądarce — dla mnie to https://ec2.loza.ovh:8443. Pamiętaj, aby dopisać https://, na tym porcie przeglądarka sama się nie domyśli, że trzeba użyć SSL i otrzymasz błąd. Po przejściu na stronę możesz zobaczyć kłódkę przy pasku adresu mówiącą nam, że połączenie jest szyfrowane.

Kłódka przy adresie witryny mówi nam, że nasze połączenie jest szyfrowane.

Odnowienie certyfikatu

Certyfikaty od Let’s encrypt są ważne przez 3 miesiące. Po tym czasie trzeba je odnowić. Możemy to zrobić, wydając jedno polecenie. Możesz spróbować teraz wykonać dry-run:

sudo certbot-2 renew --dry-run

Do odnowienia też jest potrzebny wolny port 80 wiec, jeśli coś na nim działa, musisz to najpierw wyłączyć.

Podsumowanie

Aktualnie przeglądarki już wymagają szyfrowania połączenia i jeśli nie jest ono szyfrowane, użytkownik może otrzymać ostrzeżenie zamiast naszej strony/aplikacji. Certyfikaty od Let’s encrypt są darmowe, więc warto go dodać, jeśli tworzymy jakąś aplikację. Niestety są one ważne przez 3 miesiące i po tym czasie należy je odnowić. Dostaniemy o tym powiadomienie na maila.

2 komentarze do “Serwer Amazon EC2 i SSL od Let’s encrypt w aplikacji Spring Boot”

  1. Mam taki błąd.

    Could not bind TCP port 80 because it is already in use by another process on
    this system (such as a web server). Please stop the program in question and then
    try again.

    Jak mogę zwolnić ten port, zeby zainstalować ten ssl? po wejściu przez przeglądarkę na domenę jest napis „It Works”. Docelowo na tej domenie chce mieć swój backend certyfikat

    1. Ten błąd oznacza, że masz uruchomiony jakiś serwer, który już słucha na porcie 80. Prawdopodobnie to, co serwuje odpowiedź It Works. Będzie to albo apache, nginx lub Twoja aplikacja w springu? Musisz to zatrzymać na czas generowania certyfikatu. Innym sposobem jest wygenerowanie za pomocą komendy sudo certbot certonly –manual -d domena.pl, wtedy poprosi Cię o stworzenie pliku o odpowiedniej nazwie i zawartości, musisz ten plik udostępnić pod domeną.

      Aby sprawdzić, co słucha na porcie, możesz użyć komendy: netstat -ltp, u mnie pokazuje taki wpis (port http to port 80), słucha na nim nginx:
      tcp 0 0 0.0.0.0:http 0.0.0.0:* LISTEN 1910573/nginx: mast

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

%d