sql >> Databasteknik >  >> RDS >> MariaDB

Fullständig MariaDB-kryptering i vila och under transport för maximalt dataskydd - del två

I den första delen av den här serien har vi täckt in-transit krypteringskonfiguration för MariaDB-replikeringsservrar, där vi konfigurerade klient-server- och replikeringskrypteringar. Taget från det första inlägget, där vi delvis hade konfigurerat vår fullständiga kryptering (som indikeras av de gröna pilarna till vänster i diagrammet) och i det här blogginlägget, kommer vi att slutföra krypteringsinställningen med at-rest-kryptering för att skapa en helt krypterad MariaDB-replikeringsinställning.

Följande diagram illustrerar vår nuvarande installation och den slutliga installationen som vi kommer att uppnå:

Kryptering i viloläge

Kryptering i vila innebär att data i vila som datafiler och loggar är krypterade på disken, vilket gör det nästan omöjligt för någon att komma åt eller stjäla en hårddisk och få tillgång till originaldata (förutsatt att nyckeln är säkrad och inte lagras lokalt). Data-at-rest-kryptering, även känd som Transparent Data Encryption (TDE), stöds i MariaDB 10.1 och senare. Observera att användning av kryptering har en omkostnad på ungefär 5-10 %, beroende på arbetsbelastning och klustertyp.

För MariaDB kan följande MariaDB-komponenter krypteras i vila:

  • InnoDB-datafil (delat tabellutrymme eller individuellt tabellutrymme, t.ex. *.ibd och ibdata1)
  • Aria-data och indexfiler.
  • Ångra/gör om loggar (InnoDB-loggfiler, t.ex. ib_logfile0 och ib_logfile1).
  • Binära/reläloggar.
  • Tillfälliga filer och tabeller.

Följande filer kan inte krypteras för tillfället:

  • Metadatafil (till exempel .frm-filer).
  • Filbaserad allmän logg/långsam frågelogg. Tabellbaserad allmän logg/långsam frågelogg kan krypteras.
  • Fellogg.

MariaDBs data-at-rest-kryptering kräver användning av nyckelhantering och krypteringsplugin. I det här blogginlägget kommer vi att använda File Key Management Encryption Plugin, som tillhandahålls som standard sedan MariaDB 10.1.3. Observera att det finns ett antal nackdelar med detta plugin, t.ex. kan nyckeln fortfarande läsas av root- och MySQL-användare, som förklaras på MariaDB Data-at-Rest Encryption-sidan.

Genererar nyckelfil

Låt oss skapa en dedikerad katalog för att lagra våra lediga krypteringssaker:

$ mkdir -p /etc/mysql/rest
$ cd /etc/mysql/rest

Skapa en nyckelfil. Detta är kärnan i krypteringen:

$ openssl rand -hex 32 > /etc/mysql/rest/keyfile

Lägg till en sträng "1;" som nyckelidentifierare i nyckelfilen:

$ echo '1;' 
sed -i '1s/^/1;/' /etc/mysql/rest/keyfile

Därför, när du läser nyckelfilen, bör den se ut ungefär så här:

$ cat /etc/mysql/rest/keyfile
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

Ovanstående betyder helt enkelt för nyckelidentifierare 1, nyckeln är 4eb... Nyckelfilen måste innehålla två delar av information för varje krypteringsnyckel. Först måste varje krypteringsnyckel identifieras med ett 32-bitars heltal som nyckelidentifierare. För det andra måste själva krypteringsnyckeln tillhandahållas i hex-kodad form. Dessa två informationsdelar måste separeras med semikolon.

Skapa ett lösenord för att kryptera nyckeln ovan. Här ska vi lagra lösenordet i en fil som heter "keyfile.passwd":

$ echo -n 'mySuperStrongPassword' > /etc/mysql/rest/keyfile.passwd

Du kan hoppa över steget ovan om du vill ange lösenordet direkt i konfigurationsfilen med alternativet file_key_management_filekey. Till exempel:file_key_management_filekey=mySuperStrongPassword

Men i det här exemplet kommer vi att läsa lösenordet som är lagrat i en fil, så vi måste definiera följande rad i konfigurationsfilen senare: 

file_key_management_filekey=FILE:/etc/mysql/encryption/keyfile.passwd

Vi kommer att kryptera nyckelfilen för klartext till en annan fil som heter keyfile.enc, med lösenord i lösenordsfilen:

$  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

När vi listar katalogen bör vi se dessa tre filer:

$ ls -1 /etc/mysql/rest/
keyfile
keyfile.enc
keyfile.passwd

Innehållet i nyckelfil.enc är helt enkelt en krypterad version av nyckelfil:

För att testa kan vi dekryptera den krypterade filen med OpenSSL genom att tillhandahålla lösenordsfil (keyfile.passwd):

$ openssl aes-256-cbc -d -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile.enc
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

Vi kan sedan ta bort den vanliga nyckeln eftersom vi kommer att använda den krypterade (.enc) tillsammans med lösenordsfilen:

$ rm -f /etc/mysql/encryption/keyfile

Vi kan nu fortsätta att konfigurera MariaDB at-rest-kryptering.

Konfigurera At-Rest Encryption

Vi måste flytta den krypterade nyckelfilen och lösenordet till slavarna som ska användas av MariaDB för att kryptera/dekryptera data. Annars skulle en krypterad tabell som säkerhetskopieras från mastern med hjälp av fysisk säkerhetskopiering som MariaDB Backup få problem att läsa av slavarna (på grund av olika nyckel-/lösenordskombinationer). Logisk säkerhetskopiering som mysqldump bör fungera med olika nycklar och lösenord.

Skapa en katalog på slavarna för att lagra krypteringsgrejer i vila:

(slave1)$ mkdir -p /etc/mysql/rest
(slave2)$ mkdir -p /etc/mysql/rest

På mastern, kopiera den krypterade nyckelfilen och lösenordsfilen till de andra slavarna:

(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/

Skydda filerna från global åtkomst och tilldela "mysql"-användare som ägande:

$ chown mysql:mysql /etc/mysql/rest/*
$ chmod 600 /etc/mysql/rest/*

Lägg till följande i MariaDB-konfigurationsfilen under avsnittet [mysqld] eller [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

Observera variabeln file_key_management_filekey, om lösenordet finns i en fil måste du prefixet sökvägen med "FILE:". Alternativt kan du också ange lösenordssträngen direkt (rekommenderas inte på grund av dess omfattande): 

file_key_management_filekey=mySuperStrongPassword

Starta om MariaDB-servern en nod i taget, med början med slavarna:

(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb

Observera felloggen och se till att MariaDB-kryptering är aktiverad under uppstart:

$ 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
...

Du bör se rader som indikerar krypteringsinitiering i felloggen. Vid det här laget är majoriteten av krypteringskonfigurationen nu klar.

Testa din kryptering

Skapa en testdatabas för att testa på mastern:

(master)MariaDB> CREATE SCHEMA sbtest;
(master)MariaDB> USE sbtest;

Skapa en standardtabell utan kryptering och infoga en rad:

MariaDB> CREATE TABLE tbl_plain (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
MariaDB> INSERT INTO tbl_plain SET data = 'test data';

Vi kan se lagrad data i klartext när vi bläddrar i InnoDB-datafilen med ett hexdumpverktyg:

$ 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  ................

Skapa en krypterad tabell och infoga en rad:

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';

Vi kan inte avgöra vad som lagras i InnoDB-datafilen för krypterade tabeller:

$ 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(....#......

Observera att metadatafilen tbl_enc.frm inte är krypterad i vila. Endast InnoDB-datafilen (.ibd) är krypterad.

När vi jämför de "vanliga" binära eller reläloggarna kan vi tydligt se innehållet i det med hjälp av hexdump-verktyget:

$ 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

Medan för en krypterad binär logg ser innehållet ut att vara konstigt:

$ 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...

Kryptera Aria-tabeller

För Aria-lagringsmotorn stöder den inte alternativet ENCRYPTED i CREATE/ALTER-satsen eftersom det följer det globala alternativet aria_encrypt_tables. Därför, när du skapar en Aria-tabell, skapa helt enkelt tabellen med ENGINE=Aria-alternativet:

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;

Vi kan sedan verifiera innehållet i tabellens datafil (tbl_aria_enc.MAD) eller indexfil (tbl_aria_enc.MAI) med hexdump-verktyget. För att kryptera en befintlig Aria-tabell måste tabellen byggas om:

MariaDB> ALTER TABLE db.aria_table ENGINE=Aria ROW_FORMAT=PAGE;

Denna sats får Aria att bygga om tabellen med hjälp av tabellalternativet ROW_FORMAT. I processen, med den nya standardinställningen, krypterar den tabellen när den skriver till disken.

Kryptering av allmän logg/långsam frågelogg

För att kryptera allmänna och långsamma frågeloggar kan vi ställa in MariaDB log_output alternativet till 'TABELL' istället för standardvärdet 'FILE':

MariaDB> SET GLOBAL log_ouput = 'TABLE';

Men MariaDB kommer som standard att skapa de nödvändiga tabellerna med hjälp av CSV-lagringsmotorn, som inte är krypterad av MariaDB. Inga andra motorer än CSV, MyISAM eller Aria är lagliga för loggtabellerna. Tricket är att bygga om standard CSV-tabellen med Aria-lagringsmotorn, förutsatt att alternativet aria_encrypt_tables är inställt på PÅ. Däremot måste respektive loggalternativ stängas av för att tabelländringen ska lyckas.

Därför är stegen för att kryptera den allmänna loggtabellen:

MariaDB> SET GLOBAL general_log = OFF;
MariaDB> ALTER TABLE mysql.general_log ENGINE=Aria;
MariaDB> SET GLOBAL general_log = ON;

På liknande sätt, för långsam frågelogg:

MariaDB> SET GLOBAL slow_query_log = OFF;
MariaDB> ALTER TABLE mysql.slow_log ENGINE=Aria;
MariaDB> SET GLOBAL slow_query_log = ON;

Verifiera utdata från allmänna loggar på servern:

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    |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+

Som det krypterade innehållet i Aria-datafilen i datakatalogen med hjälp av hexdump-verktyget:

$ 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-kryptering är nu klar. Kombinera detta med in-transit kryptering som vi gjorde i det första inlägget, vår slutliga arkitektur ser nu ut så här:

Slutsats

Det är nu möjligt att helt säkra dina MariaDB-databaser via kryptering för skydd mot fysiska och virtuella intrång eller stöld. ClusterControl kan hjälpa dig att upprätthålla den här typen av säkerhet också och du kan ladda ner den gratis här.


  1. uppdateringsfråga med join på två tabeller

  2. Aktivera virtualisering i BIOS i bärbar dator eller stationär dator för Virtualbox VM

  3. SQLite-gräns

  4. Kontrollera om en Postgres JSON-array innehåller en sträng