W tej serii blogów przedstawimy pełny przewodnik po tym, jak skonfigurować w pełni zaszyfrowany serwer MariaDB do szyfrowania w stanie spoczynku i podczas przesyłania, aby zapewnić maksymalną ochronę danych przed skradziony fizycznie lub podczas przenoszenia i komunikowania się z innymi hostami. Podstawowa idea polega na tym, że zamierzamy przekształcić nasze „zwykłe” wdrożenie w w pełni zaszyfrowaną replikację MariaDB, jak to uproszczono na poniższym diagramie:
Zamierzamy skonfigurować szereg komponentów szyfrowania:
- Szyfrowanie w tranzycie, które składa się z:
- Szyfrowanie klient-serwer
- Szyfrowanie replikacji
- Szyfrowanie w spoczynku, które składa się z:
- Szyfrowanie plików danych
- Szyfrowanie logów binarnych/przekaźnikowych.
Pamiętaj, że ten post na blogu dotyczy tylko szyfrowania w tranzycie. W drugiej części tej serii blogów omówimy szyfrowanie w spoczynku.
W tym przewodniku wdrażania założono, że mamy już działający serwer replikacji MariaDB. Jeśli go nie masz, możesz użyć ClusterControl do wdrożenia nowej replikacji MariaDB w ciągu kilku minut, za pomocą mniej niż 5 kliknięć. Wszystkie serwery działają na MariaDB 10.4.11 w systemie CentOS 7.
Szyfrowanie w tranzycie
Dane mogą być narażone na ryzyko zarówno podczas przesyłania, jak i w spoczynku, i wymagają ochrony w obu stanach. Szyfrowanie podczas przesyłania chroni Twoje dane w przypadku przechwycenia komunikacji podczas przesyłania danych między hostami przez sieć, z Twojej witryny i dostawcy chmury, między usługami lub między klientami a serwerem.
Dla MySQL/MariaDB dane są w ruchu, gdy klient łączy się z serwerem bazy danych lub gdy węzeł podrzędny replikuje dane z węzła głównego. MariaDB obsługuje szyfrowane połączenia między klientami a serwerem przy użyciu protokołu TLS (Transport Layer Security). TLS jest czasami określany jako SSL (Secure Sockets Layer), ale MariaDB w rzeczywistości nie używa protokołu SSL do połączeń szyfrowanych, ponieważ jego szyfrowanie jest słabe. Więcej szczegółów na ten temat na stronie dokumentacji MariaDB.
Szyfrowanie klient-serwer
W tej konfiguracji będziemy używać certyfikatów z podpisem własnym, co oznacza, że do weryfikacji naszej tożsamości nie używamy podmiotów zewnętrznych, takich jak Google, Comodo ani żaden popularny dostawca urzędu certyfikacji. W SSL/TLS weryfikacja tożsamości jest pierwszym krokiem, który należy wykonać, zanim serwer i klient wymienią swoje certyfikaty i klucze.
MySQL zapewnia bardzo przydatne narzędzie o nazwie mysql_ssl_rsa_setup, które automatycznie zajmuje się generowaniem kluczy i certyfikatów. Niestety nie ma jeszcze takiego narzędzia dla serwera MariaDB. Dlatego musimy ręcznie przygotować i wygenerować pliki związane z SSL dla naszych potrzeb MariaDB TLS.
Poniżej znajduje się lista plików, które wygenerujemy za pomocą narzędzia OpenSSL:
- Klucz CA - Klucz prywatny RSA w formacie PEM. Musi być trzymana w tajemnicy.
- Certyfikat CA - Certyfikat X.509 w formacie PEM. Zawiera klucz publiczny i metadane certyfikatu.
- CSR serwera - Żądanie podpisania certyfikatu. Nazwa pospolita (CN) podczas wypełniania formularza jest ważna, na przykład CN=mariadb-server
- Klucz serwera - Klucz prywatny RSA. Musi być trzymana w tajemnicy.
- Certyfikat serwera - Certyfikat X.509 podpisany kluczem CA. Zawiera klucz publiczny i metadane certyfikatu.
- CSR klienta - Żądanie podpisania certyfikatu. Musi użyć innej nazwy pospolitej (CN) niż CSR serwera, na przykład CN=client1
- Klucz klienta - Klucz prywatny RSA. Musi być trzymana w tajemnicy.
- Certyfikat klienta - Certyfikat X.509 podpisany kluczem CA. Zawiera klucz publiczny i metadane certyfikatu.
Przede wszystkim utwórz katalog do przechowywania naszych certyfikatów i kluczy do szyfrowania w tranzycie:
$ mkdir -p /etc/mysql/transit/
$ cd /etc/mysql/transit/
Tylko aby dać ci wyobrażenie, dlaczego nazywamy katalog tak, jak wspomniano, ponieważ w następnej części tej serii blogów utworzymy kolejny katalog do szyfrowania w stanie spoczynku w /etc/mysql/rest.
Urząd certyfikacji
Wygeneruj plik klucza dla naszego własnego urzędu certyfikacji (CA):
$ openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
.......................+++
...............................................................................................................................................................................................................................................+++
e is 65537 (0x10001)
Wygeneruj certyfikat dla naszego własnego urzędu certyfikacji (CA) na podstawie pliku ca-key.pem wygenerowanego wcześniej z wygaśnięciem 3650 dni:
$ openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:SE
State or Province Name (full name) []:Stockholm
Locality Name (eg, city) [Default City]:Stockholm
Organization Name (eg, company) [Default Company Ltd]:Severalnines
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:CA
Email Address []:[email protected]
Teraz powinniśmy mieć ca-key.pem i ca.pem w tym katalogu roboczym.
Klucz i certyfikat dla serwera
Następnie wygeneruj klucz prywatny dla serwera MariaDB:
$ openssl genrsa 2048 > server-key.pem
Generating RSA private key, 2048 bit long modulus
.............................................................................................................+++
..................................................................................................................+++
e is 65537 (0x10001)
Zaufany certyfikat musi być certyfikatem podpisanym przez urząd certyfikacji, przy czym tutaj będziemy używać naszego własnego urzędu certyfikacji, ponieważ ufamy hostom w sieci. Zanim będziemy mogli utworzyć podpisany certyfikat, musimy wygenerować certyfikat żądania o nazwie żądanie podpisania certyfikatu (CSR).
Utwórz CSR dla serwera MariaDB. Zamierzamy nazwać certyfikat jako server-req.pem. To nie jest certyfikat, którego będziemy używać dla serwera MariaDB. Ostateczny certyfikat to ten, który zostanie podpisany naszym własnym kluczem prywatnym CA (jak pokazano w następnym kroku):
$ openssl req -new -key server-key.pem -out server-req.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:SE
State or Province Name (full name) []:Stockholm
Locality Name (eg, city) [Default City]:Stockholm
Organization Name (eg, company) [Default Company Ltd]:Severalnines
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:MariaDBServer
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Zwróć uwagę na nazwę pospolitą, w której podaliśmy „MariaDBServer”. Może to być dowolna nazwa, ale wartość nie może być taka sama jak certyfikat klienta. Zwykle, jeśli aplikacje łączą się z serwerem MariaDB za pośrednictwem nazwy FQDN lub nazwy hosta (skip-name-resolve=OFF), prawdopodobnie chcesz określić nazwę FQDN serwera MariaDB jako nazwę pospolitą.
Możemy wtedy wygenerować końcowy certyfikat X.509 (server-cert.pem) i podpisać CSR (server-req.pem) certyfikatem CA (ca.pem) i kluczem prywatnym CA (ca -key.pem):
$ openssl x509 -req -in server-req.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 3650 -sha256
Signature ok
subject=/C=SE/ST=Stockholm/L=Stockholm/O=Severalnines/CN=MariaDBServer/[email protected]
Getting CA Private Key
W tym momencie mamy teraz to:
$ ls -1 /etc/mysql/transite
ca-key.pem
ca.pem
server-cert.pem
server-key.pem
server-req.pem
Potrzebujemy tylko certyfikatu CA (ca.pem), podpisanego certyfikatu serwera (server-cert.pem) i klucza prywatnego serwera (server-key.pem) dla serwera MariaDB. CSR (server-req.pem) nie jest już wymagany.
Klucz i certyfikat dla klienta
Następnie musimy wygenerować pliki kluczy i certyfikatów dla klienta MariaDB. Serwer MariaDB zaakceptuje tylko połączenie zdalne od klienta, który ma te pliki certyfikatów.
Zacznij od wygenerowania 2048-bitowego klucza dla klienta:
$ openssl genrsa 2048 > client-key.pem
Generating RSA private key, 2048 bit long modulus
.............................................................................................................+++
..................................................................................................................+++
e is 65537 (0x10001)
Utwórz CSR dla klienta o nazwie client-req.pem:
$ openssl req -new -key client-key.pem -out client-req.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:SE
State or Province Name (full name) []:Stockholm
Locality Name (eg, city) [Default City]:Stockholm
Organization Name (eg, company) [Default Company Ltd]:Severalnines
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:Client1
Email Address []:[email protected]
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Zwróć uwagę na nazwę pospolitą, w której podajemy „Klient1”. Podaj dowolną nazwę, która reprezentuje klienta. Ta wartość musi być inna niż nazwa pospolita serwera. W przypadku zaawansowanego użytkowania możesz użyć tej nazwy wspólnej, aby zezwolić określonemu użytkownikowi z certyfikatem pasującym do tej wartości, na przykład:
MariaDB> GRANT SELECT ON schema1.* TO 'client1'@'192.168.0.93' IDENTIFIED BY 's' REQUIRE SUBJECT '/CN=Client2';
Możemy wtedy wygenerować ostateczny certyfikat X.509 (client-cert.pem) i podpisać CSR (client-req.pem) certyfikatem CA (ca.pem) i kluczem prywatnym CA (ca -key.pem):
$ openssl x509 -req -in client-req.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 3650 -sha256
Signature ok
subject=/C=SE/ST=Stockholm/L=Stockholm/O=Severalnines/CN=Client1/[email protected]
Getting CA Private Key
Wszystkie certyfikaty potrzebne do konfiguracji szyfrowania w tranzycie są generowane. Sprawdź, czy oba certyfikaty są poprawnie podpisane przez urząd certyfikacji:
$ openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Konfigurowanie SSL dla MariaDB
Utwórz nowy katalog na każdym urządzeniu podrzędnym:
(slave1)$ mkdir -p /etc/mysql/transit/
(slave2)$ mkdir -p /etc/mysql/transit/
Skopiuj pliki szyfrowania do wszystkich urządzeń podrzędnych:
$ scp -r /etc/mysql/transit/* [email protected]:/etc/mysql/transit/
$ scp -r /etc/mysql/transit/* [email protected]:/etc/mysql/transit/
Upewnij się, że właścicielem katalogu certs jest użytkownik „mysql” i zmień uprawnienia wszystkich plików kluczy, aby nie można było ich odczytać globalnie:
$ cd /etc/mysql/transit
$ chown -R mysql:mysql *
$ chmod 600 client-key.pem server-key.pem ca-key.pem
Oto, co powinieneś zobaczyć, wyświetlając pliki w katalogu „transit”:
$ ls -al /etc/mysql/transit
total 32
drwxr-xr-x. 2 root root 172 Dec 14 04:42 .
drwxr-xr-x. 3 root root 24 Dec 14 04:18 ..
-rw-------. 1 mysql mysql 1675 Dec 14 04:19 ca-key.pem
-rw-r--r--. 1 mysql mysql 1383 Dec 14 04:22 ca.pem
-rw-r--r--. 1 mysql mysql 1383 Dec 14 04:42 client-cert.pem
-rw-------. 1 mysql mysql 1675 Dec 14 04:42 client-key.pem
-rw-r--r--. 1 mysql mysql 1399 Dec 14 04:42 client-req.pem
-rw-r--r--. 1 mysql mysql 1391 Dec 14 04:34 server-cert.pem
-rw-------. 1 mysql mysql 1679 Dec 14 04:28 server-key.pem
-rw-r--r--. 1 mysql mysql 1415 Dec 14 04:31 server-req.pem
Następnie włączymy połączenie SSL dla MariaDB. Na każdym hoście MariaDB (master i slave) edytuj plik konfiguracyjny i dodaj następujące wiersze w sekcji [mysqld]:
ssl-ca=/etc/mysql/transit/ca.pem
ssl-cert=/etc/mysql/transit/server-cert.pem
ssl-key=/etc/mysql/transit/server-key.pem
Restartuj serwer MariaDB po jednym węźle na raz, zaczynając od podrzędnych, a na końcu na nadrzędnym:
(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb
Po ponownym uruchomieniu MariaDB może teraz akceptować zwykłe połączenia, łącząc się z nią bez żadnych parametrów związanych z SSL lub z połączeniami szyfrowanymi, jeśli określisz parametr związany z SSL w ciągu połączenia.
W przypadku użytkowników ClusterControl można włączyć szyfrowanie klient-serwer za pomocą jednego kliknięcia. Wystarczy przejść do ClusterControl -> Bezpieczeństwo -> Szyfrowanie SSL -> Włącz -> Utwórz certyfikat -> Wygaśnięcie certyfikatu -> Włącz SSL:
ClusterControl wygeneruje wymagane klucze, certyfikat X.509 i certyfikat CA oraz skonfigurować szyfrowanie SSL dla połączeń klient-serwer dla wszystkich węzłów w klastrze. W przypadku replikacji MySQL/MariaDB pliki SSL będą znajdować się w /etc/ssl/replication/cluster_X, gdzie X jest identyfikatorem klastra w każdym węźle bazy danych. Na wszystkich węzłach będą używane te same certyfikaty, a istniejące mogą zostać nadpisane. Węzły muszą być ponownie uruchamiane pojedynczo po zakończeniu tego zadania. Zalecamy, aby najpierw zrestartować urządzenie podrzędne replikacji i sprawdzić, czy ustawienia SSL działają.
Aby zrestartować każdy węzeł, przejdź do ClusterControl -> Nodes -> Node Actions -> Restart Node. Zrestartuj jeden węzeł na raz, zaczynając od urządzeń podrzędnych. Ostatni węzeł powinien być węzłem głównym z włączoną flagą wymuszonego zatrzymania:
Możesz stwierdzić, czy węzeł jest w stanie obsłużyć szyfrowanie klient-serwer, patrząc na zieloną ikonę kłódki tuż obok węzła bazy danych w siatce Przegląd:
W tym momencie nasz klaster jest gotowy do akceptowania połączenia SSL z MySQL użytkowników.
Łączenie przez połączenie szyfrowane
Klient MariaDB wymaga wszystkich plików SSL związanych z klientem, które wygenerowaliśmy na serwerze. Skopiuj wygenerowany certyfikat klienta, certyfikat CA i klucz klienta do hosta klienta:
$ cd /etc/mysql/transit
$ scp client-cert.pem client-key.pem ca.pem [email protected]:~
**ClusterControl generuje pliki SSL klienta w /etc/ssl/replication/cluster_X/w każdym węźle bazy danych, gdzie X to identyfikator klastra.
Utwórz użytkownika bazy danych, który wymaga SSL na urządzeniu głównym:
MariaDB> CREATE SCHEMA sbtest;
MariaDB> CREATE USER [email protected]'%' IDENTIFIED BY 'mysecr3t' REQUIRE SSL;
MariaDB> GRANT ALL PRIVILEGES ON sbtest.* to [email protected]'%';
Z hosta klienta połącz się z serwerem MariaDB z parametrami związanymi z SSL. Status połączenia możemy zweryfikować za pomocą instrukcji „STATUS”:
(client)$ mysql -usbtest -p -h192.168.0.91 -P3306 --ssl-cert client-cert.pem --ssl-key client-key.pem --ssl-ca ca.pem -e 'status'
...
Current user: [email protected]
SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384
...
Zwróć uwagę na linię SSL, w której szyfr jest używany do szyfrowania. Oznacza to, że klient jest pomyślnie połączony z serwerem MariaDB za pośrednictwem połączenia szyfrowanego.
W tym momencie zaszyfrowaliśmy połączenie klient-serwer z serwerem MariaDB, co przedstawia zielona strzałka z dwoma grotami na poniższym diagramie:
W następnej części zajmiemy się szyfrowaniem połączeń replikacyjnych między węzłami.
Szyfrowanie replikacji
Konfigurowanie połączeń szyfrowanych na potrzeby replikacji jest podobne do konfigurowania połączeń klient/serwer. Możemy użyć tych samych certyfikatów klienta, klucza i certyfikatu CA, aby umożliwić użytkownikowi replikacji dostęp do serwera mastera poprzez kanał szyfrowania. Pośrednio umożliwi to szyfrowanie między węzłami, gdy podrzędny wątek IO pobiera zdarzenia replikacji z urządzenia nadrzędnego.
Skonfigurujmy to na jednym urządzeniu podrzędnym na raz. Dla pierwszego urządzenia podrzędnego, 192.168.0.92, dodaj następujący wiersz w sekcji [klient] w pliku konfiguracyjnym MariaDB:
[client]
ssl-ca=/etc/mysql/transit/ca.pem
ssl-cert=/etc/mysql/transit/client-cert.pem
ssl-key=/etc/mysql/transit/client-key.pem
Zatrzymaj wątek replikacji na urządzeniu podrzędnym:
(slave)MariaDB> STOP SLAVE;
Na urządzeniu głównym zmień istniejącego użytkownika replikacji, aby wymusić na nim połączenie przy użyciu protokołu SSL:
(master)MariaDB> ALTER USER [email protected] REQUIRE SSL;
Na urządzeniu podrzędnym przetestuj połączenie z urządzeniem głównym 192.168.0.91 za pomocą wiersza poleceń mysql z opcją --ssl:
(slave)MariaDB> mysql -urpl_user -p -h192.168.0.91 -P 3306 --ssl -e 'status'
...
Current user: [email protected]
SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384
...
Upewnij się, że możesz bezbłędnie połączyć się z hostem głównym. Następnie na urządzeniu podrzędnym określ instrukcję CHANGE MASTER z parametrami SSL jak poniżej:
(slave)MariaDB> CHANGE MASTER TO MASTER_SSL = 1, MASTER_SSL_CA = '/etc/mysql/transit/ca.pem', MASTER_SSL_CERT = '/etc/mysql/transit/client-cert.pem', MASTER_SSL_KEY = '/etc/mysql/transit/client-key.pem';
Uruchom replikację podrzędną:
(slave)MariaDB> START SLAVE;
Sprawdź, czy replikacja działa prawidłowo z powiązanymi parametrami SSL:
MariaDB> SHOW SLAVE STATUS\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master_SSL_Allowed: Yes
Master_SSL_CA_File: /etc/mysql/transit/ca.pem
Master_SSL_Cert: /etc/mysql/transit/client-cert.pem
Master_SSL_Key: /etc/mysql/transit/client-key.pem
...
Urządzenie podrzędne jest teraz bezpiecznie replikowane z urządzenia nadrzędnego za pomocą szyfrowania TLS.
Powtórz wszystkie powyższe kroki na pozostałym urządzeniu podrzędnym, 192.168.0.93. Jedyną różnicą jest instrukcja alter użytkownika, która ma zostać wykonana na urządzeniu głównym, w przypadku której musimy przejść do odpowiedniego hosta:
(master)MariaDB> ALTER USER [email protected] REQUIRE SSL;
W tym momencie zakończyliśmy szyfrowanie w tranzycie, co ilustrują zielone linie od urządzenia nadrzędnego do podrzędnego na poniższym diagramie:
Możesz zweryfikować połączenie szyfrujące, patrząc na dane wyjściowe tcpdump dla interfejsu eth1 na niewolnika. Oto przykład standardowej replikacji bez szyfrowania:
(plain-slave)$ tcpdump -i eth1 -s 0 -l -w - 'src port 3306 or dst port 3306' | strings
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
H"-'
binlog.000008Ulw
binlog.000008Ulw
sbtest
sbtest
create table t1 (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255))
binlog.000008
sbtest
BEGIN3
sbtest
test data3
Ok*Z
binlog.000008*Z
^C11 packets captured
11 packets received by filter
0 packets dropped by kernel
Wyraźnie widzimy tekst czytany przez niewolnika od pana. Podczas połączenia szyfrowanego powinieneś zobaczyć bezsensowne znaki, takie jak poniżej:
(encrypted-slave)$ tcpdump -i eth1 -s 0 -l -w - 'src port 3306 or dst port 3306' | strings
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
:|f^yb#
O5~_
@#PFh
k)]O
jtk3c
@NjN9_a
!\[email protected]
NrF
?7&Y
^C6 packets captured
6 packets received by filter
0 packets dropped by kernel
Wnioski
W następnej części tej serii blogów przyjrzymy się zakończeniu naszej w pełni zaszyfrowanej konfiguracji za pomocą szyfrowania spoczynkowego MariaDB. Bądź na bieżąco!