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.