MySQL przez VPN: zweryfikuj serwer, nie tylko szyfrowanie
Szyfrowanie do niewłaściwego hosta nadal jest błędem. Porównaj wartości ssl-mode, a następnie uruchom połączenie, które nazywa zamierzony serwer i to dowodzi.
Zapisujesz połączenie do 10.20.4.15, VPN spada, a klient nadal się łączy. To nie jest dobra wiadomość. Prywatny adres to miejsce w dowolnym kontekście routingu, w którym się znajdujesz, a wiele sieci używa tych samych zakresów. Klient dotarł do serwera MySQL, tylko być może nie twojego.
Poprawka ma dwie połowy i tylko jedna z nich dotyczy sieci. Utrzymaj połączenie na zamierzonej ścieżce i zmusić klienta do uwierzytelnienia serwera, z którym rozmawia. Pierwsza połowa to miejsce, w którym pomaga VPN; drugą trzeba skonfigurować.
Zaszyfrowane do czego, dokładnie?
TLS chroni rozmowę przed każdym w środku i nie mówi nic o tym, kim punkt końcowy twierdzi, że jest, chyba że klient to sprawdzi. Certyfikat walidowany wobec zaufanego urzędu dowodzi, że certyfikat pochodzi od tego urzędu. Nie dowodzi, że certyfikat wydano na nazwę hosta, do której chciałeś dotrzeć, a to są różne pytania.
To nie teoretyczna luka. Portale captive, błędy z niewłaściwym VRF i nakładające się plany adresowe wszystkie tworzą serwer całkowicie gotowy negocjować z tobą TLS. Jeśli klient wymaga tylko szyfrowania, sesja jest prywatna, ale wskazuje na niewłaściwą bazę danych.
Więc istotne pytanie nie brzmi, czy połączenie jest zaszyfrowane, ale czy jest zaszyfrowane do zamierzonej tożsamości. W kliencie MySQL ta różnica żyje całkowicie w ustawieniu ssl-mode.
Pięć wartości ssl-mode w praktyce
Istnieje pięć wartości i tylko jedna z nich odpowiada na pytanie tego podręcznika. Tabela wymienia, co każda z nich faktycznie gwarantuje, a nie co sugeruje jej nazwa.
| Mode | What it guarantees |
|---|---|
DISABLED | No TLS at all; everything on the wire is readable |
PREFERRED | Tries TLS and falls back to plaintext when the account and server allow it, so it is not a fail-closed requirement |
REQUIRED | Refuses to connect without TLS, and does not validate the certificate |
VERIFY_CA | Validates the server certificate against the configured CA and does not check the hostname |
VERIFY_IDENTITY | Validates the CA and checks that the certificate names the host the client used |
Tylko ostatni wiersz odpowiada na pytanie w tym artykule. PREFERRED zasługuje na osobne wyróżnienie, ponieważ klient, który po cichu przechodzi na zwykły tekst, jest gorszy od tego, który odmawia: wierzysz, że masz szyfrowanie, a przechwycenie pakietów się nie zgadza.
Połączenie, które możesz wykonać dziś
Polecenie poniżej to forma, której należy użyć, z dwoma symbolami zastępczymi: zatwierdzoną nazwą bazy danych i plikiem CA uzyskanym zaufanym kanałem. Żadnego z nich nie należy brać z tego, co serwer oferuje przy pierwszym kontakcie.
mysql --host=db.corp.example --user=app_reader \
--ssl-mode=VERIFY_IDENTITY \
--ssl-ca=/approved/path/ca.pem --password
--password bez wartości pyta o dane wejściowe, co trzyma sekret poza listą procesów i poza historią powłoki. To mały nawyk o dużym zysku na współdzielonych hostach przeskoku, gdzie wiersz poleceń jest widoczny dla innych użytkowników.
Gdy to zawodzi, tekst błędu rozróżnia przypadki lepiej niż intuicja. Błąd CA oznacza, że łańcuch nie waliduje się i należy sprawdzić, który CA podpisał certyfikat serwera. Błąd nazwy hosta oznacza, że łańcuch jest w porządku, a nazwa się nie zgadza, co zwykle oznacza, że połączono się z właściwym serwerem pod niewłaściwą nazwą, a nie z niewłaściwym serwerem.
Pojawienie się monitu nie jest dowodem, że hasło zostało już przesłane, a nieudane połączenie nie dowodzi, że nic nie opuściło klienta. Jeśli rekonstruujesz przeszłe zdarzenie, zidentyfikuj klienta, jego konfigurację, wtyczkę uwierzytelniania i etap, który zawiódł. Szacowanie ekspozycji na podstawie ostatniego komunikatu o błędzie to zgadywanie.
Gdy nazwa pochodzi z tunelu
Przekierowanie lokalnego portu psuje sprawdzanie tożsamości w sposób, który zaskakuje ludzi. Jeśli przekierujesz lokalny port do bazy danych i połączysz się z localhost, klient waliduje certyfikat wobec localhost, a dla tej nazwy nie wydano żadnego certyfikatu. Połączenie może być całkowicie bezpieczne, a weryfikacja i tak zawiedzie, co oznacza, że sprawdzanie działa zgodnie z zamiarem.
Są dwie uczciwe odpowiedzi. Nadaj przekierowanemu punktowi końcowemu nazwę, która rozwiązuje się na adres loopback i pojawia się w certyfikacie serwera, albo używaj nazwy hosta od początku do końca, aby klient zweryfikował prawdziwą tożsamość. Pierwsze jest wygodne dla programistów i wymaga pracy z certyfikatami; drugie jest łatwiejsze do przemyślenia i często właściwym domyślnym ustawieniem automatyzacji. Wyłączenie weryfikacji, aby przekierowanie działało, wyrzuca właściwość, którą próbowałeś dodać.
Akceptacja to trzy warunki
Napisz test akceptacyjny jako trzy osobne stwierdzenia: połączenie użyło zamierzonej trasy, szyfrowanie było wymagane, a nie preferowane, i tożsamość serwera została zweryfikowana wobec zaufanego materiału. Zielona ikona VPN nie ustanawia żadnego z nich.
W przypadku klientów GUI i MariaDB sprawdź dokumentację samego dostawcy, zamiast zakładać, że pisownia flagi się przenosi. Dokumentacja MySQL dotycząca połączeń szyfrowanych obejmuje różnice między trybami i wymóg dystrybucji CA, i to jest odniesienie, które należy sprawdzić przed zmianą produkcyjnego ciągu połączenia.