MySQL lässt den verschlüsselten Zugriff mit SSL zu. Dazu sollte das passende Zertifikat im Ordner /etc/ssl hinterlegt werden.
Konfiguration
Unter Ubuntu oder Debian empfiehlt es sich, die vom Paketverwalter mitgelieferte Datei /etc/mysql/my.cnf unangetastet zu lassen. Stattdessen können im Verzeichnis /etc/mysql/conf.d beliebig viele Dateien mit Endung .cnf ergänzt werden. Für die verschlüsselte Connection legen wir daher folgende Datei in /etc/mysql/conf.d/001-ssl.cnf an:
[client] ssl-ca = /etc/ssl/certs/ca-certificates.crt [mysqld] ssl ssl-ca = /etc/ssl/certs/ca-certificates.crt ssl-cert = /etc/ssl/localhost-cert.pem ssl-key = /etc/ssl/localhost-key.pem ssl-cipher = DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA
Das Zertifikat für Client und Server darf nicht mit SHA256 signiert werden, ansonsten erscheint folgende Fehlermeldung, wenn man sich mit dem mysql-Client verbinden will:
mysql -p Enter password: ERROR 2026 (HY000): SSL connection error: ASN: bad other signature confirmation
Es gibt auch einen vermeintlichen Bug unter Ubuntu 12.04 LTS. Ein dort generierter SSL-Private Key kann nicht von MySQL eingelesen werden. Mit der Anweisung kann der Schlüssel jedoch umgewandelt werden:
openssl rsa -in /etc/ssl/localhost-key.pem -out /etc/ssl/localhost-key.pem
Neustart
Die Datei des Private Key darf nur für Root und der Gruppe ssl-cert lesbar sein. Daher muss der MySQL-User mysql auch in die Gruppe ssl-cert eingetragen werden. Nach diesen Eintragungen muss MySQL mit
usermod -G ssl-cert mysql service mysql restart
neu gestartet werden.
Testen der verschlüsselten Verbindung
Jetzt kann überprüft werden, ob sich ein Client mit SSL verbindet. Dazu benutzt man einfach das Terminal-Programm mysql und verbindet sich mit beliebigen Benutzerdaten mit einer beliebigen Datenbank. Als nächstes gibt man nur:
status
ein und erhält folgende Ausgabe:
mysql> status -------------- mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.2 Connection id: 5000 Current database: Current user: root@localhost SSL: Cipher in use is DHE-RSA-AES256-SHA Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.38-0ubuntu0.12.04.1 (Ubuntu) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: latin1 Conn. characterset: latin1 UNIX socket: /run/mysqld/mysqld.sock Uptime: 7 days 5 hours 48 min 30 sec Threads: 21 Questions: 321745 Slow queries: 0 Opens: 1197 Flush tables: 1 Open tables: 413 Queries per second avg: 0.514
Die Zeile mit „SSL“ deutet auf den verwendeten Verschlüsselungsalgorithmus hin.
Verschlüsselte JDBC-Verbindung
Damit die typischen Application Server auch eine verschlüsselte Verbindung zu MySQL aufbauen, ist nur ein weiterer Connection Parameter notwendig: useSSL=true. Ein kompletter Connection String könnte also so aussehen:
jdbc:mysql://localhost:3306/database?autoReconnect=true&characterEncoding=utf8&useSSL=true