Šifrování je jednou z nejdůležitějších funkcí zabezpečení, aby byla vaše data co nejbezpečnější. V závislosti na datech, se kterými nakládáte, to není vždy nutností, ale každopádně byste to měli považovat přinejmenším za zlepšení zabezpečení ve vaší organizaci a ve skutečnosti se doporučuje vyhnout se krádeži dat nebo neoprávněnému přístupu.
V tomto blogu popíšeme dva základní typy šifrování a jak jej nakonfigurovat na serveru MariaDB.
Co je šifrování dat?
Existují dva základní typy šifrování dat:v klidu a při přenosu. Podívejme se, co znamenají.
Šifrování dat v klidu
Data uložená v systému jsou známá jako data v klidu. Šifrování těchto dat spočívá v použití algoritmu pro převod textu nebo kódu na nečitelný. K dekódování zašifrovaných dat musíte mít šifrovací klíč.
Šifrování celé databáze by mělo být prováděno opatrně, protože může mít vážný dopad na výkon. Je proto rozumné šifrovat pouze jednotlivá pole nebo tabulky.
Šifrování dat v klidu chrání data před fyzickou krádeží pevných disků nebo neoprávněným přístupem k úložišti souborů. Toto šifrování také vyhovuje předpisům o zabezpečení dat, zejména pokud jsou v souborovém systému uložena finanční nebo zdravotní data.
Šifrování přenosu dat
Přenášená data nebo jejich pohyb mezi transakcemi se nazývá přenos dat. Data pohybující se mezi serverem a klientem při procházení webových stránek jsou dobrým příkladem tohoto druhu dat.
Vzhledem k tomu, že je neustále v pohybu, musí být chráněna správným šifrováním, aby se předešlo krádeži nebo pozměnění dat, než se dostanou na místo určení.
Ideální situací pro ochranu přenášených dat je nechat data před přesunem zašifrovat a dešifrovat je až po dosažení konečného cíle.
Šifrování MariaDB Data-at-Rest
Šifrování tabulek a tabulkových prostorů bylo přidáno do MariaDB od verze 10.1 a podporuje šifrování pro úložiště XtraDB, InnoDB a Aria a také pro binární protokoly.
Můžete si vybrat různé způsoby šifrování:
- Všechny tabulky
- Jednotlivé tabulky
- Vše, kromě jednotlivých tabulek
Podle dokumentace má použití šifrování režii zhruba 3–5 %, takže je důležité mít testovací prostředí, které to zatíží a uvidí, jak reaguje, aby se předešlo problémům ve výrobě.
Jak nakonfigurovat šifrování Data-at-Rest na MariaDB
Podívejme se na existující tabulku „města“ v databázi MariaDB:
$ strings city.ibd |head
infimum
supremum
infimum
supremum
3ABW
3KHM
infimum
supremum
Kabul AFGKabol
Qandahar AFGQandahar
Jak vidíte, můžete odtud bez problémů číst data například pomocí příkazu strings Linux. Nyní se podívejme, jak jej zašifrovat.
Vygenerujte šifrovací klíče pomocí příkazu openssl rand:
$ mkdir -p /etc/mysql/encryption
$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile; done;
Upravte vygenerovaný soubor /etc/mysql/encryption/keyfile a přidejte ID klíčů, na která se bude odkazovat při vytváření šifrovaných tabulek. Formát by měl být následující:
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>
Můžete jej upravit pomocí příkazu sed linux takto:
$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done
Soubor by tedy měl být něco takového:
$ cat /etc/mysql/encryption/keyfile
1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af
2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5
3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169
4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab
Nyní vygenerujte náhodné heslo pomocí podobného příkazu openssl, který jste viděli dříve:
$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
Než přistoupíte k dalšímu kroku, je důležité znát následující podrobnosti o šifrování souboru klíče:
- Jediný algoritmus, který MariaDB v současnosti podporuje pro šifrování souboru klíče, je režim Cipher Block Chaining (CBC) Advanced Encryption Standard (AES).
- Velikost šifrovacího klíče může být 128 bitů, 192 bitů nebo 256 bitů.
- Šifrovací klíč je vytvořen z hash SHA-1 šifrovacího hesla.
- Šifrovací heslo má maximální délku 256 znaků.
Nyní, chcete-li zašifrovat soubor klíče pomocí příkazu openssl enc, spusťte následující příkaz:
$ 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
Nakonec musíte do konfiguračního souboru my.cnf přidat následující parametry (umístěné v /etc/ na operačním systému RedHat nebo /etc/mysql/ na OS 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
…
A restartujte službu MariaDB, abyste provedli změny:
$ systemctl restart mariadb
V tuto chvíli je vše připraveno k použití funkce šifrování. Zašifrujme stejnou tabulku, kterou jsme si ukázali dříve, „město“. K tomu musíte použít příkaz ALTER TABLE, který nastaví parametr ENCRYPTED na YES:
MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;
Query OK, 0 rows affected (0.483 sec)
Records: 0 Duplicates: 0 Warnings: 0
Pokud se nyní pokusíte o přístup k tabulce přímo ze systému souborů, uvidíte něco takového:
$ strings city.ibd |head
PU%O
!ybN)b
9,{9WB4
T3uG:
?oiN
,35sz
8g)Q
o(o
q_A1
k=-w
Jak vidíte, tabulka je nečitelná. Můžete také zadat ID šifrovacího klíče přidáním parametru ENCRYPTION_KEY_ID =
Nové tabulky budou ve výchozím nastavení šifrovány, protože parametr innodb_encrypt_tables v konfiguračním souboru my.cnf nastavíme na hodnotu ON.
Šifrování přenosu dat MariaDB
MariaDB vám umožňuje šifrovat data při přenosu mezi serverem a klienty pomocí protokolu Transport Layer Security (TLS), dříve známého jako Secure Socket Layer nebo SSL.
Nejprve se musíte ujistit, že váš server MariaDB byl zkompilován s podporou TLS. Můžete to ověřit spuštěním následujícího příkazu 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)
A zkontrolujte, zda se právě nepoužívá pomocí příkazu 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)
Stav SSL můžete také ověřit pomocí příkazu 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
--------------
Jak nakonfigurovat šifrování přenosu dat na MariaDB
Pojďme vytvořit adresář certs pro uložení všech certifikátů:
$ mkdir -p /etc/mysql/certs
Nyní vygenerujeme certifikáty CA, které budou nakonfigurovány pro šifrování připojení:
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
Tento poslední příkaz vás požádá o vyplnění následujících informací:
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 []:
Nyní musíte vygenerovat certifikáty serveru:
$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
Tento příkaz vás požádá o vyplnění stejných informací jako předtím a o heslo k certifikátu.
$ 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
A nakonec musíte vygenerovat klientské certifikáty:
$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
Také budete požádáni o vyplnění informací a volitelného hesla certifikátu.
$ 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
Ujistěte se, že na každém certifikátu používáte jiný Common Name, jinak to nebude fungovat a obdržíte zprávu jako:
ERROR 2026 (HY000): SSL connection error: self signed certificate
V tuto chvíli budete mít něco takového:
$ 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
A certifikáty můžete ověřit pomocí následujícího příkazu:
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Nyní jej tedy nakonfigurujeme v konfiguračním souboru my.cnf (nachází se v /etc/ na operačním systému RedHat nebo /etc/mysql/ na OS 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
Ujistěte se, že jej přidáváte do odpovídající sekce (mysqld a client-mariadb).
Změňte vlastníka certifikátu a restartujte databázovou službu:
$ chown mysql.mysql /etc/mysql/certs/
$ systemctl restart mariadb
Pokud se poté podíváte na výstup ZOBRAZIT PROMĚNNÉ, měli byste mít toto:
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)
Nyní vytvoříme uživatele s parametrem VYŽADOVAT SSL, který jej bude používat:
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;
Query OK, 0 rows affected (0.005 sec)
Pokud tohoto uživatele použijete pro přístup k databázi a zkontrolujete příkaz status, uvidíte používané SSL:
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
--------------
Jak povolit šifrování SSL pomocí ClusterControl
Další způsob, a dokonce jednodušší způsob, jak povolit SSL ve vaší databázi MariaDB, je pomocí ClusterControl. Budeme předpokládat, že máte nainstalovaný ClusterControl a spravujete pomocí něj svou databázi MariaDB, takže přejděte na ClusterControl -> Vyberte svůj cluster MariaDB -> Zabezpečení -> Šifrování SSL -> Povolit.
A je to, ve své databázi MariaDB budete mít povoleno šifrování SSL bez ručního úkolu.
Omezení šifrování v klidu v MariaDB
Existují určitá omezení související s klidovým šifrováním MariaDB, která je třeba vzít v úvahu:
- Metadata (například soubory .frm) a data odeslaná klientovi nejsou šifrována.
- Pouze server MariaDB ví, jak dešifrovat data, zejména
- mysqlbinlog dokáže číst zašifrované binární protokoly pouze při použití --read-from-remote-server.
- Percona XtraBackup nemůže zálohovat instance, které používají šifrovaný InnoDB. Mariabackup však může zálohovat zašifrované instance.
- Disková mezipaměť Galera gcache není v komunitní verzi serveru MariaDB zašifrována, tento soubor je však zašifrován na serveru MariaDB Enterprise Server 10.4.
- Plugin Audit nemůže vytvořit šifrovaný výstup. Pošlete to na syslog a nakonfigurujte ochranu tam.
- Souborový obecný protokol dotazů a protokol pomalých dotazů nelze šifrovat.
- Protokol Aria není zašifrován. To se týká pouze nedočasných tabulek Aria.
- Protokol chyb MariaDB není zašifrován. Protokol chyb může v některých případech obsahovat text dotazu a data, včetně selhání, selhání výrazů a případů, kdy InnoDB/XtraDB zapisuje výstup monitoru do protokolu, aby se usnadnilo ladění. V případě potřeby jej lze také odeslat do syslogu.
Závěr
Ochrana přenášených dat je stejně důležitá jako ochrana dat v klidu, a i když to ve vaší organizaci není nutností, měli byste zvážit její použití, protože vám může pomoci vyhnout se datům krádež nebo neoprávněný přístup.
MariaDB má docela snadný způsob, jak jej implementovat podle výše uvedených kroků, ale určitě je ještě jednodušší použít ClusterControl.