Kryptering är en av de viktigaste säkerhetsfunktionerna för att hålla din data så säker som möjligt. Beroende på vilken data du hanterar är det inte alltid ett måste men du bör åtminstone betrakta det som en säkerhetsförbättring i din organisation ändå, och det rekommenderas faktiskt att undvika datastöld eller obehörig åtkomst.
I den här bloggen kommer vi att beskriva två grundläggande typer av kryptering och hur man konfigurerar den på en MariaDB-server.
Vad är datakryptering?
Det finns två grundläggande typer av datakryptering:i vila och under transport. Låt oss se vad de betyder.
Data-at-rest-kryptering
Data som lagras i ett system kallas data-at-rest. Krypteringen av dessa data består av att använda en algoritm för att konvertera text eller kod till oläsbar. Du måste ha en krypteringsnyckel för att avkoda den krypterade informationen.
Kryptering av en hel databas bör göras med försiktighet eftersom det kan leda till allvarliga prestandapåverkan. Det är därför klokt att endast kryptera enskilda fält eller tabeller.
Kryptering av data-at-rest skyddar data från fysisk stöld av hårddiskar eller obehörig åtkomst till fillagring. Denna kryptering överensstämmer också med datasäkerhetsbestämmelser, särskilt om det finns ekonomiska eller hälsodata lagrade i filsystemet.
Data-in-Transit-kryptering
Data som överförs eller flyttas mellan transaktioner kallas data-in-transit. Data som rör sig mellan servern och klienten när du surfar på webbsidor är ett bra exempel på denna typ av data.
Eftersom den alltid är på resande fot måste den skyddas med korrekt kryptering för att undvika stöld eller ändring av data innan den når sin destination.
Den idealiska situationen för att skydda data under transport är att ha data krypterad innan den flyttar och dekrypteras först när den når slutdestinationen.
MariaDB Data-at-Rest-kryptering
Krypteringen av tabeller och tabellutrymmen lades till i MariaDB från version 10.1, och den stöder kryptering för XtraDB-, InnoDB- och Aria-lagringsmotorer och även för binära loggar.
Du kan välja olika sätt att kryptera:
- Alla tabeller
- Enskilda tabeller
- Allt, utom enskilda tabeller
Enligt dokumentationen har användning av kryptering en omkostnad på ungefär 3-5 %, så det är viktigt att ha en testmiljö för att betona det och se hur det reagerar, för att undvika problem i produktionen.
Hur man konfigurerar data-at-rest-kryptering på MariaDB
Låt oss kontrollera en befintlig "stad"-tabell i en MariaDB-databas:
$ strings city.ibd |head
infimum
supremum
infimum
supremum
3ABW
3KHM
infimum
supremum
Kabul AFGKabol
Qandahar AFGQandahar
Som du kan se kan du läsa data därifrån utan några problem genom att till exempel använda kommandot strings Linux. Nu ska vi se hur man krypterar det.
Generera en krypteringsnyckel med kommandot openssl rand:
$ mkdir -p /etc/mysql/encryption
$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile; done;
Redigera den genererade filen /etc/mysql/encryption/keyfile och lägg till nyckel-ID:n som kommer att refereras till när krypterade tabeller skapas. Formatet bör vara följande:
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>
Du kan redigera den med kommandot sed linux på det här sättet:
$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done
Så filen borde vara ungefär så här:
$ cat /etc/mysql/encryption/keyfile
1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af
2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5
3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169
4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab
Generera nu ett slumpmässigt lösenord med det liknande openssl-kommandot som du såg tidigare:
$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
Innan du fortsätter till nästa steg är det viktigt att känna till följande detaljer om kryptering av nyckelfilen:
- Den enda algoritmen som MariaDB för närvarande stöder för att kryptera nyckelfilen är Cipher Block Chaining (CBC)-läge för Advanced Encryption Standard (AES).
- Storleken på krypteringsnyckeln kan vara 128-bitar, 192-bitar eller 256-bitar.
- Krypteringsnyckeln skapas från SHA-1-hash för krypteringslösenordet.
- Krypteringslösenordet har en maxlängd på 256 tecken.
Nu, för att kryptera nyckelfilen med kommandot openssl enc, kör följande kommando:
$ 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
Slutligen måste du lägga till följande parametrar i din my.cnf-konfigurationsfil (finns i /etc/ på RedHat-baserat OS eller /etc/mysql/ på Debian-baserat OS):
[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
…
Och starta om MariaDB-tjänsten för att göra ändringarna:
$ systemctl restart mariadb
Vid denna tidpunkt är allt klart för att använda krypteringsfunktionen. Låt oss kryptera samma tabell som vi visade tidigare, "stad". För detta måste du använda ALTER TABLE-satsen som anger parametern ENCRYPTED i YES:
MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;
Query OK, 0 rows affected (0.483 sec)
Records: 0 Duplicates: 0 Warnings: 0
Nu, om du försöker komma åt tabellen direkt från filsystemet, kommer du att se något i stil med detta:
$ strings city.ibd |head
PU%O
!ybN)b
9,{9WB4
T3uG:
?oiN
,35sz
8g)Q
o(o
q_A1
k=-w
Som du kan se är tabellen oläslig. Du kan också ange krypteringsnyckel-ID genom att lägga till parametern ENCRYPTION_KEY_ID =
Nya tabeller kommer att krypteras som standard när vi ställer in parametern innodb_encrypt_tables till PÅ i konfigurationsfilen my.cnf.
MariaDB Data-in-Transit-kryptering
MariaDB låter dig kryptera data som överförs mellan servern och klienterna med hjälp av Transport Layer Security-protokollet (TLS), tidigare känt som Secure Socket Layer eller SSL.
Först och främst måste du se till att din MariaDB-server kompilerades med TLS-stöd. Du kan verifiera detta genom att köra följande SHOW GLOBAL VARIABLES-sats:
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)
Och kontrollera om den inte används för närvarande med hjälp av SHOW VARIABLES-satsen:
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)
Du kan också verifiera SSL-statusen med hjälp av kommandot 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
--------------
Hur man konfigurerar data-in-Transit-kryptering på MariaDB
Låt oss skapa certifikatkatalogen för att lagra alla certifikat:
$ mkdir -p /etc/mysql/certs
Låt oss nu generera CA-certifikaten som kommer att konfigureras för att kryptera anslutningen:
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
Det här sista kommandot ber dig att fylla i följande information:
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 []:
Nu måste du generera servercertifikaten:
$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
Detta kommando ber dig att fylla i samma information som tidigare plus ett valfritt certifikatlösenord.
$ 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
Och slutligen måste du generera klientcertifikaten:
$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
Detta kommer också att be dig att fylla i informationen och ett valfritt certifikatlösenord.
$ 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
Se till att du använder ett annat Common Name på varje certifikat, annars fungerar det inte och du får ett meddelande som:
ERROR 2026 (HY000): SSL connection error: self signed certificate
För närvarande kommer du att ha något sånt här:
$ 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
Och du kan validera certifikaten med följande kommando:
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Så låt oss nu konfigurera det i my.cnf-konfigurationsfilen (finns i /etc/ på RedHat-baserat OS eller /etc/mysql/ på Debian-baserat OS):
[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
Se till att du lägger till det under motsvarande avsnitt (mysqld och client-mariadb).
Ändra certifikatets ägare och starta om databastjänsten:
$ chown mysql.mysql /etc/mysql/certs/
$ systemctl restart mariadb
Efter detta, om du tar en titt på VISA VARIABLER, bör du ha detta:
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)
Nu, låt oss skapa en användare med parametern REQUIRE SSL för att använda den:
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;
Query OK, 0 rows affected (0.005 sec)
Om du använder den här användaren för att komma åt databasen och kontrollerar statuskommandot, kommer du att se SSL som används:
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
--------------
Hur man aktiverar SSL-kryptering med ClusterControl
Ett annat sätt, och till och med ett enklare sätt, att aktivera SSL på din MariaDB-databas är att använda ClusterControl. Vi antar att du har ClusterControl installerat och att du hanterar din MariaDB-databas med den, så gå till ClusterControl -> Välj ditt MariaDB-kluster -> Säkerhet -> SSL-kryptering -> Aktivera.
Och det är allt, du kommer att ha din SSL-kryptering aktiverad i din MariaDB-databas utan någon manuell uppgift.
Krypteringsbegränsningar i vila i MariaDB
Det finns några begränsningar relaterade till MariaDB at-rest-kryptering att ta hänsyn till:
- Metadata (till exempel .frm-filer) och data som skickas till klienten är inte krypterade.
- Endast MariaDB-servern vet hur man dekrypterar data, i synnerhet
- mysqlbinlog kan endast läsa krypterade binära loggar när --read-from-remote-server används.
- Percona XtraBackup kan inte säkerhetskopiera instanser som använder krypterad InnoDB. Mariabackup kan dock säkerhetskopiera krypterade instanser.
- Den diskbaserade Galera gcache är inte krypterad i communityversionen av MariaDB Server, men den här filen är krypterad i MariaDB Enterprise Server 10.4.
- Revisionsplugin kan inte skapa krypterad utdata. Skicka den till syslog och konfigurera skyddet där istället.
- Filbaserad allmän frågelogg och långsam frågelogg kan inte krypteras.
- Aria-loggen är inte krypterad. Detta påverkar endast icke-tillfälliga Aria-tabeller.
- MariaDB-felloggen är inte krypterad. Felloggen kan innehålla frågetext och data i vissa fall, inklusive krascher, påståendefel och fall där InnoDB/XtraDB skriver monitorutdata till loggen för att underlätta felsökning. Det kan också skickas till syslog om det behövs.
Slutsats
Att skydda data under transport är lika viktigt som att skydda data-at-rest, och även om det inte är ett måste i din organisation bör du överväga att tillämpa det eftersom det kan hjälpa dig att undvika data stöld eller obehörig åtkomst.
MariaDB har ett ganska enkelt sätt att implementera det genom att följa stegen som nämnts tidigare, men det är säkert ännu enklare att använda ClusterControl.