Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy moje połączenia z serwerem MySQL są szyfrowane i bezpieczne?

Jednym z najważniejszych czynników i podstaw zarządzania danymi jest bezpieczeństwo. Dobrą praktyką jest zaimplementowanie zabezpieczeń bazy danych, gdy zarządzanie danymi jest zaangażowane w działalność korporacyjną lub masową.

Bezpieczeństwo danych jest jednym z najważniejszych aspektów administrowania bazą danych. Odgrywa kluczową rolę, którą powinno wdrożyć każde zarządzanie bazami danych. Poprawnie zaimplementowane i wykonane w rezultacie poprawi nie tylko bezpieczeństwo danych, ale także wpłynie na stabilność systemu, wydłuży cykl rozwoju, poprawi zgodność danych i zwiększy świadomość bezpieczeństwa aż do poziomu zespołu. Każdy nie chce, aby jego dane trafiły w niepowołane ręce. Jeśli dane zostaną naruszone, nie tylko zagraża to poufności i integralności danych, ale także naraża Twoją organizację na poważne ryzyko finansowe. Nawet w przypadku prostej implementacji zarządzania bazą danych, jeśli dowiesz się, że ktoś już włamał się do Twojego systemu, poczucie niepewności i strachu przed konsekwencjami jest całkowicie niewygodne.

Stwierdzenie, czy połączenie z serwerem MySQL jest bezpieczne, zależy od tego, jak bezpiecznie MySQL przesyła przesyłane dane. Dzięki nieszyfrowanemu połączeniu między klientem MySQL a serwerem osoba mająca dostęp do sieci może obserwować cały ruch i sprawdzać dane wysyłane lub odbierane między klientem a serwerem.

Gdy musisz przenieść informacje przez sieć w bezpieczny sposób, połączenie nieszyfrowane jest niedopuszczalne. Aby uniemożliwić odczyt jakichkolwiek danych, użyj szyfrowania. Algorytmy szyfrowania muszą zawierać elementy bezpieczeństwa, aby oprzeć się wielu rodzajom znanych ataków, takich jak zmiana kolejności zaszyfrowanych wiadomości lub dwukrotne odtwarzanie danych.

Ale mój MySQL jest bezpieczny, prawda?

Wiara, że ​​Twój MySQL jest bezpieczny bez sprawdzania jego stabilności i podatności na zagrożenia, jest jak religia. Masz tendencję do wierzyć, nawet nie widząc tego, nawet nie dotykając tego. Problem w tym, że MySQL jest technologią, a jej istnienie nie opiera się na abstrakcyjnych myślach. Musi być przetestowany, musi być sprawdzony, wymaga bezpieczeństwa i przestrzegania najlepszych praktyk, które zostały przetestowane również przez innych.

Określanie, czy połączenia z serwerem MySQL, np. w drodze, są bezpieczne lub czy są zaszyfrowane, zależy od tego „jak skonfigurowałeś swoją bazę danych?” lub „kto skonfigurował Twoją bazę danych?”.

MySQL obsługuje szyfrowane połączenia między klientami a serwerem przy użyciu protokołu TLS (Transport Layer Security). TLS jest czasami określany jako SSL (Secure Sockets Layer), ale MySQL w rzeczywistości nie używa protokołu SSL do połączeń szyfrowanych, ponieważ jego szyfrowanie jest słabe, a SSL został już przestarzały na rzecz TLS. TLS wykorzystuje algorytmy szyfrowania, aby zapewnić, że dane otrzymane przez sieć publiczną można ufać. Posiada mechanizmy wykrywania zmiany, utraty lub odtwarzania danych. TLS zawiera również algorytmy, które zapewniają weryfikację tożsamości przy użyciu standardu X.509. SSL lub TLS są używane zamiennie, ale w kontekście szyfrowania za pomocą MySQL używany jest TLS, dla którego MySQL obsługuje szyfrowane połączenia przy użyciu protokołów TLSv1, TLSv1.1, TLSv1.2 i TLSv1.3.

X.509 umożliwia identyfikację kogoś w Internecie. Zasadniczo powinien istnieć podmiot zwany „Urzędem certyfikacji” (lub CA), który przypisuje certyfikaty elektroniczne każdemu, kto ich potrzebuje. Certyfikaty opierają się na algorytmach szyfrowania asymetrycznego, które mają dwa klucze szyfrowania (klucz publiczny i klucz tajny). Właściciel certyfikatu może przedstawić certyfikat innej stronie jako dowód tożsamości. Certyfikat składa się z klucza publicznego właściciela. Wszelkie dane zaszyfrowane przy użyciu tego klucza publicznego można odszyfrować tylko przy użyciu odpowiedniego tajnego klucza, który jest w posiadaniu właściciela certyfikatu.

Tak jak Spartanie używali Scytale

Scytale jest znany jako sposób na szyfrowanie i odszyfrowywanie wiadomości, który był używany około 400 r. p.n.e. przez Spartan. Pisali wiadomość na arkuszu papirusu (rodzaj papieru), który był owinięty wokół laski. Odbiorca może odszyfrować wiadomość tylko wtedy, gdy ma prawidłową średnicę i rozmiar łaty. Służy jako sposób na szyfrowanie i unikanie nieautoryzowanego wydobycia wiadomości lub danych do miejsca docelowego.

Podobnie jak w przypadku MySQL, używanie protokołów i szyfrów SSL/TLS to sposób na uniknięcie wyłudzenia danych lub przechwycenia danych przez osoby przesyłane przewodem lub przez Internet.

Domyślnie programy MySQL próbują łączyć się za pomocą szyfrowania, jeśli serwer obsługuje połączenia szyfrowane, powracając do połączenia nieszyfrowanego, jeśli nie można nawiązać połączenia szyfrowanego. Od wersji MySQL>=5.7, pliki TLS/SSL i RSA mogą być tworzone lub generowane przy pomocy zmiennych. W przypadku dystrybucji MySQL skompilowanych przy użyciu OpenSSL serwer MySQL ma możliwość automatycznego generowania brakujących plików SSL i RSA podczas uruchamiania. Zmienne systemowe auto_generate_certs, sha256_password_auto_generate_rsa_keys i caching_sha2_password_auto_generate_rsa_keys (wersja>=8.0) sterują automatycznym generowaniem tych plików. Te zmienne są domyślnie włączone. Można je włączać podczas uruchamiania i sprawdzać, ale nie można ich ustawiać w czasie wykonywania.

Domyślnie te zmienne są włączone lub włączone. W przeciwnym razie użytkownicy mogą ręcznie wywołać narzędzie mysql_ssl_rsa_setup. W przypadku niektórych typów dystrybucji, takich jak pakiety RPM i DEB, wywołanie mysql_ssl_rsa_setup następuje podczas inicjowania katalogu danych. W takim przypadku dystrybucja MySQL nie musi być skompilowana przy użyciu OpenSSL, o ile dostępne jest polecenie openssl.

Gdy te pliki będą dostępne i/lub wygenerowane, MySQL nadal nie będzie używał połączeń szyfrujących z następujących powodów. Jak wspomniano wcześniej, domyślnie programy klienckie MySQL próbują nawiązać połączenie szyfrowane, jeśli serwer obsługuje połączenia szyfrowane, z dalszą kontrolą dostępną za pośrednictwem trybu --ssl (lub --ssl <=5.7.11, ponieważ jest to już przestarzałe) opcja:

  • Domyślnie, jeśli połączenie MySQL nie jest oflagowane za pomocą --ssl-mode, domyślną wartością jest --ssl-mode=PREFEROWANE. Dlatego klienci próbują łączyć się za pomocą szyfrowania, powracając do połączenia nieszyfrowanego, jeśli nie można nawiązać połączenia szyfrowanego.

  • W przypadku --ssl-mode=REQUIRED klienci wymagają połączenia szyfrowanego i zawodzą, jeśli nie można nawiązać takiego połączenia.

  • Przy --ssl-mode=DISABLED klienci używają połączenia nieszyfrowanego.

  • W przypadku --ssl-mode=VERIFY_CA lub --ssl-mode=VERIFY_IDENTITY klienci wymagają połączenia szyfrowanego a także przeprowadzić weryfikację względem certyfikatu CA serwera i (z VERIFY_IDENTITY) względem nazwy hosta serwera w jego certyfikacie.

Z domyślnym mechanizmem MySQL do korzystania z preferowanego połączenia, prawdopodobnie próbuje użyć szyfrowanego lub zabezpieczonego połączenia, ale nadal pozostawia kilka rzeczy do zrobienia i ustalenia.

Jak wspomniano wcześniej, zmienne auto_generate_certs, sha256_password_auto_generate_rsa_keys i caching_sha2_password_auto_generate_rsa_keys (wersja>=8.0) pomagają wygenerować wymagane pliki SSL/TLS i RSA, przy czym normalny użytkownik bez takich wymagań podczas połączenia nadal będzie niepewny. Na przykład utwórzmy użytkownika o nazwie dbadmin.

mysql> create user 'dbadmin'@'192.168.40.%' identified by '[email protected]';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'192.168.40.%';
Query OK, 0 rows affected (0.01 sec)

Następnie sprawdź, czy zmienne są ustawione poprawnie, które powinny być włączone tak, jak są domyślnie:

mysql> show global variables where variable_name in ('auto_generate_certs','sha256_password_auto_generate_rsa_keys','caching_sha2_password_auto_generate_rsa_keys');
+----------------------------------------------+-------+
| Variable_name                                | Value |
+----------------------------------------------+-------+
| auto_generate_certs                          | ON    |
| caching_sha2_password_auto_generate_rsa_keys | ON    |
| sha256_password_auto_generate_rsa_keys       | ON    |
+----------------------------------------------+-------+
3 rows in set (0.00 sec)

Sprawdzanie, czy pliki są odpowiednio generowane w ścieżce /var/lib/mysql/ (lub ścieżce katalogu danych dla tego MySQL):

$ find /var/lib/mysql -name "*.pem"
/var/lib/mysql/ca-key.pem
/var/lib/mysql/ca.pem
/var/lib/mysql/server-key.pem
/var/lib/mysql/server-cert.pem
/var/lib/mysql/client-key.pem
/var/lib/mysql/client-cert.pem
/var/lib/mysql/private_key.pem
/var/lib/mysql/public_key.pem

Następnie sprawdź, czy pliki SSL są ładowane poprawnie:

mysql> show global variables like 'ssl%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| ssl_ca        | ca.pem          |
| ssl_capath    |                 |
| ssl_cert      | server-cert.pem |
| ssl_cipher    |                 |
| ssl_crl       |                 |
| ssl_crlpath   |                 |
| ssl_fips_mode | OFF             |
| ssl_key       | server-key.pem  |
+---------------+-----------------+
8 rows in set (0.00 sec)

Określ bezpieczeństwo połączenia

Teraz wygląda to dobrze. Oznacza to również, że MySQL jest gotowy do akceptowania połączeń szyfrowanych. Ale łączenie się z MySQL w takim stanie, w jakim jest, powinno używać domyślnie --ssl-mode=PREFEROWANE, lub jeśli --ssl-mode nie jest określone, nadal powróci do użycia nieszyfrowanego połączenia. Zobacz poniżej:

$ mysql przykł[email protected] -h 192.168.40.110 -udbadmin -e "status;"|grep ssl -i

SSL:                    Nieużywane

To pokazuje, że nie korzysta z bezpiecznego połączenia. Sprawdzanie zmiennych stanu sesji SSL, jeśli używane są jakiekolwiek szyfry, pokazuje puste:

mysql> show global status like 'ssl%';
+--------------------------------+--------------------------+
| Variable_name                  | Value                    |
+--------------------------------+--------------------------+
| Ssl_accept_renegotiates        | 0                        |
| Ssl_accepts                    | 2                        |
| Ssl_callback_cache_hits        | 0                        |
| Ssl_cipher                     |                          |
| Ssl_cipher_list                |                          |
| Ssl_client_connects            | 0                        |
| Ssl_connect_renegotiates       | 0                        |
| Ssl_ctx_verify_depth           | 18446744073709551615     |
| Ssl_ctx_verify_mode            | 5                        |
| Ssl_default_timeout            | 0                        |
| Ssl_finished_accepts           | 2                        |
| Ssl_finished_connects          | 0                        |
| Ssl_server_not_after           | Aug 28 12:48:46 2031 GMT |
| Ssl_server_not_before          | Aug 30 12:48:46 2021 GMT |
| Ssl_session_cache_hits         | 0                        |
| Ssl_session_cache_misses       | 0                        |
| Ssl_session_cache_mode         | SERVER                   |
| Ssl_session_cache_overflows    | 0                        |
| Ssl_session_cache_size         | 128                      |
| Ssl_session_cache_timeouts     | 0                        |
| Ssl_sessions_reused            | 0                        |
| Ssl_used_session_cache_entries | 0                        |
| Ssl_verify_depth               | 0                        |
| Ssl_verify_mode                | 0                        |
| Ssl_version                    |                          |
+--------------------------------+--------------------------+
25 rows in set (0.002 sec)

Wymuszanie bezpiecznego połączenia 

Ponieważ pokazuje, że połączenie nadal nie jest zabezpieczone, MySQL wprowadza zmienną require_secure_transport, która wymaga, aby wszystkie połączenia, które mają być nawiązane, były szyfrowane i zabezpieczone. Wszelkie próby nawiązania połączenia niezabezpieczonego kończą się niepowodzeniem. Na przykład włączenie go na serwerze:

mysql> set global require_secure_transport=1;
Query OK, 0 rows affected (0.00 sec)

Próba połączenia jako klient przy użyciu połączenia nieszyfrowanego nie powiedzie się:

$ mysql [email protected] -h 192.168.40.110 -udbadmin
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.

Aby połączyć się pomyślnie i bezpiecznie, musisz określić zmienne ssl-ca, ssl-cert, ssl-key. Zobacz poniżej:

$ mysql [email protected] -h 192.168.40.110 -udbadmin --ssl-ca=/tmp/pem/ca.pem --ssl-cert=/tmp/pem/server-cert.pem --ssl-key=/tmp/pem/server-key.pem -e "show global status like 'ssl%'\G"
*************************** 1. row ***************************
Variable_name: Ssl_accept_renegotiates
        Value: 0
*************************** 2. row ***************************
Variable_name: Ssl_accepts
        Value: 16
*************************** 3. row ***************************
Variable_name: Ssl_callback_cache_hits
        Value: 0
*************************** 4. row ***************************
Variable_name: Ssl_cipher
        Value: TLS_AES_256_GCM_SHA384
*************************** 5. row ***************************
Variable_name: Ssl_cipher_list
        Value: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA
*************************** 6. row ***************************
Variable_name: Ssl_client_connects
        Value: 0
*************************** 7. row ***************************
Variable_name: Ssl_connect_renegotiates
        Value: 0
*************************** 8. row ***************************
Variable_name: Ssl_ctx_verify_depth
        Value: 18446744073709551615
*************************** 9. row ***************************
Variable_name: Ssl_ctx_verify_mode
        Value: 5
*************************** 10. row ***************************
Variable_name: Ssl_default_timeout
        Value: 7200
*************************** 11. row ***************************
Variable_name: Ssl_finished_accepts
        Value: 11
*************************** 12. row ***************************
Variable_name: Ssl_finished_connects
        Value: 0
*************************** 13. row ***************************
Variable_name: Ssl_server_not_after
        Value: Aug 28 12:48:46 2031 GMT
*************************** 14. row ***************************
Variable_name: Ssl_server_not_before
        Value: Aug 30 12:48:46 2021 GMT
*************************** 15. row ***************************
Variable_name: Ssl_session_cache_hits
        Value: 0
*************************** 16. row ***************************
Variable_name: Ssl_session_cache_misses
        Value: 0
*************************** 17. row ***************************
Variable_name: Ssl_session_cache_mode
        Value: SERVER
*************************** 18. row ***************************
Variable_name: Ssl_session_cache_overflows
        Value: 0
*************************** 19. row ***************************
Variable_name: Ssl_session_cache_size
        Value: 128
*************************** 20. row ***************************
Variable_name: Ssl_session_cache_timeouts
        Value: 0
*************************** 21. row ***************************
Variable_name: Ssl_sessions_reused
        Value: 0
*************************** 22. row ***************************
Variable_name: Ssl_used_session_cache_entries
        Value: 0
*************************** 23. row ***************************
Variable_name: Ssl_verify_depth
        Value: 18446744073709551615
*************************** 24. row ***************************
Variable_name: Ssl_verify_mode
        Value: 5
*************************** 25. row ***************************
Variable_name: Ssl_version
        Value: TLSv1.3

Alternatywnie, jeśli użytkownik jest utworzony na przykład z WYMAGANYM SSL, powinien on również łączyć się przy użyciu SSL, niezależnie od tego, że require_secure_transport jest wyłączony, co jest jego wartością domyślną. Zwróć uwagę, że jeśli opcja require_secure_transport jest włączona, jej możliwości uzupełniają wymagania SSL dla poszczególnych kont, które mają pierwszeństwo. Dlatego też, jeśli konto jest zdefiniowane z WYMAGAJ SSL, włączenie require_secure_transport nie umożliwia korzystania z konta do łączenia się przy użyciu pliku gniazda Unix.

Upewnianie się, że wdrożenia serwerów MySQL są szyfrowane i bezpieczne

Bezproblemowy jest tym, na co zawsze czekamy, aby nie było innych problemów i obaw, którymi trzeba się martwić. ClusterControl wdraża bazy danych MySQL przy użyciu szyfrowanych połączeń i generuje dla Ciebie certyfikaty SSL i RSA. Na przykład poniższy zrzut ekranu przedstawiający aktywność zadania polecenia Utwórz klaster z ClusterControl.

Konfiguruje pliki SSL i RSA i umieszcza je w /etc/ mysql/certs/ ścieżka jak poniżej:

mysql> show global variables like 'ssl%';
+---------------+--------------------------------+
| Variable_name | Value                          |
+---------------+--------------------------------+
| ssl_ca        | /etc/mysql/certs/server_ca.crt |
| ssl_capath    |                                |
| ssl_cert      | /etc/mysql/certs/server.crt    |
| ssl_cipher    |                                |
| ssl_crl       |                                |
| ssl_crlpath   |                                |
| ssl_key       | /etc/mysql/certs/server.key    |
+---------------+--------------------------------+
7 rows in set (0.00 sec)

Następnie ClusterControl grupuje również wygenerowane pliki SSL i RSA w sposób scentralizowany w panelu nawigacyjnym Key Management, jak pokazano poniżej:

Po wdrożeniu wszystko, co musisz zrobić, to utworzyć użytkowników z WYMAGANYM protokołem SSL lub mieć require_secure_transport, jeśli chcesz wymusić szyfrowaną i bezpieczną warstwę dla połączeń z serwerem MySQL.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zainstalować sterownik pdo w obrazie dokera php?

  2. Jak zainstalować MySQL Workbench na Ubuntu?

  3. Jak uzyskać surowe, skompilowane zapytanie SQL z wyrażenia SQLAlchemy?

  4. Wskazówki dotyczące aktualizacji klastra Percona XtraDB do wersji 8.0

  5. Jak korzystać z pakietu zbiorczego MySQL