MySQL
SSL-Verbindungsaufbau
Suche…
Setup für Debian-basierte Systeme
(Dies setzt voraus, dass MySQL installiert wurde und sudo
verwendet wird.)
CA und SSL-Schlüssel generieren
Stellen Sie sicher, dass OpenSSL und Bibliotheken installiert sind:
apt-get -y install openssl
apt-get -y install libssl-dev
Als Nächstes erstellen und geben Sie ein Verzeichnis für die SSL-Dateien ein:
mkdir /home/ubuntu/mysqlcerts
cd /home/ubuntu/mysqlcerts
Erstellen Sie zum Generieren von Schlüsseln eine Zertifizierungsstelle (Certificate Authority, CA) zum Signieren der Schlüssel (selbstsigniert):
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem
Die bei jeder Eingabeaufforderung eingegebenen Werte haben keinen Einfluss auf die Konfiguration. Als Nächstes erstellen Sie einen Schlüssel für den Server und signieren Sie mit der Zertifizierungsstelle von vor:
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Dann erstellen Sie einen Schlüssel für einen Kunden:
openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Um sicherzustellen, dass alles korrekt eingerichtet wurde, überprüfen Sie die Schlüssel:
openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
Hinzufügen der Schlüssel zu MySQL
Öffnen Sie die MySQL-Konfigurationsdatei . Zum Beispiel:
vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
Abschnitt [mysqld]
die folgenden Optionen hinzu:
ssl-ca = /home/ubuntu/mysqlcerts/ca.pem
ssl-cert = /home/ubuntu/mysqlcerts/server-cert.pem
ssl-key = /home/ubuntu/mysqlcerts/server-key.pem
Starten Sie MySQL neu. Zum Beispiel:
service mysql restart
Testen Sie die SSL-Verbindung
ssl-ca
dieselbe Weise eine Verbindung her und übergeben Sie die zusätzlichen Optionen ssl-ca
, ssl-cert
und ssl-key
mit dem generierten Client-Schlüssel. Angenommen, cd /home/ubuntu/mysqlcerts
:
mysql --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h 127.0.0.1 -u superman -p
Überprüfen Sie nach dem Anmelden, ob die Verbindung tatsächlich sicher ist:
[email protected] [None]> SHOW VARIABLES LIKE '%ssl%';
+---------------+-----------------------------------------+
| Variable_name | Value |
+---------------+-----------------------------------------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | /home/ubuntu/mysqlcerts/ca.pem |
| ssl_capath | |
| ssl_cert | /home/ubuntu/mysqlcerts/server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /home/ubuntu/mysqlcerts/server-key.pem |
+---------------+-----------------------------------------+
Sie können auch überprüfen:
[email protected] [None]> STATUS;
...
SSL: Cipher in use is DHE-RSA-AES256-SHA
...
SSL erzwingen
Dies erfolgt über GRANT
mit REQUIRE SSL
:
GRANT ALL PRIVILEGES ON *.* TO 'superman'@'127.0.0.1' IDENTIFIED BY 'pass' REQUIRE SSL;
FLUSH PRIVILEGES;
Nun superman
muss über SSL verbinden.
Wenn Sie keine Clientschlüssel verwalten möchten, verwenden Sie den Clientschlüssel von früher und verwenden Sie ihn automatisch für alle Clients. Öffnen Sie die MySQL-Konfigurationsdatei , zum Beispiel:
vim /etc/mysql/mysql.conf.d/mysqld.cnf
Fügen Sie im Abschnitt [client]
die folgenden Optionen hinzu:
ssl-ca = /home/ubuntu/mysqlcerts/ca.pem
ssl-cert = /home/ubuntu/mysqlcerts/client-cert.pem
ssl-key = /home/ubuntu/mysqlcerts/client-key.pem
Jetzt muss superman
nur noch Folgendes eingeben, um sich über SSL anzumelden:
mysql -h 127.0.0.1 -u superman -p
Das Herstellen einer Verbindung von einem anderen Programm, beispielsweise in Python, erfordert normalerweise nur einen zusätzlichen Parameter für die Verbindungsfunktion. Ein Python-Beispiel:
import MySQLdb
ssl = {'cert': '/home/ubuntu/mysqlcerts/client-cert.pem', 'key': '/home/ubuntu/mysqlcerts/client-key.pem'}
conn = MySQLdb.connect(host='127.0.0.1', user='superman', passwd='imsoawesome', ssl=ssl)
Referenzen und weiterführende Literatur:
- https://www.percona.com/blog/2013/06/22/setting-up-mysql-ssl-and-secure-connections/
- https://lowendbox.com/blog/getting-started-with-mysql-over-ssl/
- http://xmodulo.com/enable-ssl-mysql-server-client.html
- https://ubuntuforums.org/showthread.php?t=1121458
Setup für CentOS7 / RHEL7
In diesem Beispiel werden zwei Server vorausgesetzt:
- dbserver (wo unsere Datenbank lebt)
- appclient (wo unsere Anwendungen leben)
FWIW, beide Server erzwingen SELinux.
Melden Sie sich zuerst bei dbserver an
Erstellen Sie ein temporäres Verzeichnis zum Erstellen der Zertifikate.
mkdir /root/certs/mysql/ && cd /root/certs/mysql/
Erstellen Sie die Serverzertifikate
openssl genrsa 2048 > ca-key.pem
openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem > ca-cert.pem
openssl req -sha1 -newkey rsa:2048 -days 730 -nodes -keyout server-key.pem > server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -sha1 -req -in server-req.pem -days 730 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
Serverzertifikate nach / etc / pki / tls / certs / mysql / verschieben
Der Verzeichnispfad setzt CentOS oder RHEL voraus (passen Sie ihn ggf. für andere Distros an):
mkdir /etc/pki/tls/certs/mysql/
Stellen Sie sicher, dass Sie Berechtigungen für den Ordner und die Dateien festlegen. mysql benötigt vollen Besitz und Zugriff.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
Konfigurieren Sie nun MySQL / MariaDB
# vi /etc/my.cnf
# i
[mysqld]
bind-address=*
ssl-ca=/etc/pki/tls/certs/ca-cert.pem
ssl-cert=/etc/pki/tls/certs/server-cert.pem
ssl-key=/etc/pki/tls/certs/server-key.pem
# :wq
Dann
systemctl restart mariadb
Vergessen Sie nicht, Ihre Firewall zu öffnen, um Verbindungen vom Client (mit IP 1.2.3.4) zuzulassen.
firewall-cmd --zone=drop --permanent --add-rich-rule 'rule family="ipv4" source address="1.2.3.4" service name="mysql" accept'
# I force everything to the drop zone. Season the above command to taste.
Starten Sie nun die Firewall neu
service firewalld restart
Melden Sie sich als Nächstes beim MySQL-Server von dbserver an:
mysql -uroot -p
Geben Sie Folgendes ein, um einen Benutzer für den Client zu erstellen. note Hinweis SSL in GRANT-Anweisung angeben.
GRANT ALL PRIVILEGES ON *.* TO ‘iamsecure’@’appclient’ IDENTIFIED BY ‘dingdingding’ REQUIRE SSL;
FLUSH PRIVILEGES;
# quit mysql
Sie sollten sich im ersten Schritt noch in / root / certs / mysql befinden. Wenn nicht, kehren Sie für einen der folgenden Befehle zurück.
Erstellen Sie die Client-Zertifikate
openssl req -sha1 -newkey rsa:2048 -days 730 -nodes -keyout client-key.pem > client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -sha1 -req -in client-req.pem -days 730 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
Hinweis : Ich habe sowohl für Server- als auch für Client-Zertifikate denselben allgemeinen Namen verwendet. YMMV.
Stellen Sie sicher, dass Sie für den nächsten Befehl noch / root / certs / mysql / sind
Server- und Client-CA-Zertifikat in einer einzigen Datei kombinieren:
cat server-cert.pem client-cert.pem > ca.pem
Stellen Sie sicher, dass Sie zwei Zertifikate sehen:
cat ca.pem
ENDE DER SERVER-SEITENARBEIT FÜR JETZT.
Öffnen Sie ein anderes Terminal und
ssh appclient
Erstellen Sie wie zuvor eine permanente Heimat für die Clientzertifikate
mkdir /etc/pki/tls/certs/mysql/
Platzieren Sie nun die Clientzertifikate (erstellt auf dem Datenbankserver) im Anwendungsclient. Sie können die Dateien entweder scp oder die Dateien nacheinander kopieren und einfügen.
scp dbserver
# copy files from dbserver to appclient
# exit scp
Stellen Sie erneut sicher, dass Sie Berechtigungen für den Ordner und die Dateien festlegen. mysql benötigt vollen Besitz und Zugriff.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
Sie sollten drei Dateien haben, die jeweils dem Benutzer mysql gehören:
/etc/pki/tls/certs/mysql/ca.pem
/etc/pki/tls/certs/mysql/client-cert.pem
/etc/pki/tls/certs/mysql/client-key.pem
Bearbeiten Sie nun die MariaDB / MySQL-Konfiguration des Anwendungs- [client]
Abschnitt [client]
.
vi /etc/my.cnf
# i
[client]
ssl-ca=/etc/pki/tls/certs/mysql/ca.pem
ssl-cert=/etc/pki/tls/certs/mysql/client-cert.pem
ssl-key=/etc/pki/tls/certs/mysql/client-key.pem
# :wq
Starten Sie den Mariadb-Dienst von appclient erneut:
systemctl restart mariadb
immer noch auf dem Client hier
Dies sollte zurückgeben: ssl TRUE
mysql --ssl --help
Melden Sie sich jetzt bei der mysql-Instanz von appclient an
mysql -uroot -p
Sollte für beide Variablen JA stehen
show variables LIKE '%ssl';
have_openssl YES
have_ssl YES
Anfangs habe ich gesehen
have_openssl NO
Ein kurzer Blick in mariadb.log ergab:
SSL-Fehler: Zertifikat kann nicht von '/etc/pki/tls/certs/mysql/client-cert.pem' abgerufen werden.
Das Problem war, dass root-client.pem und der dazugehörige Ordner gehörten. Die Lösung bestand darin, den Besitz von / etc / pki / tls / certs / mysql / auf mysql zu setzen.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
Starten Sie mariadb neu, falls erforderlich
JETZT KÖNNEN WIR DIE SICHERE VERBINDUNG TESTEN
Wir sind immer noch hier
Versuchen Sie, mit dem oben erstellten Konto eine Verbindung zur mysql-Instanz von dbserver herzustellen.
mysql -h dbserver -u iamsecure -p
# enter password dingdingding (hopefully you changed that to something else)
Mit etwas Glück sollten Sie ohne Fehler eingeloggt sein.
Geben Sie den folgenden Befehl an der MariaDB / MySQL-Eingabeaufforderung aus, um zu bestätigen, dass Sie mit SSL verbunden sind:
\s
Das ist ein Backslash, auch bekannt als Status
Daraufhin wird der Status Ihrer Verbindung angezeigt, der ungefähr wie folgt aussehen sollte:
Connection id: 4
Current database:
Current user: iamsecure@appclient
SSL: Cipher in use is DHE-RSA-AES256-GCM-SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 5.X.X-MariaDB MariaDB Server
Protocol version: 10
Connection: dbserver via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 42 min 13 sec
Wenn Sie bei Ihrem Verbindungsversuch auf Erlaubnis verweigerte Fehler erhalten, überprüfen Sie Ihre obige GRANT-Anweisung, um sicherzustellen, dass keine verstreuten Zeichen oder 'Markierungen vorhanden sind.
Wenn Sie SSL-Fehler haben, lesen Sie diese Anleitung erneut durch, um sicherzustellen, dass die Schritte ordnungsgemäß ausgeführt werden.
Dies funktionierte mit RHEL7 und wird wahrscheinlich auch mit CentOS7 funktionieren. Kann nicht bestätigen, ob diese genauen Schritte anderswo funktionieren.
Ich hoffe, das erspart jemandem etwas Zeit und Ärger.