sql >> Databasteknik >  >> RDS >> MariaDB

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

I den här bloggserien kommer vi att ge dig en komplett genomgång av hur du konfigurerar en helt krypterad MariaDB-server för kryptering i vila och under transport, för att säkerställa maximalt skydd av data från att vara stulen fysiskt eller under överföring och kommunikation med andra värdar. Grundtanken är att vi kommer att förvandla vår "vanliga" distribution till en helt krypterad MariaDB-replikering, som förenklat i följande diagram:

Vi kommer att konfigurera ett antal krypteringskomponenter:

  • Kryptering under transport, som består av:
    • Klient-serverkryptering
    • replikeringskryptering
  • Kryptering i vila, som består av:
    • Datafilkryptering
    • Binär/reläloggkryptering.

Observera att det här blogginlägget endast täcker in-transit-kryptering. Vi kommer att ta upp kryptering i vila i den andra delen av den här bloggserien.

Denna implementeringsgenomgång antog att vi redan har en MariaDB-replikeringsserver som redan körs. Om du inte har en kan du använda ClusterControl för att distribuera en ny MariaDB-replikering inom några minuter, med färre än 5 klick. Alla servrar körs på MariaDB 10.4.11 på CentOS 7-systemet.

Kryptering i transit

Data kan utsättas för risker både under transport och vila och kräver skydd i båda staterna. Kryptering under transport skyddar dina data om kommunikation fångas upp medan data flyttas mellan värdar via nätverket, antingen från din webbplats och molnleverantören, mellan tjänster eller mellan klienter och servern.

För MySQL/MariaDB är data i rörelse när en klient ansluter till en databasserver, eller när en slavnod replikerar data från en masternod. MariaDB stöder krypterade anslutningar mellan klienter och servern med TLS-protokollet (Transport Layer Security). TLS kallas ibland för SSL (Secure Sockets Layer) men MariaDB använder faktiskt inte SSL-protokollet för krypterade anslutningar eftersom dess kryptering är svag. Mer information om detta på MariaDB-dokumentationssidan.

Klient-serverkryptering

I den här installationen kommer vi att använda självsignerade certifikat, vilket innebär att vi inte använder externa parter som Google, Comodo eller någon populär certifikatutfärdare för att verifiera vår identitet. I SSL/TLS är identitetsverifiering det första steget som måste passeras innan servern och klienten utbyter sina certifikat och nycklar.

MySQL tillhandahåller ett mycket praktiskt verktyg som heter mysql_ssl_rsa_setup som tar hand om nyckel- och certifikatgenereringen automatiskt. Tyvärr finns det inget sådant verktyg för MariaDB-servern ännu. Därför måste vi manuellt förbereda och generera de SSL-relaterade filerna för våra MariaDB TLS-behov.

Följande är en lista över de filer som vi kommer att generera med OpenSSL-verktyget:

  • CA-nyckel - RSA privat nyckel i PEM-format. Måste hållas hemligt.
  • CA-certifikat - X.509-certifikat i PEM-format. Innehåller offentlig nyckel och certifikatmetadata.
  • Server CSR - Begäran om undertecknande av certifikat. Common Name (CN) när du fyller i formuläret är viktigt, till exempel CN=mariadb-server
  • Servernyckel - RSA privat nyckel. Måste hållas hemligt.
  • Servercertifikat - X.509-certifikat signerat av CA-nyckel. Innehåller offentlig nyckel och certifikatmetadata.
  • Kundens CSR - Begäran om undertecknande av certifikat. Måste använda ett annat Common Name (CN) än serverns CSR, till exempel CN=client1 
  • Klientnyckel - RSA privat nyckel. Måste hållas hemligt.
  • Kundcertifikat - X.509-certifikat signerat av CA-nyckel. Innehåller offentlig nyckel och certifikatmetadata.

Skapa först och främst en katalog för att lagra våra certifikat och nycklar för kryptering under transport:

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

Bara för att ge dig en uppfattning om varför vi namnger katalogen som nämnts är för att i nästa del av den här bloggserien kommer vi att skapa en annan katalog för at-rest-kryptering på /etc/mysql/rest.

Certifikatutfärdare

Generera en nyckelfil för vår egen certifikatutfärdare (CA):

$ openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
.......................+++
...............................................................................................................................................................................................................................................+++
e is 65537 (0x10001)

Generera ett certifikat för vår egen certifikatutfärdare (CA) baserat på ca-key.pem som genererats tidigare med utgången på 3650 dagar:

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

Nu borde vi ha ca-key.pem och ca.pem under den här arbetskatalogen.

Nyckel och certifikat för server

Generera sedan privat nyckel för MariaDB-servern:

$ openssl genrsa 2048 > server-key.pem
Generating RSA private key, 2048 bit long modulus
.............................................................................................................+++
..................................................................................................................+++
e is 65537 (0x10001)

Ett pålitligt certifikat måste vara ett certifikat signerat av en certifikatutfärdare, varvid vi här kommer att använda vår egen CA eftersom vi litar på värdarna i nätverket. Innan vi kan skapa ett signerat certifikat måste vi skapa ett begärandecertifikat som heter Certificate Signing Request (CSR).

Skapa en CSR för MariaDB-servern. Vi kommer att kalla certifikatet som server-req.pem. Det här är inte certifikatet som vi kommer att använda för MariaDB-servern. Det slutliga certifikatet är det som kommer att signeras av vår egen CA-nyckel (som visas i nästa steg):

$ 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 []:

Notera det gemensamma namnet där vi angav "MariaDBServer". Detta kan vara vilket namn som helst men värdet får inte vara detsamma som klientcertifikatet. Vanligtvis, om applikationerna ansluter till MariaDB-servern via FQDN eller värdnamn (skip-name-resolve=OFF), vill du förmodligen ange MariaDB-serverns FQDN som Common Name.

Vi kan sedan generera det slutliga X.509-certifikatet (server-cert.pem) och signera CSR (server-req.pem) med CA:s certifikat (ca.pem) och CA:s privata nyckel (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

Vi har det här nu:

$ ls -1 /etc/mysql/transite
ca-key.pem
ca.pem
server-cert.pem
server-key.pem
server-req.pem

Vi behöver bara CA-certifikatet (ca.pem), serverns signerade certifikat (server-cert.pem) och serverns privata nyckel (server-key.pem) för MariaDB-servern. CSR (server-req.pem) krävs inte längre.

Nyckel och certifikat för klienten

Närnäst måste vi generera nyckel- och certifikatfiler för MariaDB-klienten. MariaDB-servern accepterar endast fjärranslutning från klienten som har dessa certifikatfiler.

Börja med att generera en 2048-bitars nyckel för klienten:

$ openssl genrsa 2048 > client-key.pem
Generating RSA private key, 2048 bit long modulus
.............................................................................................................+++
..................................................................................................................+++
e is 65537 (0x10001)

Skapa CSR för klienten som heter 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 []:

Var uppmärksam på Common Name där vi anger "Client1". Ange vilket namn som helst som representerar klienten. Detta värde måste skilja sig från serverns Common Name. För avancerad användning kan du använda detta Common Name för att tillåta vissa användare med certifikat som matchar detta värde, till exempel:

MariaDB> GRANT SELECT ON schema1.* TO 'client1'@'192.168.0.93' IDENTIFIED BY 's' REQUIRE SUBJECT '/CN=Client2';

Vi kan sedan generera det slutliga X.509-certifikatet (client-cert.pem) och signera CSR (client-req.pem) med CA:s certifikat (ca.pem) och CA:s privata nyckel (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

Alla certifikat som vi behöver för inställning av kryptering under transport genereras. Kontrollera att båda certifikaten är korrekt signerade av CA:

$ openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK

Konfigurera SSL för MariaDB

Skapa en ny katalog på varje slav:

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

Kopiera krypteringsfilerna till alla slavar:

$ scp -r /etc/mysql/transit/* [email protected]:/etc/mysql/transit/
$ scp -r /etc/mysql/transit/* [email protected]:/etc/mysql/transit/

Se till att ägaren av certs-katalogen till "mysql"-användaren och ändra behörigheterna för alla nyckelfiler så att den inte kan läsas globalt:

$ cd /etc/mysql/transit
$ chown -R mysql:mysql *
$ chmod 600 client-key.pem server-key.pem ca-key.pem

Här är vad du bör se när du listar filer under "transit"-katalogen:

$ 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

Närnäst kommer vi att aktivera SSL-anslutningen för MariaDB. Redigera konfigurationsfilen på varje MariaDB-värd (master och slavar) och lägg till följande rader under avsnittet [mysqld]:

ssl-ca=/etc/mysql/transit/ca.pem
ssl-cert=/etc/mysql/transit/server-cert.pem
ssl-key=/etc/mysql/transit/server-key.pem

Starta om MariaDB-servern en nod i taget, med start från slavar och slutligen på mastern:

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

Efter omstart kan MariaDB nu acceptera vanliga anslutningar genom att ansluta till den utan några SSL-relaterade parametrar eller med krypterade anslutningar, när du anger SSL-relaterad parameter i anslutningssträngen.

För ClusterControl-användare kan du aktivera klient-serverkryptering bara en fråga om klick. Gå bara till ClusterControl -> Säkerhet -> SSL-kryptering -> Aktivera -> Skapa certifikat -> Certifikatets utgång -> Aktivera SSL:

ClusterControl genererar de nödvändiga nycklarna, X.509-certifikatet och CA-certifikatet och ställ in SSL-kryptering för klient-serveranslutningar för alla noder i klustret. För MySQL/MariaDB-replikering kommer SSL-filerna att finnas under /etc/ssl/replikation/cluster_X, där X är kluster-ID på varje databasnod. Samma certifikat kommer att användas på alla noder och de befintliga kan skrivas över. Noderna måste startas om individuellt efter att detta jobb har slutförts. Vi rekommenderar att du först startar om en replikeringsslav och verifierar att SSL-inställningarna fungerar.

För att starta om varje nod, gå till ClusterControl -> Noder -> Nodåtgärder -> Starta om nod. Starta om en nod i taget, börja med slavarna. Den sista noden ska vara huvudnoden med tvingande stoppflagga aktiverad:

Du kan se om en nod kan hantera klient-server-kryptering genom att titta på den gröna låsikonen bredvid databasnoden i översiktsrutnätet:

Vid denna tidpunkt är vårt kluster nu redo att acceptera SSL-anslutning från MySQL användare.

Ansluter via krypterad anslutning

MariaDB-klienten kräver alla klientrelaterade SSL-filer som vi har genererat inuti servern. Kopiera det genererade klientcertifikatet, CA-certifikatet och klientnyckeln till klientvärden:

$ cd /etc/mysql/transit
$ scp client-cert.pem client-key.pem ca.pem [email protected]:~

**ClusterControl genererar klientens SSL-filer under /etc/ssl/replication/cluster_X/på varje databasnod, där X är kluster-ID.

Skapa en databasanvändare som kräver SSL på mastern:

MariaDB> CREATE SCHEMA sbtest;
MariaDB> CREATE USER [email protected]'%' IDENTIFIED BY 'mysecr3t' REQUIRE SSL;
MariaDB> GRANT ALL PRIVILEGES ON sbtest.* to [email protected]'%';

Från klientvärden, anslut till MariaDB-servern med SSL-relaterade parametrar. Vi kan verifiera anslutningsstatusen genom att använda "STATUS"-satsen:

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

Var uppmärksam på SSL-raden där chiffret används för krypteringen. Detta innebär att klienten är framgångsrikt ansluten till MariaDB-servern via krypterad anslutning.

Vid denna tidpunkt har vi krypterat klient-serveranslutningen till MariaDB-servern, som representeras av den gröna tvåhuvudena pilen i följande diagram:

I nästa del kommer vi att kryptera replikeringsanslutningar mellan noder.

replikeringskryptering

Att ställa in krypterade anslutningar för replikering liknar att göra det för klient-/serveranslutningar. Vi kan använda samma klientcertifikat, nyckel och CA-certifikat för att låta replikeringsanvändaren komma åt masterns server via krypteringskanal. Detta kommer indirekt att möjliggöra kryptering mellan noder när slav-IO-tråden drar replikeringshändelser från mastern.

Låt oss konfigurera detta på en slav i taget. För den första slaven, 192.168.0.92, lägg till följande rad under avsnittet [klient] i MariaDB-konfigurationsfilen:

[client]
ssl-ca=/etc/mysql/transit/ca.pem
ssl-cert=/etc/mysql/transit/client-cert.pem
ssl-key=/etc/mysql/transit/client-key.pem

Stoppa replikeringstråden på slaven:

(slave)MariaDB> STOP SLAVE;

På mastern, ändra den befintliga replikeringsanvändaren för att tvinga den att ansluta med SSL:

(master)MariaDB> ALTER USER [email protected] REQUIRE SSL;

På slaven, testa anslutningen till mastern, 192.168.0.91 via mysql kommandorad med --ssl flagga:

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

Se till att du kan ansluta till huvudvärden utan fel. Ange sedan CHANGE MASTER-satsen på slaven med SSL-parametrar enligt nedan:

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

Starta replikeringsslaven:

(slave)MariaDB> START SLAVE;

Verifiera att replikeringen fungerar som den ska med relaterade SSL-parametrar:

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

Slaven replikerar nu från mastern på ett säkert sätt via TLS-kryptering.

Upprepa alla ovanstående steg på den återstående slaven, 192.168.0.93. Den enda skillnaden är alter user statement som ska köras på mastern där vi måste byta till dess respektive värd:

(master)MariaDB> ALTER USER [email protected] REQUIRE SSL;

Vi har nu slutfört kryptering under transport som illustreras av de gröna linjerna från master till slavar i följande diagram:

Du kan verifiera krypteringsanslutningen genom att titta på tcpdump-utgången för gränssnitt eth1 på slaven. Följande är ett exempel på standardreplikering utan kryptering:

(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

Vi kan tydligt se texten läst av slaven från mästaren. Medan du är på en krypterad anslutning, bör du se floskeltecken som nedan:

(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

Slutsats

I nästa del av den här bloggserien kommer vi att undersöka att slutföra vår helt krypterade installation med MariaDB at-rest-kryptering. Håll utkik!


  1. En lösning för gränsen för åtkomst 255 kolumner

  2. Hur reparerar jag en InnoDB-tabell?

  3. hur man hittar radstorlek i tabell

  4. Kul med (columnstore) komprimering på ett väldigt stort bord – del 3