MySQL Verbindungen mit SSL verschlüsseln

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen

Dieser Artikel erklärt wie ein MySQL Client eine verschlüsselte Verbindung zu einem MySQL Server aufbauen kann. In der Standardkonfiguration ist eine Clientverbindung unverschlüsselt, was z.B. bei einer Verbindung über das Internet unerwünscht ist, da Daten am Weg abgehört werden könnten.

Die MySQL Verschlüsselung kann pro Client Verbindung separat erfolgen, d.h. es können gleichzeitig sowohl verschlüsselte als auch unverschlüsselte Verbindungen verwendet werden. Es kann für einzelne Verbindungen jedoch SSL auch als zwingend konfiguriert werden.

SSL Konfiguration aktivieren

In der MySQL Konfiguration (z.B. /etc/my.cnf) muss SSL mit den zugehörigen Zertifikaten aktiviert werden.

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

SSL Zertifikate erstellen

Es werden Zertifikate mit 2048 Bits und einer Gültigkeit von 1095 Tagen (3 Jahre) erstellt. Nach diesem Zeitraum müssen die Zertifikate verlängert oder neu erstellt werden.

Hinweis: Das unter Ubuntu 12.04 verwendet AppArmor Profil macht es notwendig, dass das Zertifikat unter /etc/mysql/*.pem abgelegt wird.

Wichtig bei der Erstellung ist, dass der Common Name (CN) vom Client und Server Zertifikat unterschiedlich ist. z.B. server.thomas-krenn.com und client.thomas-krenn.com

cd /etc/mysql/

openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 1095 -key ca-key.pem > ca-cert.pem

openssl req -newkey rsa:2048 -days 1095 -nodes -keyout server-key-pkcs8.pem > server-req.pem
openssl rsa -in server-key-pkcs8.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 1095 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

openssl req -newkey rsa:2048 -days 1095 -nodes -keyout client-key-pkcs8.pem > client-req.pem
openssl rsa -in client-key-pkcs8.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 1095 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

chmod 400 /etc/mysql/*.pem
chown mysql /etc/mysql/*.pem

Das Kommando "openssl rsa -in ... -out ..." konvertiert den Server/Client-Key von PKCS#8 nach PKCS#1. Dies sorgt laut [1] für eine bessere Performance.

Danach muss der Server neu gestartet werden, damit die Konfiguration aktiviert wird.

/etc/init.d/mysql restart

Jetzt kann überprüft werden, ob die Konfiguration richtig übernommen wurde.

mysql> show variables like '%ssl%';
+---------------+----------------------------------+
| Variable_name | Value                            |
+---------------+----------------------------------+
| have_openssl  | YES                              |
| have_ssl      | YES                              |
| ssl_ca        | /etc/mysql/ca-cert.pem           |
| ssl_capath    |                                  |
| ssl_cert      | /etc/mysql/server-cert.pem       |
| ssl_cipher    |                                  |
| ssl_key       | /etc/mysql/server-key.pem        |
+---------------+----------------------------------+

SSL Verschlüsselung für MySQL User aktivieren

Es gibt folgende Möglichkeiten bei der Rechtevergabe für Benutzer in Bezug auf SSL:

  • REQUIRE X509: ein beliebiges gültiges SSL Client Zertifikat kann verwendet werden
  • REQUIRE ISSUER / REQUIRE SUBJECT: ein beliebiges gültiges SSL Client Zertifikat reicht nicht aus, es muss von einer mit ISSUER spezifizierten CA kommen und/oder ein bestimmtes SUBJECT enthalten.
  • REQUIRE SSL: die Verbindung muss über SSL verschlüsselt aufgebaut werden, die Authenfizierung kann sowohl via Passwort als auch über ein SSL Client Zertifikat erfolgen.

Im Folgenden Beispiel wird der User "ssluser" erstellt der alle Rechte (ALL PRIVILEGES) auf alle Datenbanken (*.*) am "localhost" hat und ein gültiges SSL Client Zertifikat vorweisen muss.

GRANT ALL PRIVILEGES ON *.* TO 'ssluser'@'localhost' IDENTIFIED BY 'topsecret' REQUIRE X509;

Natürlich macht die Limitierung auf "localhost" in diesem Fall wenig Sinn, da eine Verschlüsselung am selben Server nicht notwendig ist. Stattdessen sollte man statt "localhost" in der Praxis die IP eintragen, von der aus der Zugriff verschlüsselt erfolgen soll.

Verschlüsselte MySQL Verbindung testen

cd /etc/mysql/
mysql -u ssluser -p --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem

Mittels dem Befehl SHOW STATUS LIKE 'Ssl_cipher'; kann sich der Verschlüsselungsstatus des verbundenen MySQL Clients angezeigt werden lassen.

mysql> SHOW STATUS LIKE 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA | 
+---------------+--------------------+
1 row in set (0.00 sec)

Die dafür notwendigen .pem-Dateien müssen dafür natürlich zuvor über einen gesicherten Weg zum Client kopiert werden.



Foto Christoph Mitasch.jpg

Autor: Christoph Mitasch

Christoph Mitasch arbeitet in der Abteilung Web Operations & Knowledge Transfer bei Thomas-Krenn. Er ist für die Betreuung und Weiterentwicklung der Webshop Infrastruktur zuständig. Seit einem Studienprojekt zum Thema Hochverfügbarkeit und Daten Replikation unter Linux beschäftigt er sich intensiv mit diesem Themenbereich. Nach einem Praktikum bei IBM Linz schloss er sein Diplomstudium „Computer- und Mediensicherheit“ an der FH Hagenberg ab. Er wohnt in der Nähe von Linz und ist neben der Arbeit ein begeisterter Marathon-Läufer und Jongleur, wo er mehrere Weltrekorde in der Team-Jonglage hält.