In het eerste deel van deze serie hebben we de coderingsconfiguratie tijdens het transport voor MariaDB-replicatieservers behandeld, waarbij we client-server- en replicatiecoderingen hebben geconfigureerd. Genomen uit de eerste post, waar we onze volledige codering gedeeltelijk hadden geconfigureerd (zoals aangegeven door de groene pijlen aan de linkerkant in het diagram) en in deze blogpost gaan we de coderingsconfiguratie voltooien met at-rest-codering om een volledig versleutelde MariaDB-replicatie-installatie.
Het volgende diagram illustreert onze huidige opstelling en de uiteindelijke opstelling die we gaan bereiken:
Versleuteling in rust
At-rest-codering betekent dat de data-at-rest zoals databestanden en logs op de schijf worden versleuteld, waardoor het bijna onmogelijk wordt voor iemand om toegang te krijgen tot een harde schijf of deze te stelen en toegang te krijgen tot de originele gegevens (mits de sleutel beveiligd is en niet lokaal opgeslagen). Data-at-rest-encryptie, ook bekend als Transparent Data Encryption (TDE), wordt ondersteund in MariaDB 10.1 en hoger. Houd er rekening mee dat het gebruik van codering een overhead heeft van ongeveer 5-10%, afhankelijk van de werkbelasting en het clustertype.
Voor MariaDB kunnen de volgende MariaDB-componenten in rust worden versleuteld:
- InnoDB-gegevensbestand (gedeelde tabelruimte of individuele tabelruimte, bijv. *.ibd en ibdata1)
- Aria-gegevens en indexbestanden.
- Logboeken ongedaan maken/opnieuw doen (InnoDB-logbestanden, bijv. ib_logfile0 en ib_logfile1).
- Binaire/relay-logboeken.
- Tijdelijke bestanden en tabellen.
De volgende bestanden kunnen momenteel niet worden versleuteld:
- Metadatabestand (bijvoorbeeld .frm-bestanden).
- Op bestanden gebaseerd algemeen logboek/langzaam querylogboek. Op tabellen gebaseerd algemeen logboek/log met trage zoekopdrachten kan worden versleuteld.
- Foutenlogboek.
MariaDB's data-at-rest-codering vereist het gebruik van sleutelbeheer en coderingsplug-ins. In deze blogpost gaan we de File Key Management Encryption Plugin gebruiken, die standaard wordt geleverd sinds MariaDB 10.1.3. Merk op dat er een aantal nadelen zijn aan het gebruik van deze plug-in, de sleutel kan bijvoorbeeld nog steeds worden gelezen door root en MySQL-gebruiker, zoals uitgelegd op de MariaDB Data-at-Rest Encryption-pagina.
Sleutelbestand genereren
Laten we een speciale map maken om onze at-rest encryptie-dingen op te slaan:
$ mkdir -p /etc/mysql/rest
$ cd /etc/mysql/rest
Maak een sleutelbestand. Dit is de kern van codering:
$ openssl rand -hex 32 > /etc/mysql/rest/keyfile
Voeg een tekenreeks "1;" toe als de sleutel-ID in het sleutelbestand:
$ echo '1;'
sed -i '1s/^/1;/' /etc/mysql/rest/keyfile
Dus, bij het lezen van het sleutelbestand, zou het er ongeveer zo uit moeten zien:
$ cat /etc/mysql/rest/keyfile
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7
Het bovenstaande betekent eenvoudigweg voor sleutelidentificatie 1, de sleutel is 4eb... Het sleutelbestand moet twee stukjes informatie bevatten voor elke coderingssleutel. Ten eerste moet elke coderingssleutel worden geïdentificeerd met een 32-bits geheel getal als sleutel-ID. Ten tweede moet de coderingssleutel zelf in hex-gecodeerde vorm worden verstrekt. Deze twee stukjes informatie moeten worden gescheiden door een puntkomma.
Maak een wachtwoord om de bovenstaande sleutel te coderen. Hier gaan we het wachtwoord opslaan in een bestand met de naam "keyfile.passwd":
$ echo -n 'mySuperStrongPassword' > /etc/mysql/rest/keyfile.passwd
U kunt de bovenstaande stap overslaan als u het wachtwoord rechtstreeks in het configuratiebestand wilt opgeven met de optie file_key_management_filekey. Bijvoorbeeld:file_key_management_filekey=mySuperStrongPassword
Maar in dit voorbeeld gaan we het wachtwoord lezen dat in een bestand is opgeslagen, dus moeten we later de volgende regel in het configuratiebestand definiëren:
file_key_management_filekey=FILE:/etc/mysql/encryption/keyfile.passwd
We gaan het leesbare sleutelbestand versleutelen naar een ander bestand genaamd keyfile.enc, met een wachtwoord in het wachtwoordbestand:
$ openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile -out /etc/mysql/rest/keyfile.enc
Als we de directory opsommen, zouden we deze 3 bestanden moeten zien:
$ ls -1 /etc/mysql/rest/
keyfile
keyfile.enc
keyfile.passwd
De inhoud van keyfile.enc is gewoon een versleutelde versie van keyfile:
Als test kunnen we het versleutelde bestand ontsleutelen met OpenSSL door de wachtwoordbestand (keyfile.passwd):
$ openssl aes-256-cbc -d -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile.enc
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7
We kunnen dan de gewone sleutel verwijderen omdat we de versleutelde (.enc) samen met het wachtwoordbestand gaan gebruiken:
$ rm -f /etc/mysql/encryption/keyfile
We kunnen nu doorgaan met het configureren van MariaDB at-rest encryptie.
At-Rest-codering configureren
We moeten het gecodeerde sleutelbestand en wachtwoord naar de slaves verplaatsen die door MariaDB moeten worden gebruikt om de gegevens te coderen/decoderen. Anders zou een gecodeerde tabel waarvan een back-up wordt gemaakt van de master met behulp van fysieke back-up zoals MariaDB Backup, een probleem hebben om te lezen door de slaven (vanwege een verschillende sleutel-/wachtwoordcombinatie). Logische back-up zoals mysqldump zou moeten werken met verschillende sleutels en wachtwoorden.
Maak op de slaves een map aan om de coderingsspullen in rust op te slaan:
(slave1)$ mkdir -p /etc/mysql/rest
(slave2)$ mkdir -p /etc/mysql/rest
Kopieer op de master het versleutelde sleutelbestand en het wachtwoordbestand naar de andere slaves:
(master)$ cd /etc/mysql/rest
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/
Bescherm de bestanden tegen globale toegang en wijs de gebruiker "mysql" toe als eigendom:
$ chown mysql:mysql /etc/mysql/rest/*
$ chmod 600 /etc/mysql/rest/*
Voeg het volgende toe aan het MariaDB-configuratiebestand onder de sectie [mysqld] of [mariadb]:
# at-rest encryption
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/rest/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/rest/keyfile.passwd
file_key_management_encryption_algorithm = AES_CBC
innodb_encrypt_tables = ON
innodb_encrypt_temporary_tables = ON
innodb_encrypt_log = ON
innodb_encryption_threads = 4
innodb_encryption_rotate_key_age = 1
encrypt-tmp-disk-tables = 1
encrypt-tmp-files = 1
encrypt-binlog = 1
aria_encrypt_tables = ON
Let op de variabele file_key_management_filekey, als het wachtwoord in een bestand staat, moet u het pad voorafgaan door "FILE:". U kunt ook de wachtwoordreeks rechtstreeks opgeven (niet aanbevolen vanwege de breedsprakigheid):
file_key_management_filekey=mySuperStrongPassword
Herstart MariaDB-server één knooppunt tegelijk, te beginnen met de slaves:
(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb
Let op het foutenlogboek en zorg ervoor dat MariaDB-codering is geactiveerd tijdens het opstarten:
$ tail -f /var/log/mysql/mysqld.log
...
2019-12-17 6:44:47 0 [Note] InnoDB: Encrypting redo log: 2*67108864 bytes; LSN=143311
2019-12-17 6:44:48 0 [Note] InnoDB: Starting to delete and rewrite log files.
2019-12-17 6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 67108864 bytes
2019-12-17 6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 67108864 bytes
2019-12-17 6:44:48 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2019-12-17 6:44:48 0 [Note] InnoDB: New log files created, LSN=143311
2019-12-17 6:44:48 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2019-12-17 6:44:48 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2019-12-17 6:44:48 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2019-12-17 6:44:48 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2019-12-17 6:44:48 0 [Note] InnoDB: Waiting for purge to start
2019-12-17 6:44:48 0 [Note] InnoDB: 10.4.11 started; log sequence number 143311; transaction id 222
2019-12-17 6:44:48 0 [Note] InnoDB: Creating #1 encryption thread id 139790011840256 total threads 4.
2019-12-17 6:44:48 0 [Note] InnoDB: Creating #2 encryption thread id 139790003447552 total threads 4.
2019-12-17 6:44:48 0 [Note] InnoDB: Creating #3 encryption thread id 139789995054848 total threads 4.
2019-12-17 6:44:48 0 [Note] InnoDB: Creating #4 encryption thread id 139789709866752 total threads 4.
2019-12-17 6:44:48 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2019-12-17 6:44:48 0 [Note] Plugin 'FEEDBACK' is disabled.
2019-12-17 6:44:48 0 [Note] Using encryption key id 1 for temporary files
...
Je zou regels moeten zien die de initialisatie van de versleuteling in het foutenlogboek aangeven. Op dit punt is het grootste deel van de coderingsconfiguratie nu voltooid.
Uw versleuteling testen
Maak een testdatabase om op de master te testen:
(master)MariaDB> CREATE SCHEMA sbtest;
(master)MariaDB> USE sbtest;
Maak een standaardtabel zonder codering en voeg een rij in:
MariaDB> CREATE TABLE tbl_plain (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
MariaDB> INSERT INTO tbl_plain SET data = 'test data';
We kunnen de opgeslagen gegevens in leesbare tekst zien wanneer we door het InnoDB-gegevensbestand bladeren met behulp van een hexdump-tool:
$ xxd /var/lib/mysql/sbtest/tbl_plain.ibd | less
000c060: 0200 1c69 6e66 696d 756d 0002 000b 0000 ...infimum......
000c070: 7375 7072 656d 756d 0900 0000 10ff f180 supremum........
000c080: 0000 0100 0000 0000 0080 0000 0000 0000 ................
000c090: 7465 7374 2064 6174 6100 0000 0000 0000 test data.......
000c0a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
Maak een versleutelde tabel en voeg een rij in:
MariaDB> CREATE TABLE tbl_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENCRYPTED=YES;
MariaDB> INSERT INTO tbl_enc SET data = 'test data';
We kunnen niet zeggen wat er is opgeslagen in het InnoDB-gegevensbestand voor versleutelde tabellen:
$ xxd /var/lib/mysql/sbtest/tbl_enc.ibd | less
000c060: 0c2c 93e4 652e 9736 e68a 8b69 39cb 6157 .,..e..6...i9.aW
000c070: 3cd1 581c 7eb9 84ca d792 7338 521f 0639 <.X.~.....s8R..9
000c080: d279 9eb3 d3f5 f9b0 eccb ed05 de16 f3ac .y..............
000c090: 6d58 5519 f776 8577 03a4 fa88 c507 1b31 mXU..v.w.......1
000c0a0: a06f 086f 28d9 ac17 8923 9412 d8a5 1215 .o.o(....#......
Houd er rekening mee dat het metadatabestand tbl_enc.frm in rust niet versleuteld is. Alleen het InnoDB-gegevensbestand (.ibd) is versleuteld.
Wanneer we de "gewone" binaire of relaislogboeken vergelijken, kunnen we de inhoud ervan duidelijk zien met behulp van de hexdump-tool:
$ xxd binlog.000002 | less
0000560: 0800 0800 0800 0b04 726f 6f74 096c 6f63 ........root.loc
0000570: 616c 686f 7374 0047 5241 4e54 2052 454c alhost.GRANT REL
0000580: 4f41 442c 4c4f 434b 2054 4142 4c45 532c OAD,LOCK TABLES,
0000590: 5245 504c 4943 4154 494f 4e20 434c 4945 REPLICATION CLIE
00005a0: 4e54 2c45 5645 4e54 2c43 5245 4154 4520 NT,EVENT,CREATE
00005b0: 5441 424c 4553 5041 4345 2c50 524f 4345 TABLESPACE,PROCE
00005c0: 5353 2c43 5245 4154 452c 494e 5345 5254 SS,CREATE,INSERT
00005d0: 2c53 454c 4543 542c 5355 5045 522c 5348 ,SELECT,SUPER,SH
00005e0: 4f57 2056 4945 5720 4f4e 202a 2e2a 2054 OW VIEW ON *.* T
Voor een versleuteld binair logboek ziet de inhoud er wartaal uit:
$ xxd binlog.000004 | less
0000280: 4a1d 1ced 2f1b db50 016a e1e9 1351 84ba J.../..P.j...Q..
0000290: 38b6 72e7 8743 7713 afc3 eecb c36c 1b19 8.r..Cw......l..
00002a0: 7b3f 6176 208f 0000 00dc 85bf 6768 e7c6 {?av .......gh..
00002b0: 6107 5bea 241c db12 d50c 3573 48e5 3c3d a.[.$.....5sH.<=
00002c0: 3179 1653 2449 d408 1113 3e25 d165 c95b 1y.S$I....>%.e.[
00002d0: afb0 6778 4b26 f672 1bc7 567e da96 13f5 ..gxK&.r..V~....
00002e0: 2ac5 b026 3fb9 4b7a 3ef4 ab47 6c9f a686 *..&?.Kz>..Gl...
Aria-tabellen versleutelen
Voor de Aria-opslagengine ondersteunt deze de ENCRYPTED-optie in de CREATE/ALTER-instructie niet, omdat deze de algemene optie aria_encrypt_tables volgt. Daarom, wanneer u een Aria-tabel maakt, maakt u de tabel eenvoudig met de optie ENGINE=Aria:
MariaDB> CREATE TABLE tbl_aria_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENGINE=Aria;
MariaDB> INSERT INTO tbl_aria_enc(data) VALUES ('test data');
MariaDB> FLUSH TABLE tbl_aria_enc;
We kunnen dan de inhoud van het gegevensbestand van de tabel (tbl_aria_enc.MAD) of indexbestand (tbl_aria_enc.MAI) verifiëren met de hexdump-tool. Om een bestaande Aria-tafel te versleutelen, moet de tafel opnieuw worden opgebouwd:
MariaDB> ALTER TABLE db.aria_table ENGINE=Aria ROW_FORMAT=PAGE;
Deze instructie zorgt ervoor dat Aria de tabel opnieuw opbouwt met behulp van de ROW_FORMAT tabeloptie. In het proces, met de nieuwe standaardinstelling, versleutelt het de tabel wanneer het naar schijf schrijft.
Algemeen log/slow query log versleutelen
Om algemene en langzame querylogboeken te coderen, kunnen we de MariaDB log_output-optie instellen op 'TABLE' in plaats van de standaard 'FILE':
MariaDB> SET GLOBAL log_ouput = 'TABLE';
MariaDB maakt echter standaard de benodigde tabellen met behulp van de CSV-opslagengine, die niet is versleuteld door MariaDB. Geen andere engine dan CSV, MyISAM of Aria zijn legaal voor de logtabellen. De truc is om de standaard CSV-tabel opnieuw op te bouwen met de Aria-opslagengine, op voorwaarde dat de optie aria_encrypt_tables is ingesteld op AAN. De respectievelijke logoptie moet echter uitgeschakeld zijn om de tabelwijziging te laten slagen.
De stappen voor het versleutelen van de algemene logtabel zijn dus:
MariaDB> SET GLOBAL general_log = OFF;
MariaDB> ALTER TABLE mysql.general_log ENGINE=Aria;
MariaDB> SET GLOBAL general_log = ON;
Evenzo, voor langzame querylog:
MariaDB> SET GLOBAL slow_query_log = OFF;
MariaDB> ALTER TABLE mysql.slow_log ENGINE=Aria;
MariaDB> SET GLOBAL slow_query_log = ON;
Verifieer de uitvoer van algemene logs binnen de server:
MariaDB> SELECT * FROM mysql.general_log;
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| event_time | user_host | thread_id | server_id | command_type | argument |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| 2019-12-17 07:45:53.109558 | root[root] @ localhost [] | 19 | 28001 | Query | select * from sbtest.tbl_enc |
| 2019-12-17 07:45:55.504710 | root[root] @ localhost [] | 20 | 28001 | Query | select * from general_log |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
Alsook de versleutelde inhoud van het Aria-gegevensbestand in de gegevensmap met behulp van de hexdump-tool:
$ xxd /var/lib/mysql/mysql/general_log.MAD | less
0002040: 1d45 820d 7c53 216c 3fc6 98a6 356e 1b9e .E..|S!l?...5n..
0002050: 6bfc e193 7509 1fa7 31e2 e22a 8f06 3c6f k...u...1..*..<o
0002060: ae71 bb63 e81b 0b08 7120 0c99 9f82 7c33 .q.c....q ....|3
0002070: 1117 bc02 30c1 d9a7 c732 c75f 32a6 e238 ....0....2._2..8
0002080: d1c8 5d6f 9a08 455a 8363 b4f4 5176 f8a1 ..]o..EZ.c..Qv..
0002090: 1bf8 113c 9762 3504 737e 917b f260 f88c ...<.b5.s~.{.`..
00020a0: 368e 336f 9055 f645 b636 c5c1 debe fbe7 6.3o.U.E.6......
00020b0: d01e 028f 8b75 b368 0ef0 8889 bb63 e032 .....u.h.....c.2
MariaDB at-rest-versleuteling is nu voltooid. Combineer dit met in-transit-codering die we in de eerste post hebben gedaan, onze uiteindelijke architectuur ziet er nu als volgt uit:
Conclusie
Het is nu mogelijk om uw MariaDB-databases volledig te beveiligen via encryptie voor bescherming tegen fysieke en virtuele inbreuken of diefstal. ClusterControl kan u ook helpen bij het onderhouden van dit type beveiliging en u kunt het hier gratis downloaden.