Hier wird erklärt, wie ein MySQL Client eine verschlüsselte Verbindung zu einem MySQL Server, der mit Ubuntu 14.04 und Mysql-Server 5.6.28 betrieben wird, aufgebaut werden kann.
SSL Zertifikate erstellen
Es werden Zertifikate mit 2048 Bits und einer Gültigkeit von 3650 Tagen erstellt. Nach diesem Zeitraum müssen die Zertifikate verlängert oder neu erstellt werden.
Bitte nicht vergessen, dass der Common Name (CN) vom Client und Server Zertifikat unterschiedlich ist. z.B. servername.intelli.ch und client.intelli.ch
cd /etc/mysql/
# Generate a CA key and certificate with SHA1 digest openssl genrsa 2048 > ca-key.pem openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem # Create server key and certficate with SHA1 digest, sign it and convert # the RSA key from PKCS #8 (OpenSSL 1.0 and newer) to the old PKCS #1 format openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem openssl rsa -in server-key.pem -out server-key.pem # Create client key and certificate with SHA digest, sign it and convert # the RSA key from PKCS #8 (OpenSSL 1.0 and newer) to the old PKCS #1 format openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem openssl rsa -in client-key.pem -out client-key.pem
chmod 400 /etc/mysql/*.pem chown mysql /etc/mysql/*.pem
SSL Konfiguration aktivieren
In der MySQL Konfiguration (/etc/mysql/my.cnf
) muss SSL mit den zugehörigen Zertifikaten aktiviert werden.
ssl-ca=/etc/mysql/ca-cert.pem ssl-cert=/etc/mysql/server-cert.pem ssl-key=/etc/mysql/server-key.pem
Nun MySql-Server neu starten
sudo service mysql restart
Es kann auf der DB ü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;
Client SSL erzwingen
grant all privileges on database.* to 'username'@'hostaddress' identified by 'password' require SSL; oder GRANT USAGE ON *.* TO 'ralph'@'%' REQUIRE SSL;
Verschlüsselte MySQL Verbindung testen
cd /etc/mysql/ mysql -ussluser -p -h127.0.0.1 --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem
Hint: Auf Ubuntu 18.04 schlug dieser Befehl mit dem Feher “SSL connection error: SSL_CTX_set_default_verify_paths failed” fehl. Das liegt daran, weil der lokale User mit dem dieser mysql-Befehl ausgeführt wird, keine Berechtigung auf die Zertifikate hat. Um den Test trotzdem machen zu können, kann der Befehl mit sudo ausgeführt werden.
Die SSL Keys müssen wenn der Zugriff von einem entfernten Host aus erfolgen soll natürlich vorher dorthin kopiert werden.
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)
mysql> SHOW STATUS LIKE 'Ssl_version'; +---------------+---------+ | Variable_name | Value | +---------------+---------+ | Ssl_version | TLSv1.1 | +---------------+---------+ 1 row in set (0.01 sec)
Überprüfe alle Server-Connections
Es kann auch überprüft werden ob ALLE Verbindungen zum Mysql-Server auch wirklich mit SSL Connecten.
Mit folgendem Befehl kann überprüft werden ob und welche User mit SSL mit dem Mysql-Server kommunizieren:
SELECT sbt.variable_value AS tls_version, t2.variable_value AS cipher, processlist_user AS user, processlist_host AS host FROM performance_schema.status_by_thread AS sbt JOIN performance_schema.threads AS t ON t.thread_id = sbt.thread_id JOIN performance_schema.status_by_thread AS t2 ON t2.thread_id = t.thread_id WHERE sbt.variable_name = 'Ssl_version' and t2.variable_name = 'Ssl_cipher' ORDER BY tls_version;
Links
- Bei diesem Beitrag handelt es sich um eine Erweiterung des Beitrags von Christoph Mitasch. Siehe auch https://www.thomas-krenn.com/de/wiki/MySQL_Verbindungen_mit_SSL_verschl%C3%BCsseln
- https://www.howtoforge.com/tutorial/how-to-enable-ssl-and-remote-connections-for-mysql-on-centos-7/
- https://www.percona.com/blog/2016/02/23/mysql-connection-using-ssl-or-not/