Im ersten Teil dieser Serie haben wir die Verschlüsselungskonfiguration während der Übertragung für MariaDB-Replikationsserver behandelt, wo wir Client-Server- und Replikationsverschlüsselungen konfiguriert haben. Entnommen aus dem ersten Beitrag, in dem wir unsere vollständige Verschlüsselung teilweise konfiguriert hatten (wie durch die grünen Pfeile links im Diagramm angezeigt), und in diesem Blogbeitrag werden wir die Verschlüsselungseinrichtung mit ruhender Verschlüsselung abschließen, um eine zu erstellen vollständig verschlüsselte Einrichtung der MariaDB-Replikation.
Das folgende Diagramm veranschaulicht unser aktuelles Setup und das endgültige Setup, das wir erreichen werden:
Verschlüsselung im Ruhezustand
At-Rest-Verschlüsselung bedeutet, dass die Data-at-Rest wie Datendateien und Protokolle auf der Festplatte verschlüsselt sind, was es für jemanden fast unmöglich macht, auf eine Festplatte zuzugreifen oder sie zu stehlen und Zugriff auf die Originaldaten zu erhalten (vorausgesetzt, der Schlüssel ist gesichert und nicht lokal gespeichert). Data-at-Rest-Verschlüsselung, auch bekannt als Transparent Data Encryption (TDE), wird in MariaDB 10.1 und höher unterstützt. Beachten Sie, dass die Verwendung von Verschlüsselung je nach Arbeitslast und Clustertyp einen Overhead von etwa 5–10 % verursacht.
Für MariaDB können die folgenden MariaDB-Komponenten im Ruhezustand verschlüsselt werden:
- InnoDB-Datendatei (gemeinsam genutzter Tablespace oder individueller Tablespace, z. B. *.ibd und ibdata1)
- Aria-Daten und Indexdateien.
- Undo/Redo-Protokolle (InnoDB-Protokolldateien, z. B. ib_logfile0 und ib_logfile1).
- Binär-/Relay-Protokolle.
- Temporäre Dateien und Tabellen.
Folgende Dateien können derzeit nicht verschlüsselt werden:
- Metadatendatei (z. B. .frm-Dateien).
- Dateibasiertes allgemeines Protokoll/langsames Abfrageprotokoll. Tabellenbasiertes allgemeines Protokoll/langsames Abfrageprotokoll kann verschlüsselt werden.
- Fehlerprotokoll.
Die Data-at-Rest-Verschlüsselung von MariaDB erfordert die Verwendung von Schlüsselverwaltungs- und Verschlüsselungs-Plugins. In diesem Blogbeitrag verwenden wir das File Key Management Encryption Plugin, das seit MariaDB 10.1.3 standardmäßig bereitgestellt wird. Beachten Sie, dass es bei der Verwendung dieses Plugins eine Reihe von Nachteilen gibt, z. B. kann der Schlüssel immer noch von Root und MySQL-Benutzern gelesen werden, wie auf der MariaDB-Seite Data-at-Rest Encryption erklärt.
Schlüsseldatei wird generiert
Lassen Sie uns ein dediziertes Verzeichnis erstellen, um unser at-rest-Verschlüsselungsmaterial zu speichern:
$ mkdir -p /etc/mysql/rest
$ cd /etc/mysql/rest
Erstellen Sie eine Schlüsseldatei. Dies ist der Kern der Verschlüsselung:
$ openssl rand -hex 32 > /etc/mysql/rest/keyfile
Hängen Sie eine Zeichenfolge "1;" an als Schlüsselkennung in die Schlüsseldatei:
$ echo '1;'
sed -i '1s/^/1;/' /etc/mysql/rest/keyfile
Also sollte die Schlüsseldatei beim Lesen etwa so aussehen:
$ cat /etc/mysql/rest/keyfile
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7
Das obige bedeutet einfach für Schlüsselkennung 1, der Schlüssel ist 4eb... Die Schlüsseldatei muss zwei Informationen für jeden Verschlüsselungsschlüssel enthalten. Zunächst muss jeder Verschlüsselungsschlüssel mit einer 32-Bit-Ganzzahl als Schlüsselkennung identifiziert werden. Zweitens muss der Verschlüsselungsschlüssel selbst in Hex-codierter Form bereitgestellt werden. Diese beiden Informationen müssen durch ein Semikolon getrennt werden.
Erstellen Sie ein Passwort, um den obigen Schlüssel zu verschlüsseln. Hier speichern wir das Passwort in einer Datei namens "keyfile.passwd":
$ echo -n 'mySuperStrongPassword' > /etc/mysql/rest/keyfile.passwd
Sie können den obigen Schritt überspringen, wenn Sie das Passwort direkt in der Konfigurationsdatei mit der Option file_key_management_filekey angeben möchten. Beispiel:file_key_management_filekey=mySuperStrongPassword
Aber in diesem Beispiel lesen wir das Passwort, das in einer Datei gespeichert ist, daher müssen wir später die folgende Zeile in der Konfigurationsdatei definieren:
file_key_management_filekey=FILE:/etc/mysql/encryption/keyfile.passwd
Wir werden die Klartext-Schlüsseldatei in eine andere Datei namens keyfile.enc verschlüsseln, wobei wir das Passwort in der Passwortdatei verwenden:
$ 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
Wenn wir das Verzeichnis auflisten, sollten wir diese 3 Dateien sehen:
$ ls -1 /etc/mysql/rest/
keyfile
keyfile.enc
keyfile.passwd
Der Inhalt von keyfile.enc ist einfach eine verschlüsselte Version von keyfile:
Zum Testen können wir die verschlüsselte Datei mit OpenSSL entschlüsseln, indem wir die Passwortdatei (keyfile.passwd):
$ openssl aes-256-cbc -d -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile.enc
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7
Dann können wir den einfachen Schlüssel entfernen, da wir den verschlüsselten Schlüssel (.enc) zusammen mit der Passwortdatei verwenden werden:
$ rm -f /etc/mysql/encryption/keyfile
Wir können jetzt mit der Konfiguration der MariaDB-Verschlüsselung im Ruhezustand fortfahren.
Verschlüsselung im Ruhezustand konfigurieren
Wir müssen die verschlüsselte Schlüsseldatei und das Passwort auf die Slaves verschieben, die von MariaDB verwendet werden, um die Daten zu verschlüsseln/entschlüsseln. Andernfalls würde eine verschlüsselte Tabelle, die vom Master mit einem physischen Backup wie MariaDB Backup gesichert wird, Probleme haben, von den Slaves gelesen zu werden (aufgrund einer anderen Schlüssel-/Passwort-Kombination). Logische Backups wie mysqldump sollten mit anderen Schlüsseln und Passwörtern funktionieren.
Erstellen Sie auf den Slaves ein Verzeichnis, um Verschlüsselungsmaterial im Ruhezustand zu speichern:
(slave1)$ mkdir -p /etc/mysql/rest
(slave2)$ mkdir -p /etc/mysql/rest
Kopieren Sie auf dem Master die verschlüsselte Schlüsseldatei und die Passwortdatei auf die anderen 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/
Schützen Sie die Dateien vor globalem Zugriff und weisen Sie dem Benutzer "mysql" den Eigentümer zu:
$ chown mysql:mysql /etc/mysql/rest/*
$ chmod 600 /etc/mysql/rest/*
Fügen Sie Folgendes in die MariaDB-Konfigurationsdatei im Abschnitt [mysqld] oder [mariadb] ein:
# 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
Achten Sie auf die Variable file_key_management_filekey, wenn das Passwort in einer Datei steht, müssen Sie dem Pfad "FILE:" voranstellen. Alternativ können Sie die Passwortzeichenfolge auch direkt angeben (aufgrund ihrer Ausführlichkeit nicht empfohlen):
file_key_management_filekey=mySuperStrongPassword
Starten Sie den MariaDB-Server Knoten für Knoten neu, beginnend mit den Slaves:
(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb
Beachten Sie das Fehlerprotokoll und stellen Sie sicher, dass die MariaDB-Verschlüsselung beim Start aktiviert ist:
$ 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
...
Sie sollten im Fehlerprotokoll Zeilen sehen, die auf die Initialisierung der Verschlüsselung hinweisen. An diesem Punkt ist der Großteil der Verschlüsselungskonfiguration abgeschlossen.
Testen Sie Ihre Verschlüsselung
Erstellen Sie eine Testdatenbank zum Testen auf dem Master:
(master)MariaDB> CREATE SCHEMA sbtest;
(master)MariaDB> USE sbtest;
Erstelle eine Standardtabelle ohne Verschlüsselung und füge eine Zeile ein:
MariaDB> CREATE TABLE tbl_plain (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
MariaDB> INSERT INTO tbl_plain SET data = 'test data';
Wir können die gespeicherten Daten im Klartext sehen, wenn wir die InnoDB-Datendatei mit einem Hexdump-Tool durchsuchen:
$ 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 ................
Erstelle eine verschlüsselte Tabelle und füge eine Zeile ein:
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';
Wir können nicht sagen, was in der InnoDB-Datendatei für verschlüsselte Tabellen gespeichert ist:
$ 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(....#......
Beachten Sie, dass die Metadatendatei tbl_enc.frm im Ruhezustand nicht verschlüsselt ist. Nur die InnoDB-Datendatei (.ibd) wird verschlüsselt.
Beim Vergleich der "einfachen" Binär- oder Relaisprotokolle können wir den Inhalt mit dem Hexdump-Tool deutlich erkennen:
$ 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
Während bei einem verschlüsselten Binärlog der Inhalt Kauderwelsch aussieht:
$ 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 verschlüsseln
Für die Aria-Speicher-Engine wird die ENCRYPTED-Option in der CREATE/ALTER-Anweisung nicht unterstützt, da sie der globalen Option aria_encrypt_tables folgt. Erstellen Sie daher beim Erstellen einer Aria-Tabelle einfach die Tabelle mit der Option 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;
Wir können dann den Inhalt der Datendatei (tbl_aria_enc.MAD) oder der Indexdatei (tbl_aria_enc.MAI) der Tabelle mit dem Hexdump-Tool überprüfen. Um eine vorhandene Aria-Tabelle zu verschlüsseln, muss die Tabelle neu erstellt werden:
MariaDB> ALTER TABLE db.aria_table ENGINE=Aria ROW_FORMAT=PAGE;
Diese Anweisung bewirkt, dass Aria die Tabelle mit der Tabellenoption ROW_FORMAT neu erstellt. Dabei verschlüsselt er mit der neuen Voreinstellung die Tabelle beim Schreiben auf die Platte.
Verschlüsselndes allgemeines Protokoll/langsames Abfrageprotokoll
Um allgemeine und langsame Abfrageprotokolle zu verschlüsseln, können wir die Option MariaDB log_output auf 'TABLE' anstelle der Standardeinstellung 'FILE' setzen:
MariaDB> SET GLOBAL log_ouput = 'TABLE';
MariaDB erstellt jedoch standardmäßig die erforderlichen Tabellen mit der CSV-Speicher-Engine, die nicht von MariaDB verschlüsselt wird. Für die Protokolltabellen sind keine anderen Engines als CSV, MyISAM oder Aria zulässig. Der Trick besteht darin, die Standard-CSV-Tabelle mit der Aria-Speicher-Engine neu zu erstellen, vorausgesetzt, dass die Option aria_encrypt_tables auf ON gesetzt ist. Die entsprechende Protokolloption muss jedoch deaktiviert sein, damit die Tabellenänderung erfolgreich ist.
Die Schritte zum Verschlüsseln der allgemeinen Protokolltabelle sind also:
MariaDB> SET GLOBAL general_log = OFF;
MariaDB> ALTER TABLE mysql.general_log ENGINE=Aria;
MariaDB> SET GLOBAL general_log = ON;
Ähnlich für langsames Abfrageprotokoll:
MariaDB> SET GLOBAL slow_query_log = OFF;
MariaDB> ALTER TABLE mysql.slow_log ENGINE=Aria;
MariaDB> SET GLOBAL slow_query_log = ON;
Überprüfen Sie die Ausgabe allgemeiner Protokolle innerhalb des Servers:
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 |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
Sowie der verschlüsselte Inhalt der Aria-Datendatei im Datenverzeichnis mit dem 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-Verschlüsselung im Ruhezustand ist jetzt abgeschlossen. Kombinieren Sie dies mit der Verschlüsselung während der Übertragung, die wir im ersten Beitrag durchgeführt haben, unsere endgültige Architektur sieht nun so aus:
Fazit
Es ist jetzt möglich, Ihre MariaDB-Datenbanken durch Verschlüsselung vollständig zu sichern, um sie vor physischem und virtuellem Eindringen oder Diebstahl zu schützen. ClusterControl kann Ihnen auch dabei helfen, diese Art von Sicherheit aufrechtzuerhalten, und Sie können es hier kostenlos herunterladen.