Mysql
 sql >> Database >  >> RDS >> Mysql

Le mie connessioni al server MySQL sono crittografate e sicure?

Uno dei principali fattori e fondamenti della governance dei dati è la sicurezza. È buona norma avere la sicurezza del database implementata ogni volta che si ha a che fare con la gestione dei dati per il consumo aziendale o di massa.

La sicurezza dei dati è uno degli aspetti più significativi dell'amministrazione di un database. Svolge un ruolo critico per il quale ogni gestione di database dovrebbe implementare. Quando viene implementato e fatto correttamente, il risultato non solo migliorerà la sicurezza dei dati, ma influirà anche sulla stabilità del sistema, migliora il ciclo di vita dello sviluppo, aumenta la conformità dei dati e migliora la consapevolezza della sicurezza fino al livello del tuo team. Tutti non vogliono che i propri dati finiscano nelle mani sbagliate. La violazione dei dati non solo mette a rischio la riservatezza e l'integrità dei dati, ma lascia anche l'organizzazione esposta a rischi finanziari significativi. Anche per una semplice implementazione della gestione del database, se scopri che qualcuno si è già intromesso nel tuo sistema, la sensazione di essere insicuro e spaventato dalle conseguenze che ti porteranno è totalmente sconfortante.

La determinazione della sicurezza della connessione al server MySQL dipende dalla sicurezza con cui MySQL trasmette i dati in transito. Con una connessione non crittografata tra il client MySQL e il server, qualcuno con accesso alla rete potrebbe controllare tutto il tuo traffico e ispezionare i dati inviati o ricevuti tra client e server.

Quando devi spostare le informazioni su una rete in modo sicuro, una connessione non crittografata è inaccettabile. Per rendere illeggibile qualsiasi tipo di dato, usa la crittografia. Gli algoritmi di crittografia devono includere elementi di sicurezza per resistere a molti tipi di attacchi noti, come la modifica dell'ordine dei messaggi crittografati o la riproduzione dei dati due volte.

Ma il mio MySQL è sicuro, giusto?

Credere che il proprio MySQL sia al sicuro senza determinarne la stabilità e i controlli di vulnerabilità è come una religione. Tendi a credere anche senza vederlo, anche senza toccarlo. Il problema è che MySQL è una tecnologia e la sua esistenza non si basa su pensieri astratti. Deve essere testato, deve essere dimostrato e richiede sicurezza e segue le migliori pratiche che sono state testate anche da altri.

La determinazione se le connessioni del server MySQL, ad esempio in transito, sono sicure o se è crittografato si basa su "come hai impostato il database?" o "chi ha configurato il tuo database?".

MySQL supporta connessioni crittografate tra client e server utilizzando il protocollo TLS (Transport Layer Security). TLS è talvolta indicato come SSL (Secure Sockets Layer) ma MySQL in realtà non utilizza il protocollo SSL per le connessioni crittografate perché la sua crittografia è debole e SSL è già stato deprecato a favore di TLS. TLS utilizza algoritmi di crittografia per garantire che i dati ricevuti su una rete pubblica siano affidabili. Dispone di meccanismi per rilevare la modifica, la perdita o la riproduzione dei dati. TLS incorpora anche algoritmi che forniscono la verifica dell'identità utilizzando lo standard X.509. SSL o TLS vengono utilizzati in modo intercambiabile, ma per il contesto della crittografia con MySQL, viene utilizzato TLS per il quale MySQL supporta connessioni crittografate utilizzando i protocolli TLSv1, TLSv1.1, TLSv1.2 e TLSv1.3.

X.509 consente di identificare qualcuno su Internet. In parole povere, dovrebbe esserci un'entità chiamata "Autorità di certificazione" (o CA) che assegna certificati elettronici a chiunque ne abbia bisogno. I certificati si basano su algoritmi di crittografia asimmetrici che dispongono di due chiavi di crittografia (una chiave pubblica e una chiave segreta). Il proprietario del certificato può presentare il certificato a un'altra parte come prova di identità. Un certificato è costituito dalla chiave pubblica del suo proprietario. Qualsiasi dato crittografato utilizzando questa chiave pubblica può essere decrittografato solo utilizzando la chiave segreta corrispondente, che è detenuta dal proprietario del certificato.

Proprio come gli Spartani usavano Scytale

Scytale è noto per essere utilizzato come un modo per crittografare e decrittare un messaggio utilizzato intorno al 400 a.C. dagli Spartani. Avrebbero scritto un messaggio su un foglio di papiro (un tipo di carta) avvolto attorno a un bastone. Il destinatario può decifrare il messaggio solo se il diametro e la dimensione del personale corretti. Serve come un modo per crittografare ed evitare l'estrazione non autorizzata di messaggi o dati nella destinazione di destinazione.

Proprio come con MySQL, l'utilizzo di protocolli e cifrari SSL/TLS è un modo per evitare che qualcuno estragga i tuoi dati o dirotti i tuoi dati mentre passano il cavo o su Internet.

Per impostazione predefinita, i programmi MySQL tentano di connettersi utilizzando la crittografia se il server supporta connessioni crittografate, ricorrendo a una connessione non crittografata se non è possibile stabilire una connessione crittografata. Dalla versione MySQL>=5.7, i file TLS/SSL e RSA possono essere creati o generati con il supporto di variabili. Per le distribuzioni MySQL compilate utilizzando OpenSSL, il server MySQL ha la capacità di generare automaticamente file SSL e RSA mancanti all'avvio. Le variabili di sistema auto_generate_certs, sha256_password_auto_generate_rsa_keys e caching_sha2_password_auto_generate_rsa_keys (versione>=8.0), controllano la generazione automatica di questi file. Queste variabili sono abilitate per impostazione predefinita. Possono essere abilitati all'avvio e ispezionati ma non impostati in fase di esecuzione.

Per impostazione predefinita, queste variabili sono impostate su ON o abilitate. In caso contrario, gli utenti possono richiamare manualmente l'utilità mysql_ssl_rsa_setup. Per alcuni tipi di distribuzione, come i pacchetti RPM e DEB, il richiamo di mysql_ssl_rsa_setup avviene durante l'inizializzazione della directory dei dati. In questo caso, non è necessario che la distribuzione MySQL sia stata compilata utilizzando OpenSSL finché è disponibile il comando openssl.

Una volta che questi file sono disponibili e/o generati, MySQL non utilizzerà ancora le connessioni di crittografia per i seguenti motivi. Come accennato in precedenza, per impostazione predefinita, i programmi client MySQL tentano di stabilire una connessione crittografata se il server supporta connessioni crittografate, con ulteriore controllo disponibile tramite --ssl-mode (o --ssl <=5.7.11 poiché questo è già deprecato) opzione:

  • Per impostazione predefinita, se la connessione MySQL non è contrassegnata con --ssl-mode, il valore predefinito è impostato su --ssl-mode=PREFERITO. Pertanto, i client tentano di connettersi utilizzando la crittografia, ricorrendo a una connessione non crittografata se non è possibile stabilire una connessione crittografata.

  • Con --ssl-mode=REQUIRED, i client richiedono una connessione crittografata e falliscono se non può essere stabilita.

  • Con --ssl-mode=DISABLED, i client utilizzano una connessione non crittografata.

  • Con --ssl-mode=VERIFY_CA o --ssl-mode=VERIFY_IDENTITY, i client richiedono una connessione crittografata ed eseguire anche la verifica rispetto al certificato CA del server e (con VERIFY_IDENTITY) rispetto al nome host del server nel suo certificato.

Con il meccanismo predefinito di MySQL per utilizzare una connessione preferita, probabilmente tenterà di utilizzare la connessione crittografata o protetta, ma questo lascia ancora alcune cose da fare e da determinare.

Come accennato in precedenza, le variabili auto_generate_certs, sha256_password_auto_generate_rsa_keys e caching_sha2_password_auto_generate_rsa_keys (versione>=8.0) aiutano a generare i file SSL/TLS e RSA richiesti, con l'utente normale senza tali requisiti durante la connessione deve comunque essere insicuro. Ad esempio, creiamo un utente chiamato 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)

Quindi verifica se le variabili sono impostate correttamente che dovrebbero essere abilitate come sono di default:

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)

Verifica se i file vengono generati di conseguenza nel percorso /var/lib/mysql/ (o nel percorso di datadir per questo 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

Quindi verifica se i file SSL sono stati caricati correttamente:

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)

Determina la sicurezza della tua connessione

Ora, sembra a posto. Significa anche che MySQL è pronto per accettare connessioni crittografate. Ma la connessione a MySQL così com'è, come affermato, utilizzerà --ssl-mode=PREFFERED per impostazione predefinita, o se --ssl-mode non è specificato, eseguirà comunque il failback per utilizzare una connessione non crittografata. Vedi sotto:

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

SSL:                    Non utilizzato

Questo rivela che non sta usando una connessione protetta. Il controllo delle variabili di stato della sessione SSL se vengono utilizzati codici rivela vuoto:

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)

Applicazione di una connessione protetta 

Poiché rivela che la connessione non è ancora protetta, MySQL introduce la variabile require_secure_transport che richiede che tutte le connessioni da effettuare siano crittografate e protette. Qualsiasi tentativo di connessione per una connessione non protetta non riesce. Ad esempio, abilitandolo sul server:

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

Il tentativo di connessione come client utilizzando una connessione non crittografata avrà esito negativo:

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

Per connettersi correttamente e in modo sicuro, è necessario specificare le variabili ssl-ca, ssl-cert, ssl-key. Vedi sotto:

$ 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

In alternativa, se un utente viene creato ad esempio con REQUIRED SSL, anche questo dovrebbe connetterti utilizzando SSL indipendentemente dal fatto che require_secure_transport sia disabilitato, che è il suo valore predefinito. Tieni presente che, se require_secure_transport è abilitato, la sua funzionalità integra i requisiti SSL per account, che hanno la precedenza. Pertanto, se un account è definito con REQUIRE SSL, l'abilitazione di require_secure_transport non rende possibile utilizzare l'account per connettersi utilizzando un file socket Unix.

Assicurarsi che le implementazioni del server MySQL siano crittografate e sicure

La semplicità è ciò che attendiamo sempre con impazienza, in modo che non ci siano altri problemi e preoccupazioni di cui preoccuparsi. ClusterControl distribuisce database MySQL utilizzando connessioni crittografate e genera i certificati SSL e RSA per te. Ad esempio, uno screenshot di seguito che mostra l'attività lavorativa di un comando Crea cluster da ClusterControl.

Imposta i file SSL e RSA e li inserisce in /etc/ mysql/certs/ percorso proprio come di seguito:

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)

Quindi ClusterControl raggruppa anche i file SSL e RSA generati in modo centralizzato nel pannello di navigazione di Key Management come mostrato di seguito:

Una volta distribuito, tutto ciò che devi fare è creare utenti con SSL RICHIESTO o avere require_secure_transport se desideri applicare un livello crittografato e protetto per le connessioni del tuo server MySQL.