MySQL Verbindungen mit SSL verschlüsseln
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.
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.
|