La crittografia è una delle funzionalità di sicurezza più importanti per mantenere i tuoi dati il più sicuri possibile. A seconda dei dati che stai gestendo, non sempre è un must, ma dovresti almeno considerarlo come un miglioramento della sicurezza nella tua organizzazione, ed è effettivamente consigliabile evitare il furto di dati o l'accesso non autorizzato.
In questo blog descriveremo due tipi base di crittografia e come configurarla su un server MariaDB.
Cos'è la crittografia dei dati?
Esistono due tipi base di crittografia dei dati:a riposo e in transito. Vediamo cosa significano.
Crittografia dati a riposo
I dati archiviati in un sistema sono noti come dati inattivi. La crittografia di questi dati consiste nell'utilizzare un algoritmo per convertire il testo o il codice in illeggibile. È necessario disporre di una chiave di crittografia per decodificare i dati crittografati.
La crittografia di un intero database deve essere eseguita con cautela poiché può comportare un grave impatto sulle prestazioni. È quindi consigliabile crittografare solo singoli campi o tabelle.
La crittografia dei dati inattivi protegge i dati dal furto fisico dei dischi rigidi o dall'accesso non autorizzato all'archiviazione dei file. Questa crittografia è inoltre conforme alle normative sulla sicurezza dei dati, soprattutto se sono presenti dati finanziari o sanitari archiviati nel filesystem.
Crittografia dei dati in transito
I dati trasferiti o spostati tra le transazioni sono noti come dati in transito. I dati che si spostano tra il server e il client durante la navigazione nelle pagine web sono un buon esempio di questo tipo di dati.
Dato che è sempre in movimento, deve essere protetto con un'adeguata crittografia per evitare qualsiasi furto o alterazione dei dati prima che raggiungano la sua destinazione.
La situazione ideale per proteggere i dati in transito è crittografare i dati prima che si spostino e decodificarli solo quando raggiungono la destinazione finale.
Crittografia dei dati a riposo di MariaDB
La crittografia di tabelle e tablespace è stata aggiunta in MariaDB dalla versione 10.1 e supporta la crittografia per i motori di archiviazione XtraDB, InnoDB e Aria e anche per i log binari.
Puoi scegliere diversi modi per crittografare:
- Tutte le tabelle
- Tabelle individuali
- Tutto, esclusi i singoli tavoli
Secondo la documentazione, l'utilizzo della crittografia ha un sovraccarico di circa il 3-5%, quindi è importante disporre di un ambiente di test per sottolinearlo e vedere come risponde, per evitare problemi in produzione.
Come configurare la crittografia dei dati a riposo su MariaDB
Controlliamo una tabella "city" esistente in un database MariaDB:
$ strings city.ibd |head
infimum
supremum
infimum
supremum
3ABW
3KHM
infimum
supremum
Kabul AFGKabol
Qandahar AFGQandahar
Come puoi vedere, puoi leggere i dati da lì senza alcun problema usando il comando strings Linux, ad esempio. Ora vediamo come crittografarlo.
Genera una chiave di crittografia usando il comando openssl rand:
$ mkdir -p /etc/mysql/encryption
$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile; done;
Modifica il file generato /etc/mysql/encryption/keyfile e aggiungi gli ID chiave a cui verrà fatto riferimento durante la creazione di tabelle crittografate. Il formato dovrebbe essere il seguente:
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>
Puoi modificarlo usando il comando sed linux in questo modo:
$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done
Quindi il file dovrebbe essere qualcosa del genere:
$ cat /etc/mysql/encryption/keyfile
1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af
2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5
3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169
4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab
Ora, genera una password casuale usando il comando openssl simile che hai visto prima:
$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
Prima di procedere al passaggio successivo, è importante conoscere i seguenti dettagli sulla crittografia del file della chiave:
- L'unico algoritmo attualmente supportato da MariaDB per crittografare il file della chiave è la modalità Cipher Block Chaining (CBC) di Advanced Encryption Standard (AES).
- La dimensione della chiave di crittografia può essere 128 bit, 192 bit o 256 bit.
- La chiave di crittografia viene creata dall'hash SHA-1 della password di crittografia.
- La password di crittografia ha una lunghezza massima di 256 caratteri.
Ora, per crittografare il file della chiave utilizzando il comando openssl enc, eseguire il comando seguente:
$ openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/encryption/keyfile.key -in /etc/mysql/encryption/keyfile -out /etc/mysql/encryption/keyfile.enc
Infine, devi aggiungere i seguenti parametri nel tuo file di configurazione my.cnf (che si trova in /etc/ su OS basato su RedHat o /etc/mysql/ su OS basato su Debian):
[mysqld]
…
#################### DATABASE ENCRYPTION ####################
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/encryption/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
file_key_management_encryption_algorithm = aes_cbc
encrypt_binlog = 1
innodb_encrypt_tables = ON
innodb_encrypt_log = ON
innodb_encryption_threads = 4
innodb_encryption_rotate_key_age = 0
…
E riavvia il servizio MariaDB per accettare le modifiche:
$ systemctl restart mariadb
A questo punto, tutto è pronto per utilizzare la funzione di crittografia. Criptiamo la stessa tabella che abbiamo mostrato in precedenza, "città". Per questo, è necessario utilizzare l'istruzione ALTER TABLE impostando il parametro ENCRYPTED in YES:
MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;
Query OK, 0 rows affected (0.483 sec)
Records: 0 Duplicates: 0 Warnings: 0
Ora, se provi ad accedere alla tabella direttamente dal file system, vedrai qualcosa del genere:
$ strings city.ibd |head
PU%O
!ybN)b
9,{9WB4
T3uG:
?oiN
,35sz
8g)Q
o(o
q_A1
k=-w
Come puoi vedere, la tabella è illeggibile. Puoi anche specificare l'ID della chiave di crittografia aggiungendo il parametro ENCRYPTION_KEY_ID =
Le nuove tabelle verranno crittografate per impostazione predefinita poiché impostiamo il parametro innodb_encrypt_tables su ON nel file di configurazione my.cnf.
Crittografia dei dati in transito di MariaDB
MariaDB consente di crittografare i dati in transito tra il server e i client utilizzando il protocollo Transport Layer Security (TLS), precedentemente noto come Secure Socket Layer o SSL.
Prima di tutto, devi assicurarti che il tuo server MariaDB sia stato compilato con il supporto TLS. Puoi verificarlo eseguendo la seguente istruzione SHOW GLOBAL VARIABLES:
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'version_ssl_library';
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------+
1 row in set (0.001 sec)
E controlla se non è attualmente in uso usando l'istruzione SHOW VARIABLES:
MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| have_openssl | YES |
| have_ssl | DISABLED |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | |
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------+
10 rows in set (0.001 sec)
Puoi anche verificare lo stato SSL usando il comando status MariaDB:
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Connection id: 22
Current database:
Current user: [email protected]
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 4 hours 28 min 25 sec
Threads: 11 Questions: 111668 Slow queries: 0 Opens: 92 Flush tables: 1 Open tables: 85 Queries per second avg: 6.933
--------------
Come configurare la crittografia dei dati in transito su MariaDB
Creiamo la directory certs per memorizzare tutti i certificati:
$ mkdir -p /etc/mysql/certs
Ora generiamo i certificati CA che verranno configurati per crittografare la connessione:
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
Questo ultimo comando ti chiederà di completare le seguenti informazioni:
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Ora devi generare i certificati del server:
$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
Questo comando ti chiederà di inserire le stesse informazioni di prima più una password del certificato opzionale.
$ openssl rsa -in server-key.pem -out server-key.pem
$ openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
E infine, devi generare i certificati client:
$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
Questo ti chiederà anche di completare le informazioni e una password di certificato opzionale.
$ openssl rsa -in client-key.pem -out client-key.pem
$ openssl x509 -req -in client-req.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Assicurati di utilizzare un nome comune diverso su ogni certificato, altrimenti non funzionerà e riceverai un messaggio del tipo:
ERROR 2026 (HY000): SSL connection error: self signed certificate
In questo momento, avrai qualcosa del genere:
$ ls /etc/mysql/certs/
ca-cert.pem ca-key.pem client-cert.pem client-key.pem client-req.pem server-cert.pem server-key.pem server-req.pem
E puoi convalidare i certificati usando il seguente comando:
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Quindi ora configuriamolo nel file di configurazione my.cnf (che si trova in /etc/ su OS basato su RedHat o /etc/mysql/ su OS basato su Debian):
[mysqld]
ssl_ca=/etc/mysql/certs/ca-cert.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pem
[client-mariadb]
ssl_ca =/etc/mysql/certs/ca-cert.pem
ssl_cert=/etc/mysql/certs/client-cert.pem
ssl_key=/etc/mysql/certs/client-key.pem
Assicurati di aggiungerlo nella sezione corrispondente (mysqld e client-mariadb).
Cambia il proprietario del certificato e riavvia il servizio database:
$ chown mysql.mysql /etc/mysql/certs/
$ systemctl restart mariadb
Dopo questo, se dai un'occhiata all'output SHOW VARIABLES, dovresti avere questo:
MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';
+---------------------+----------------------------------+
| Variable_name | Value |
+---------------------+----------------------------------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | /etc/mysql/certs/ca-cert.pem |
| ssl_capath | |
| ssl_cert | /etc/mysql/certs/server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/mysql/certs/server-key.pem |
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------------+
10 rows in set (0.001 sec)
Ora creiamo un utente con il parametro REQUIRE SSL per usarlo:
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;
Query OK, 0 rows affected (0.005 sec)
Se usi questo utente per accedere al database e controlli il comando di stato, vedrai l'SSL in uso:
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Connection id: 15
Current database:
Current user: [email protected]
SSL: Cipher in use is TLS_AES_256_GCM_SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution
Protocol version: 10
Connection: 127.0.0.1 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 16 sec
Threads: 11 Questions: 136 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 8.500
--------------
Come abilitare la crittografia SSL con ClusterControl
Un altro modo, e anche più semplice, per abilitare SSL sul database MariaDB consiste nell'usare ClusterControl. Supponiamo che tu abbia installato ClusterControl e che tu stia gestendo il tuo database MariaDB utilizzandolo, quindi vai su ClusterControl -> Seleziona il tuo cluster MariaDB -> Sicurezza -> Crittografia SSL -> Abilita.
E il gioco è fatto, avrai la tua crittografia SSL abilitata nel tuo database MariaDB senza alcuna operazione manuale.
Limitazioni della crittografia a riposo in MariaDB
Esistono alcune limitazioni relative alla crittografia a riposo di MariaDB di cui tenere conto:
- I metadati (ad esempio i file .frm) ei dati inviati al client non sono crittografati.
- Solo il server MariaDB sa come decrittare i dati, in particolare
- mysqlbinlog può leggere log binari crittografati solo quando viene utilizzato --read-from-remote-server.
- Percona XtraBackup non può eseguire il backup di istanze che utilizzano InnoDB crittografato. Tuttavia, Mariabackup può eseguire il backup di istanze crittografate.
- La gcache Galera basata su disco non è crittografata nella versione community di MariaDB Server, tuttavia, questo file è crittografato in MariaDB Enterprise Server 10.4.
- Il plug-in Audit non può creare output crittografato. Invialo a syslog e configura lì invece la protezione.
- Il registro delle query generali basato su file e il registro delle query lente non possono essere crittografati.
- Il log di Aria non è crittografato. Ciò riguarda solo i tavoli Aria non temporanei.
- Il registro degli errori di MariaDB non è crittografato. Il registro degli errori può contenere testo e dati della query in alcuni casi, inclusi arresti anomali, errori di asserzione e casi in cui InnoDB/XtraDB scrive l'output di monitoraggio nel registro per facilitare il debug. Può essere inviato anche a syslog, se necessario.
Conclusione
La protezione dei dati in transito è importante quanto la protezione dei dati inattivi e, anche se non è un must nella tua organizzazione, dovresti prendere in considerazione l'applicazione in quanto può aiutarti a evitare i dati furto o accesso non autorizzato.
MariaDB ha un modo abbastanza semplice per implementarlo seguendo i passaggi menzionati in precedenza, ma è sicuramente ancora più semplice utilizzare ClusterControl.