MariaDB
 sql >> Baza danych >  >> RDS >> MariaDB

Pełne szyfrowanie MariaDB w spoczynku i podczas przesyłania w celu maksymalnej ochrony danych — część druga

W pierwszej części tej serii omówiliśmy konfigurację szyfrowania w tranzycie dla serwerów replikacji MariaDB, gdzie skonfigurowaliśmy szyfrowanie klient-serwer i replikację. Zaczerpnięte z pierwszego postu, w którym częściowo skonfigurowaliśmy nasze pełne szyfrowanie (jak wskazują zielone strzałki po lewej na diagramie) oraz w tym poście na blogu, zamierzamy zakończyć konfigurację szyfrowania za pomocą szyfrowania spoczynkowego, aby utworzyć w pełni zaszyfrowana konfiguracja replikacji MariaDB.

Poniższy diagram ilustruje naszą obecną konfigurację i ostateczną konfigurację, którą zamierzamy osiągnąć:

Szyfrowanie w spoczynku

Szyfrowanie w spoczynku oznacza, że ​​dane w spoczynku, takie jak pliki danych i logi, są szyfrowane na dysku, co sprawia, że ​​prawie niemożliwe jest uzyskanie przez kogoś dostępu lub kradzieży dysku twardego i uzyskanie dostępu do oryginalnych danych (pod warunkiem, że klucz jest zabezpieczony i nie jest przechowywany lokalnie). Szyfrowanie danych w spoczynku, znane również jako przezroczyste szyfrowanie danych (TDE), jest obsługiwane w MariaDB 10.1 i nowszych. Pamiętaj, że korzystanie z szyfrowania wiąże się z obciążeniem wynoszącym około 5-10%, w zależności od obciążenia i typu klastra.

W przypadku MariaDB następujące składniki MariaDB mogą być szyfrowane w stanie spoczynku:

  • Plik danych InnoDB (wspólny obszar tabel lub indywidualny obszar tabel, np. *.ibd i ibdata1)
  • Pliki danych i indeksów Aria.
  • Cofnij/powtórz logi (pliki dziennika InnoDB, np. ib_logfile0 i ib_logfile1).
  • Dzienniki binarne/przekaźnikowe.
  • Pliki i tabele tymczasowe.

Następujących plików nie można obecnie zaszyfrować:

  • Plik metadanych (na przykład pliki .frm).
  • Dziennik ogólny oparty na pliku/dziennik powolnych zapytań. Dziennik ogólny/dziennik powolnych zapytań oparty na tabeli może być szyfrowany.
  • Dziennik błędów.

Szyfrowanie danych w spoczynku MariaDB wymaga użycia wtyczek do zarządzania kluczami i szyfrowania. W tym poście na blogu użyjemy wtyczki szyfrowania zarządzania kluczami plików, która jest domyślnie dostarczana od wersji MariaDB 10.1.3. Zauważ, że korzystanie z tej wtyczki ma wiele wad, np. klucz może nadal być odczytywany przez roota i użytkownika MySQL, jak wyjaśniono na stronie MariaDB Data-at-Rest Encryption.

Generowanie pliku klucza

Stwórzmy dedykowany katalog do przechowywania naszych funkcji szyfrowania w spoczynku:

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

Utwórz plik klucza. To jest rdzeń szyfrowania:

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

Dołącz ciąg "1;" jako identyfikator klucza do pliku klucza:

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

Tak więc podczas czytania pliku klucza powinien on wyglądać mniej więcej tak:

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

Powyższe oznacza po prostu dla identyfikatora klucza 1, kluczem jest 4eb... Plik klucza musi zawierać dwie informacje dla każdego klucza szyfrowania. Po pierwsze, każdy klucz szyfrowania musi być identyfikowany za pomocą 32-bitowej liczby całkowitej jako identyfikatora klucza. Po drugie, sam klucz szyfrowania musi być dostarczony w postaci zakodowanej szesnastkowo. Te dwie informacje należy oddzielić średnikiem.

Utwórz hasło, aby zaszyfrować powyższy klucz. Tutaj będziemy przechowywać hasło w pliku o nazwie "keyfile.passwd":

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

Możesz pominąć powyższy krok, jeśli chcesz określić hasło bezpośrednio w pliku konfiguracyjnym za pomocą opcji file_key_management_filekey. Na przykład:file_key_management_filekey=mySuperStrongPassword

Ale w tym przykładzie zamierzamy odczytać hasło przechowywane w pliku, dlatego musimy później zdefiniować następujący wiersz w pliku konfiguracyjnym: 

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

Zamierzamy zaszyfrować plik kluczy w postaci zwykłego tekstu do innego pliku o nazwie keyfile.enc, używając hasła w pliku haseł:

$  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

Podczas wyświetlania katalogu powinniśmy zobaczyć te 3 pliki:

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

Zawartość pliku klucza.enc to po prostu zaszyfrowana wersja pliku klucza:

Aby przetestować, możemy odszyfrować zaszyfrowany plik za pomocą OpenSSL, podając plik hasła (keyfile.passwd):

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

Możemy wtedy usunąć zwykły klucz, ponieważ będziemy używać zaszyfrowanego (.enc) razem z plikiem haseł:

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

Możemy teraz przejść do konfiguracji szyfrowania spoczynkowego MariaDB.

Konfigurowanie szyfrowania w spoczynku

Musimy przenieść zaszyfrowany plik klucza i hasło do urządzeń podrzędnych, które będą używane przez MariaDB do szyfrowania/odszyfrowywania danych. W przeciwnym razie zaszyfrowana tabela, której kopia zapasowa została utworzona z urządzenia nadrzędnego przy użyciu fizycznej kopii zapasowej, takiej jak kopia zapasowa MariaDB, miałaby problem z odczytem przez urządzenia podrzędne (z powodu innej kombinacji klucza/hasła). Logiczna kopia zapasowa, taka jak mysqldump, powinna działać z różnymi kluczami i hasłami.

Na urządzeniach podrzędnych utwórz katalog do przechowywania elementów szyfrowania w spoczynku:

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

Na urządzeniu głównym skopiuj zaszyfrowany plik klucza i plik z hasłami do innych urządzeń podrzędnych:

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

Chroń pliki przed globalnym dostępem i przypisz użytkownika „mysql” jako właściciela:

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

Dodaj następujące elementy do pliku konfiguracyjnego MariaDB w sekcji [mysqld] lub [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

Zwróć uwagę na zmienną file_key_management_filekey, jeśli hasło znajduje się w pliku, musisz poprzedzić ścieżkę przedrostkiem „FILE:”. Możesz też podać bezpośrednio ciąg hasła (niezalecane ze względu na jego szczegółowość): 

file_key_management_filekey=mySuperStrongPassword

Restartuj serwer MariaDB po jednym węźle na raz, zaczynając od urządzeń podrzędnych:

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

Obserwuj dziennik błędów i upewnij się, że szyfrowanie MariaDB jest aktywowane podczas uruchamiania:

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

Powinieneś zobaczyć wiersze wskazujące na zainicjowanie szyfrowania w dzienniku błędów. W tym momencie większość konfiguracji szyfrowania jest już zakończona.

Testowanie szyfrowania

Utwórz testową bazę danych do testowania na wzorcu:

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

Utwórz standardową tabelę bez szyfrowania i wstaw wiersz:

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

Możemy zobaczyć przechowywane dane w postaci zwykłego tekstu podczas przeglądania pliku danych InnoDB za pomocą narzędzia hexdump:

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

Utwórz zaszyfrowaną tabelę i wstaw wiersz:

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

Nie możemy stwierdzić, co jest przechowywane w pliku danych InnoDB dla zaszyfrowanych tabel:

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

Zauważ, że plik metadanych tbl_enc.frm nie jest szyfrowany w stanie spoczynku. Tylko plik danych InnoDB (.ibd) jest szyfrowany.

Porównując „zwykłe” logi binarne lub przekaźnikowe, możemy wyraźnie zobaczyć ich zawartość za pomocą narzędzia hexdump:

$ 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

Podczas gdy w przypadku zaszyfrowanego dziennika binarnego zawartość wygląda na bełkot:

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

Szyfrowanie tablic Aria

W przypadku aparatu pamięci masowej Aria nie obsługuje opcji ENCRYPTED w instrukcji CREATE/ALTER, ponieważ jest ona zgodna z opcją globalną aria_encrypt_tables. Dlatego tworząc tabelę Aria, po prostu utwórz tabelę za pomocą opcji 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;

Możemy następnie zweryfikować zawartość pliku danych tabeli (tbl_aria_enc.MAD) lub pliku indeksu (tbl_aria_enc.MAI) za pomocą narzędzia hexdump. Aby zaszyfrować istniejącą tabelę Aria, należy ją przebudować:

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

Ta instrukcja powoduje, że Aria odbudowuje tabelę przy użyciu opcji tabeli ROW_FORMAT. W trakcie tego procesu, z nowym ustawieniem domyślnym, szyfruje tabelę podczas zapisu na dysku.

Szyfrowanie dziennika ogólnego/dziennika powolnych zapytań

Aby zaszyfrować ogólne i wolne logi zapytań, możemy ustawić opcję MariaDB log_output na „TABLE” zamiast domyślnej „FILE”:

MariaDB> SET GLOBAL log_ouput = 'TABLE';

Jednak MariaDB domyślnie utworzy niezbędne tabele przy użyciu mechanizmu przechowywania CSV, który nie jest szyfrowany przez MariaDB. Żadne inne silniki niż CSV, MyISAM lub Aria nie są dozwolone w przypadku tabel dziennika. Sztuczka polega na odbudowaniu domyślnej tabeli CSV za pomocą silnika pamięci masowej Aria, pod warunkiem, że opcja aria_encrypt_tables jest ustawiona na ON. Jednak odpowiednia opcja dziennika musi być wyłączona, aby zmiana tabeli powiodła się.

Zatem kroki do zaszyfrowania ogólnej tabeli dziennika to:

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

Podobnie w przypadku wolnego dziennika zapytań:

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

Zweryfikuj dane wyjściowe logów ogólnych na serwerze:

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

Jak również zaszyfrowana zawartość pliku danych Aria w katalogu danych za pomocą narzędzia hexdump:

$ 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

Szyfrowanie spoczynkowe MariaDB zostało zakończone. Połącz to z szyfrowaniem w tranzycie, które zrobiliśmy w pierwszym poście, nasza ostateczna architektura wygląda teraz tak:

Wnioski

Teraz można całkowicie zabezpieczyć bazy danych MariaDB za pomocą szyfrowania w celu ochrony przed fizycznym i wirtualnym naruszeniem lub kradzieżą. ClusterControl może również pomóc w utrzymaniu tego typu zabezpieczeń i można go pobrać bezpłatnie tutaj.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MariaDB WERSJA() Objaśnienie

  2. Popularne obrazy Docker dla serwerów MySQL i MariaDB

  3. Przygotowanie serwera MySQL lub MariaDB do produkcji — część druga

  4. 6 typowych scenariuszy awarii dla MySQL i MariaDB oraz jak je naprawić

  5. MariaDB LOCALTIMESTAMP() Objaśnienie