Spring Boot - konfiguracja SSL

0

Witajcie,
Napisałem rozbudowane API RESTowe i chcę skonfigurować je teraz tak, żeby nie powstydzić się mojej pracy pokazać chociażby osobom rekrutującym.
Sprawa wygląda tak, że o ile radzę sobie z programowaniem do administracja systemami to nie jest moja mocna strona - mam już przygotowany plan do jej nauki, ale muszę na szybko skonfigurować działający system.

A zatem:
Mam jeden wirtualny serwer VPS. Podpiąłem do niego domenę.
Na serwerze są 3 aplikacje na JVMie oraz 1 aplikacja angularowa.

:80 - tu stoi Nginx serwujący index.html angularowego builda
:8888 - tu stoi główny serwis i tyle
:8890 ---
:9991 --- na obu pozostałych portach stoją mikroserwisy pomocnicze, które komunikuję się po zwykłym HTTP - porty nie wystawione na zewnątrz, jedynie dostępne dla serwisu z :8888

Teraz tak:
Po wpisaniu <nazwa.domeny.pl> otrzymuję aplikację Angularową, ale Chrome w logach krzyczy INVALID_CERT coś tam coś tam.
Mam skonfigurowanego Tomcata pod SSL, a keystore wygenerowałem tak jak gościu tutaj: https://dzone.com/articles/securing-rest-apis-with-client-certificates

I na ubuntu wszystko działa, ale jest czerwona kłódka.
Na Windowsie także w Chrome jak i systemowo zaimportowałem sobie klucz i nie działa :( Nie może zrobić Handshake'a tak jakby klucz był nieprawidłowy...

Podpowie ktoś jak konfigurować Javowe API pod produkcję? Bo wszędzie widzę tylko certyfikaty self-generated.
To się jakoś kupuje w COMODO czy goDaddy?

Chcę tylko, żeby Chrome się nie dowalał i po prostu łączył się do API, tak żeby ludzie sobie mogli oglądać aplikację.

0

Po wpisaniu <nazwa.domeny.pl> otrzymuję aplikację Angularową, ale Chrome w logach krzyczy INVALID_CERT coś tam coś tam.

Nie cośtam cośtam, tylko przyjrzyj się temu, co mówi, bo dzięki temu może się dowiesz, co konkretnie jest źle :P

Przeglądałeś wygenerowany keystore przez keytool? Powinien Ci wypluć różne informacje dotyczące poszczególnych certyfikatów trzymanych w keystorze. Może się okazać, że np. wygenerowałeś sobie certyfikat, ale certyfikat nie mówi, że uwierzytelnia akurat Twój serwer/klient.

Przy okazji logi z serwera też dobrze by było pokazać + Twoje appliaction.properties i SecurityConfig.

0

Patrząc na ten link o generowaniu certyfikatu SSL, to wygenerowałeś sobie Certification Authority, którego użyłeś do podpisania certyfikatu.
Takie własne CA nie są traktowane jako godne zaufania i Chrome Ci o tym mówi.

Alternatywnie możesz ten swój certyfikat CA zaimportować do chroma i będzie już zaufany. Oczywiście tylko na Twoim Chromie. Inni będą dostawali info, że jest to INVALID CERT.

Jak chcesz mieć certyfikat z prawdziwego zdarzenia to powinien być on podpisany przez CA, które są powszechnie uznawane za "trusted".

Edycja:
Inną sprawa jest właściwe dobranie profilu (zestawu atrybutów do CSR i podpisywania certa), tak by pełnił on rolę "Server Identity", a nie np. "Client Identity".

0

@yarel: jak zamówię taki certyfikat to dostanę plik .p12 do wrzucenia do resources?
Bo widzę, że są u różnych dostawców oferty gdzie trzeba podać domenę... tylko, że to mi nie potrzebne.

1
NeutrinoSpinZero napisał(a):

Bo widzę, że są u różnych dostawców oferty gdzie trzeba podać domenę... tylko, że to mi nie potrzebne.

Jak chcesz mieć certyfikat, to certyfikat musi coś uwierzytelniać. Nie możesz wziąć pierwszego-lepszego certyfikatu i powiedzieć, że od teraz ten certyfikat uwierzytelnia Twojego bloga, bo wtedy każdy mógłby sobie pobrać certyfikaty Facebooka czy Google i używać jak swoich. Inaczej te certyfikaty byłyby do niczego - certyfikat ma uwierzytelniać coś konkretnego, to raczej zrozumiałe, że do tego jest potrzebna domena, dla której ma być wystawiony certyfikat ;)

Jak nie masz i nie chcesz mieć domeny, dla której chciałbyś zamówić certyfikat od zaufanego CA, to zostań przy self-signed :P

0

@superdurszlak: a self-signed działa normalnie jak certyfikat za pieniądze, tyle, że przeglądarka nie rozpoznaje go? Chodzi mi o to czy jest to bezpieczne połączenie.

0

Działa o tyle, że nadaje się do wykorzystania przy SSL/HTTPS, więc do jakichś tam własnych zabaw w development nie ma co strzelać armatą we wróble i zamawiać certyfikaty. Przeglądarka nie tyle nie będzie go rozpoznawać (o ile będzie poprawnie wygenerowany), co będzie się słusznie pluć o to, że taki certyfikat nie jest godny zaufania, bo pochodzi z niepotwierdzonego źródła. Ale jak już będziesz chciał to gdzieś wystawić na świat, trzeba będzie wymienić ten certyfikat na jakiś od CA ;)

1
NeutrinoSpinZero napisał(a):

@yarel: jak zamówię taki certyfikat to dostanę plik .p12 do wrzucenia do resources?
Bo widzę, że są u różnych dostawców oferty gdzie trzeba podać domenę... tylko, że to mi nie potrzebne.

Możesz prezentować ten swój self-signed certyfikat, tylko tak jak pisałem, nie będzie on traktowany jako zaufany przez przeglądarki innych osób.
Obejściem jest akceptacja takiego certyfikatu w drodze wyjątku. Czyli import certyfikatu do grupy certyfikatów zaufanych. Przeglądarka daje wówczas wybór w stylu: "Advanced settings/Confirm security exception" i tam masz możliwość zaakceptowania takiego lewego certyfikatu.

Certyfikat wystawiasz na jakiś podmiot (Subject) i tam przeważnie jest Fully Qualified Domain Name (np. mojserwer.com), dodatkowo certyfikat może posiadać tzw. Subject Alternate Name, np.: dns:www.mojserwer.com,dns:*.appz.mojserwer.com. Dzięki temu certyfikat może być wystawiony na wiele logicznych nazw, a fizycznie odnosić się do 1 serwera.

Jak zamówisz certyfikat (generujesz klucz prywatny, generujesz CSR dla klucza prywatnego i wysyłasz CSR do jednostki podpisującej), to dostaniesz (w jakimś formacie binarnym lub tekstowym): podpisany certyfikat, łańcuch certyfikatów biorących udział w podpisywaniu. Np. jeden plik foo.pem a w nim:

---BEGIN CERT---
<Twój podpisany cert>
---END CERT----
---BEGIN CERT---
<Intermediate CA#1>
---END CERT----
...
---BEGIN CERT---
<Intermediate CA#N>
---END CERT----
---BEGIN CERT---
<Root CA>
---END CERT----

To co logicznie musisz zrobić, to wskazać Twojej aplikacji skąd ma brać klucz publiczny, skąd prywatny i jaki jest łańcuch certyfikatów. W zależności od tego czy aplikacja rozumie .p12 czy nie, mogą być potrzebne konwersje (np. za pomocą openssla) do wspieranego formatu.

Edycja:
@NeutrinoSpinZero: jeśli chodzi o samego springboota, to na https://www.thomasvitale.com/https-spring-boot-ssl-certificate/ wygląda na sensownie opisane.

0

A jest możliwe zrobić certyfikaty certbotem z letsencrypt?
Tzn:
Kupuję domenę: domain.pl
Ona kieruje na Nginxa na port :80
W nginxie robię reverse proxy i z portu :80 kieruję na :8888 czyli na aplikację.
A certyfikat wystawię na domain.pl na free z letsencrypt.

Ma to szansę? Dokupię drugi VPS pod klienta najwyżej.

0
NeutrinoSpinZero napisał(a):

A jest możliwe zrobić certyfikaty certbotem z letsencrypt?
Tzn:
Kupuję domenę: domain.pl
Ona kieruje na Nginxa na port :80
W nginxie robię reverse proxy i z portu :80 kieruję na :8888 czyli na aplikację.
A certyfikat wystawię na domain.pl na free z letsencrypt.

Ma to szansę? Dokupię drugi VPS pod klienta najwyżej.

Nie rozumiem tego opisu.

Samo domain.pl rozwiąże Ci nazwę do IP i tyle, a jaki serwis będzie na porcie 80 i czy będzie wspierał SSLa to inna sprawa.

Jeśli ścieżka komunikacji wygląda tak: Klient <--> nginx <--> backend, to SSLa możesz mieć miedzy Klient-ngingx i nginx-backend.

Jak chcesz zabezpieczyć całą ścieżkę, to idealnie byłoby mieć 2 certy:

  1. Na serwerze (nginx)
  2. Na backendzie (Tomcat)

Dodatkowo między nginx i backendem mógłbyś mieć 2-way-SSL, tj.. nginx przedstawia się certyfikatem klienckim tomcatowi.

Możesz też nginxa i tomcata hostować na tej samej maszynie ale na różnych interfejsach sieciowych i szyfrować ruch tylko między klientem i nginxem.
np. eth0 - ruch internetowy, eth1 - ruch lokalny. Wówczas nginx będzie gadał po eth1 do tomcata, a tomcat nie będzie widoczny z netu.

0

@yarel: dzięki za podpowiedzi. Czyli wygląda na to, że da się to przy odpowiednim wysiłku zrobić na darmowym letsencrypcie. Popróbuję.
Zdecydowałem się dokupienie VPS oddzielnego pod clienta na którym będzie sobie angularowy build hostowany przez Nginxa - tutaj walnę certa dla nginxa przez certbota i będzie git.
Jak taki klient będzie strzelał na https://domain.pl to request będzie przechwycony przez Nginxa (z certyfikatem z certbota), który nasłuchuje na czystym IP (nie wiem jak to nazwać, że IP bez portu) i z tego IP zrobi mi redirect do :8888 gdzie jest apka. I pytanie czy apka może być na HTTP czy trzeba konfigurować HTTPS i czy Nginx nie będzie się pruł coś w stylu: SSL handshake error

0

Nie wiem czy redirect ma sens, skoro ten port 8888 ma być dostępny tylko dla Nginxa (chyba, że dla Ciebie redirect i forwarding to jedno i to samo).
Natomiast możliwa jest konfiguracja: Client --HTTPS --> Nginx --> HTTP --> Tomcat

Dawno w webówce nie siedziałem, ale pamiętam że był jakiś myk z taką konfiguracją, tj. cookies mogą być oznaczone jako Secure, wówczas będą przekazywane tylko po protokole HTTPS , w efekcie przy takiej ścieżce częściowo szyfrowanej, ciasteczka mogą Ci gdzieś po drodze zniknąć. Nie wiem czy to będzie dla Ciebie problemem czy nie.

edycja:
Po skonfigurowaniu serwera możesz zweryfikować swój cert:
openssl s_client -host twoj.server -port 443 -showcerts

Powinno pokazać Twój cert + łancuch certyfikacji (certyfikaty jednostek biorących udział w podpisywaniu).

Jak masz łańcuch certyfikatów CA od jednostki podpisującej CSRa, to możesz zweryfikować poprawność certa używanego przez serwer:
openssl s_client -CAfile lancuch_certyfikatow_ca..pem -connect twoj.server:443
gdzie lancuch_certyfikatow_ca.pem to plik, który otrzymasz od jednostki podpisującej Twój cert.

0

@yarel: dam znać jak skonfiguruję wszystko poprawnie.

1

Chyba trochę komplikujesz, zwłaszcza jak to jest tylko "demo" projekt pod rekrutację :)

  1. Olej SSL w Tomcacie, bo to z tego co widzę działa dość średnio. Jeśli masz wszystko na jednej maszynie, to w ogóle nie ma co się przejmować szyfrowaną komunikacją między serwisami, niech gadają po czystym HTTP na localhoście. Tak długo jak ruch między serwisami nie wychodzi poza localhost, albo VPC na przykładzie Amazona, nie ma problemu.

  2. Zainstaluj sobie Certbot i wygeneruj certyfikat z LE. W trybie --standalone nie trzeba mieć nawet nginx-a, sam sobie poradzi z tą magiczną weryfikacją domen.

  3. Zainstaluj sobie nginx i pogoogluj jak a) zgrać to z LE + dodać redirect http->https, b) serwować statyczne pliki z Angulara, c) użyć reverse proxy do komunikacji z backendem. Najprostszy pattern to serwowanie pod ścieżką "/api" (albo dowolną unikalną) twojego backendu, a pod resztą frontendu. Wtedy mamy 1 domenę i wszystko cacy z zielonymi kłódkami i ciastkami.

PS. Piszesz "porty nie wystawione na zewnątrz" - upewnij się co do tego, bo o ile nie konfigurowałeś firewalla, to te porty są wystawione na zewnątrz domyślnie w SB.

0

Kurde, bawiłem się w jakieś Tomcaty i keystory, a to wszystko takie proste. Dodałem do domeny wpisy AAAA i po prostu certbot załatwił za mnie resztę.
Żeby nginx przekierował HTTPS na tomcata wystarczyło dodać
location / {
...
proxy_pass http://127.0.0.1:8888;
...
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1