[JAVA] Connectez-vous à plusieurs instances MySQL avec SSL activé dans JDBC

Cet article

Ceci est l'article du 8ème jour du Speee Advent Calendar 2018! Veuillez vous abonner si vous le souhaitez.

Hier, je suis allé à [AWS re: Invent 2018] par @selmertsx! ](Https://tech.speee.jp/entry/2018/12/07/163341).

Aujourd'hui ** se connecte à plusieurs instances MySQL compatibles SSL dans JDBC **. Après avoir lu cet article, vous n'aurez peut-être pas à vous soucier de vous connecter à plusieurs instances MySQL avec SSL dans JDBC.

introduction

Auparavant, j'avais migré deux serveurs MySQL, maître et réplica, vers Cloud SQL de GCP, comme illustré dans la figure ci-dessous. Database移行 À ce moment-là, lorsque j'ai activé SSL, ce que je n'avais pas pu faire auparavant, il était facile de basculer dans Ruby (Rails), mais je ne pouvais pas le faire immédiatement en Java.

Cet article est un mémo de la solution à ce moment-là.

Soudain un aparté

Puisque c'est un gros problème, comment se connecter avec Rails. Pour Rails, ajoutez simplement les paramètres SSL à database.yaml. Il semble bon d'émettre un certificat avec Cloud SQL et de le placer au bon endroit. Je l'ai mis sous la forme suivante (extrait).

database.yaml


default: &default
    adapter: mysql2
    ...

  ssl: &ssl
    sslca: <%= ENV.fetch("HOGE_DATABASE_SSL_SERVER_CA") %>
    sslcert: <%= ENV.fetch("HOGE_DATABASE_SSL_CLIENT_CERT") %>
    sslkey: <%= ENV.fetch("HOGE_DATABASE_SSL_CLIENT_KEY") %>

  development:
    <<: *default
    database: hoge_development
    ...

  test:
    <<: *default
    database: hoge_test
    ...

  staging:
    <<: *default
    <<: *ssl
    database: hoge_staging
    ...

  production:
    <<: *default
    <<: *ssl
    database: hoge_production
    ...

L'application Rails qui a changé la destination de connexion dans ce travail de commutation a créé un modèle de base pour chaque DB dans lequel le database.yaml à lire a été modifié afin de se connecter à plusieurs DB, donc ajoutez-le à chaque database.yaml. J'ai pu le faire SSL.

C'est facile.

Sujet principal

Pour Java, c'est un peu plus compliqué que Rails. En principe, il est supposé qu'il existe un paramètre JDBC pour chaque destination de connexion.

Préparation

Dans le cas de Java, il n'est pas possible d'utiliser les trois pems car ils sont comme des Rails. Il doit être importé dans un conteneur au format Java Key Store (JKS). De plus, si vous souhaitez importer la clé privée, vous devez utiliser la commande ʻopenssh` pour la convertir au format PKCS12 avant de pouvoir l'importer dans JKS.

L'importation est la suivante. Créez ceci ** séparément pour chaque instance MySQL à laquelle vous souhaitez vous connecter.

$ keytool -import -file ./server-ca.pem -alias <Quelque chose de nom distinctif> -keystore <Nom de fichier du conteneur>
$ openssl pkcs12 -export -inkey ./client-key.pem -in ./client-cert.pem -name <Quelque chose de nom distinctif> -out ./temp.p12
$ keytool -importkeystore -srckeystore ./temp.p12 -srcstoretype pkcs12 -destkeystore <Nom de fichier du conteneur>

--Lors de la création d'un conteneur au format Java Key Store pour la première fois, un nouveau sera créé avec le nom de fichier spécifié. ―― keytool est un outil fourni avec JDK etc., et il peut ne pas être possible de passer le chemin. Il semble être dans bin sous le chemin d'installation de JDK.

Paramètres de connexion

Après avoir préparé JKS pour chaque base de données, ajoutez les paramètres à l'URL de connexion de JDBC. Spécifiez les six suivants.

L'exemple suivant est l'URL de connexion pour se connecter à une instance MySQL pour une réplique avec IP: www.xxx.yyy.zzz avec le pilote MySQL JDBC.

jdbc:mysql://www.xxx.yyy.zzz:3306/hoge?useSSL=true&amp;requireSSL=true&amp;clientCertificateKeyStoreUrl=file:///path/to/secrets/hoge_replica.jks&amp;clientCertificateKeyStoreType=JKS&amp;clientCertificateKeyStorePassword=<Définir le mot de passe&amp;trustCertificateKeyStoreUrl=file:///path/to/secrets/hoge_replica.jks&amp;trustCertificateKeyStoreType=JKS&amp;trustCertificateKeyStorePassword=<Définir le mot de passe>"

Si vous souhaitez l'utiliser en tant que maître, remplacez simplement le chemin du fichier JKS et le mot de passe par celui du maître. Vous pouvez maintenant vous connecter à plusieurs instances MySQL compatibles SSL.

De côté

Une façon de se connecter à une instance MySQL avec SSL activé dans Java était de la spécifier comme option lors de l'exécution de Java. Au départ, j'ai essayé de combiner les certificats et les clés maître et réplique en un seul JKS, mais pour une raison quelconque, le programme ne fonctionnait pas correctement et j'étais en difficulté.

Après avoir étudié diverses choses, il semble que ce soit un bogue Java? spécification? Donc, si l'émetteur (dans le cas de CloudSQL, c'est Google) met plusieurs certificats identiques dans un JKS, veuillez sélectionner de manière appropriée pour chaque destination de connexion DB ** pas ** est. Ainsi, par exemple, lorsque vous essayez de vous connecter à la réplique avec le certificat du maître, la connexion SSL est coupée.

en conclusion

Depuis que j'ai fait une instance MySQL de CloudSQL, je l'ai utilisée comme MySQL dans le texte, mais je pense que l'application sera efficace lors de l'établissement d'une connexion SSL en utilisant JDBC en Java.

Recommended Posts

Connectez-vous à plusieurs instances MySQL avec SSL activé dans JDBC
Connectez-vous à MySQL 8 avec Java
Activer ou non SSL lors de l'utilisation de JDBC avec MySQL.
[Java] Connectez-vous à MySQL
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Comment connecter MySQL / MariaDB + HikariCP avec Liferay 7 / DXP
Connectez-vous à DB avec Java
Connectez-vous à Oracle avec Eclipse!
[Android] Connectez-vous à MySQL (non terminé)
J'ai essayé de me connecter à MySQL en utilisant le modèle JDBC avec Spring MVC
Opération pour connecter plusieurs Streams @Java
Connexion JDBC avec MySQL 8.x * Notes *
mysql2 ne s'installe pas avec l'installation du bundle
Connectez-vous au serveur Rails avec iPhone
Mettre à jour MySQL de 5.7 à 8.0 avec Docker
Je souhaite sélectionner plusieurs éléments avec une disposition personnalisée dans la boîte de dialogue
[Java] J'ai installé JDBC et essayé de me connecter avec servlet + MySQL. (Il existe une version utilisant DAO / Bean)
Mémo pour avoir plusieurs valeurs dans HashMap
Déployer sur heroku avec Docker (Rails 6, MySQL)
Modifier Mysql avec des commandes dans l'environnement Docker
Comment utiliser MySQL dans le didacticiel Rails
Connectez-vous de Java à MySQL à l'aide d'Eclipse
Comment rediriger vers http-> https lorsque SSL est activé dans l'environnement Rails × Heroku
Solution qui donne une erreur lors de la tentative de connexion à DB (MySQL) avec Java
[Rails] Comment enregistrer plusieurs enregistrements dans la table intermédiaire avec une association plusieurs-à-plusieurs
[Java] J'ai essayé de me connecter en utilisant le pool de connexion avec Servlet (tomcat) & MySQL & Java