MySQL
SSL-verbinding instellen
Zoeken…
Setup voor op Debian gebaseerde systemen
(Dit veronderstelt dat MySQL is geïnstalleerd en dat sudo
wordt gebruikt.)
CA- en SSL-sleutels genereren
Zorg ervoor dat OpenSSL en bibliotheken zijn geïnstalleerd:
apt-get -y install openssl
apt-get -y install libssl-dev
Maak vervolgens een map aan voor de SSL-bestanden:
mkdir /home/ubuntu/mysqlcerts
cd /home/ubuntu/mysqlcerts
Om sleutels te genereren, maakt u een certificeringsinstantie (CA) om de sleutels te ondertekenen (zelfondertekend):
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem
De waarden die bij elke prompt worden ingevoerd, hebben geen invloed op de configuratie. Maak vervolgens een sleutel voor de server en onderteken met de CA van eerder:
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
Maak vervolgens een sleutel voor een client:
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
Controleer de sleutels om te controleren of alles correct is ingesteld:
openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
De sleutels toevoegen aan MySQL
Open het MySQL-configuratiebestand . Bijvoorbeeld:
vim /etc/mysql/mysql.conf.d/mysqld.cnf
Voeg in het gedeelte [mysqld]
de volgende opties toe:
ssl-ca = /home/ubuntu/mysqlcerts/ca.pem
ssl-cert = /home/ubuntu/mysqlcerts/server-cert.pem
ssl-key = /home/ubuntu/mysqlcerts/server-key.pem
Start MySQL opnieuw. Bijvoorbeeld:
service mysql restart
Test de SSL-verbinding
Maak op dezelfde manier verbinding met de extra opties ssl-ca
, ssl-cert
en ssl-key
, met behulp van de gegenereerde clientsleutel. cd /home/ubuntu/mysqlcerts
bijvoorbeeld 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
Controleer na het inloggen of de verbinding inderdaad veilig is:
[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 |
+---------------+-----------------------------------------+
U kunt ook controleren:
[email protected] [None]> STATUS;
...
SSL: Cipher in use is DHE-RSA-AES256-SHA
...
SSL afdwingen
Dit is via GRANT
, met REQUIRE SSL
:
GRANT ALL PRIVILEGES ON *.* TO 'superman'@'127.0.0.1' IDENTIFIED BY 'pass' REQUIRE SSL;
FLUSH PRIVILEGES;
Nu, superman
moet verbinden via SSL.
Als u geen clientsleutels wilt beheren, gebruikt u de eerdere clientsleutel en gebruikt u deze automatisch voor alle clients. Open het MySQL-configuratiebestand , bijvoorbeeld:
vim /etc/mysql/mysql.conf.d/mysqld.cnf
Voeg in het gedeelte [client]
de volgende opties toe:
ssl-ca = /home/ubuntu/mysqlcerts/ca.pem
ssl-cert = /home/ubuntu/mysqlcerts/client-cert.pem
ssl-key = /home/ubuntu/mysqlcerts/client-key.pem
Nu hoeft superman
alleen het volgende te typen om in te loggen via SSL:
mysql -h 127.0.0.1 -u superman -p
Verbinding maken vanuit een ander programma, bijvoorbeeld in Python, vereist meestal alleen een extra parameter voor de verbindingsfunctie. Een voorbeeld van Python:
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)
Referenties en verder lezen:
- 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 voor CentOS7 / RHEL7
Dit voorbeeld gaat uit van twee servers:
- dbserver (waar onze database staat)
- appclient (waar onze applicaties wonen)
FWIW, beide servers handhaven SELinux.
Meld u eerst aan bij dbserver
Maak een tijdelijke map voor het maken van de certificaten.
mkdir /root/certs/mysql/ && cd /root/certs/mysql/
Maak de servercertificaten
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
Verplaats servercertificaten naar / etc / pki / tls / certs / mysql /
Directorypad gaat uit van CentOS of RHEL (pas zo nodig aan voor andere distro's):
mkdir /etc/pki/tls/certs/mysql/
Zorg ervoor dat u machtigingen instelt voor de map en bestanden. mysql heeft volledige eigendom en toegang nodig.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
Configureer nu 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
Vervolgens
systemctl restart mariadb
Vergeet niet uw firewall te openen om verbindingen van appclient toe te staan (met behulp van IP 1.2.3.4)
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.
Start firewall nu opnieuw
service firewalld restart
Log vervolgens in op de MySQL-server van dbserver:
mysql -uroot -p
Geef het volgende op om een gebruiker voor de client te maken. note VEREIST SSL in GRANT-verklaring.
GRANT ALL PRIVILEGES ON *.* TO ‘iamsecure’@’appclient’ IDENTIFIED BY ‘dingdingding’ REQUIRE SSL;
FLUSH PRIVILEGES;
# quit mysql
Je zou nog steeds in / root / certs / mysql moeten zijn vanaf de eerste stap. Zo niet, ga dan terug naar de cd voor een van de onderstaande opdrachten.
Maak de clientcertificaten
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
Opmerking : ik gebruikte dezelfde algemene naam voor zowel server- als clientcertificaten. YMMV.
Zorg ervoor dat je nog steeds / root / certs / mysql / bent voor dit volgende commando
Combineer server- en client-CA-certificaat in één bestand:
cat server-cert.pem client-cert.pem > ca.pem
Zorg ervoor dat u twee certificaten ziet:
cat ca.pem
EINDE VAN HET SERVER-ZIJWERK VOOR NU.
Open een andere terminal en
ssh appclient
Maak zoals altijd een permanent thuis voor de clientcertificaten
mkdir /etc/pki/tls/certs/mysql/
Plaats nu de clientcertificaten (gemaakt op dbserver) op appclient. Je kunt ze overnemen of de bestanden één voor één kopiëren en plakken.
scp dbserver
# copy files from dbserver to appclient
# exit scp
Nogmaals, zorg ervoor dat u machtigingen instelt voor de map en bestanden. mysql heeft volledige eigendom en toegang nodig.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
U zou drie bestanden moeten hebben, elk eigendom van gebruiker mysql:
/etc/pki/tls/certs/mysql/ca.pem
/etc/pki/tls/certs/mysql/client-cert.pem
/etc/pki/tls/certs/mysql/client-key.pem
Bewerk nu de MariaDB / MySQL-configuratie van appclient in het gedeelte [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
Start de mariadb-service van appclient opnieuw:
systemctl restart mariadb
nog steeds op de client hier
Dit zou moeten terugkeren: ssl WAAR
mysql --ssl --help
Meld u nu aan bij de mysql-instantie van appclient
mysql -uroot -p
Moet JA zien voor beide variabelen hieronder
show variables LIKE '%ssl';
have_openssl YES
have_ssl YES
Aanvankelijk zag ik
have_openssl NO
Een snelle blik op mariadb.log onthulde:
SSL-fout: kan certificaat niet krijgen van '/etc/pki/tls/certs/mysql/client-cert.pem'
Het probleem was dat root eigendom was van client-cert.pem en de map daarin. De oplossing was om eigenaar te worden van / etc / pki / tls / certs / mysql / to mysql.
chown -R mysql:mysql /etc/pki/tls/certs/mysql
Start mariadb indien nodig opnieuw vanaf de stap direct hierboven
NU ZIJN WE KLAAR OM DE VEILIGE VERBINDING TE TESTEN
We zijn nog steeds op appclient hier
Probeer verbinding te maken met de MySQL-instantie van dbserver met behulp van de hierboven gemaakte account.
mysql -h dbserver -u iamsecure -p
# enter password dingdingding (hopefully you changed that to something else)
Met een beetje geluk moet je zonder fouten zijn ingelogd.
Om te bevestigen dat u verbonden bent met SSL ingeschakeld, geeft u de volgende opdracht op vanaf de MariaDB / MySQL-prompt:
\s
Dat is een backslash s, ook bekend als status
Dat toont de status van uw verbinding, die er ongeveer zo uit zou moeten zien:
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
Als u toestemming krijgt voor geweigerde fouten bij uw verbindingspoging, controleer dan uw GRANT-verklaring hierboven om te controleren of er geen losse tekens of 'tekens' zijn.
Als u SSL-fouten hebt, ga dan door deze handleiding om te controleren of de stappen correct verlopen.
Dit werkte op RHEL7 en zal waarschijnlijk ook werken op CentOS7. Kan niet bevestigen of deze exacte stappen elders werken.
Ik hoop dat dit iemand een beetje tijd en ergernis bespaart.