Posted at

EB の Java アプリケーションから CloudSQL に SSL 接続してみた

More than 3 years have passed since last update.


はじめに

結論から言うと、 I/O が厳しくてお蔵入り という感じです


前提


  • EB で稼働しているアプリケーションから CloudSQL へ SSL 接続する

  • EB アプリケーションは VPN にいる

  • Java から MySQL へ SSL 接続するときは、 keystore、truststore ファイルが必要になる

  • CI は Bamboo を使っている


手順


  1. CloudSQL の SSL 証明書をダウンロードする

  2. keystore、truststore ファイルを作成する

  3. CI(Bamboo) に keystore、truststore 情報を持たせる

  4. EB に JVM 起動引数を設定する

  5. (EB アプリケーションが Private Network の場合) NAT サーバーのポートを開く

  6. CloudSQL で NAT サーバーの IP を承認する


CloudSQL の各種 SSL 証明書をダウンロードする

公式: Configuring SSL for Instances - Cloud SQL — Google Cloud Platform

CloudSQL のコンソール画面を開き、 アクセス制御 → SSL でクライアント証明書を作成できる

クライアント証明書を作成した直後に証明書をダウンロードできるが、その時に MySQL へ SSL 接続するための MySQL コマンドも一緒に表示してくれるので、すぐに接続してみることができる

1_cloudsql_cert.png


keystore、truststore ファイルを作成する


truststore ファイルを作成する

RDS のように中間証明書だけで SSL 接続できる場合は、次の keystore は作成しなくてよい

keytool -import -alias mysqlServerCACert -file server-ca.pem -keystore truststore


keystore ファイルを作成する


pkcs12 ファイルを作成する

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out client.p12


pkcs12 ファイルを keystore に変換する

keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore keystore


CI(Bamboo) に keystore、truststore 情報を持たせる

keystore、truststore 情報は git 管理せず CI に持たせる

今回は Bamboo を使用したので、 Bamboo の Script ジョブを追加した

2_bamboo_script.png



  • Script locationInline


    • truststore・keystore (を base64 変換した) 情報を CI に持たせるため




  • Working sub directory は Java プロジェクト名を設定した


  • Script body は以下のとおり



    • ./src/main/resources/ 配下に配置することで keystore・truststore が classpath に配置される



echo (truststore を base64 エンコードした文字列) > base64ed-truststore

base64 -d base64ed-truststore > ./src/main/resources/truststore
echo (keystore を base64 エンコードした文字列) > base64ed-keystore
base64 -d base64ed-keystore > ./src/main/resources/keystore


EB に JVM 起動引数を設定する


  • AWS Management Console でアプリケーションの画面を開き、 Configuration > Software Configuration に以下の JVM 引数を設定する

-Djavax.net.ssl.keyStore=/usr/share/(Tomcat のディレクトリ)/webapps/ROOT/WEB-INF/classes/keystore 

-Djavax.net.ssl.keyStorePassword=(keystore 作成時に設定したパスワード)
-Djavax.net.ssl.trustStore=/usr/share/(Tomcat のディレクトリ)/webapps/ROOT/WEB-INF/classes/truststore
-Djavax.net.ssl.trustStorePassword=(truststore 作成時に設定したパスワード)


(EB アプリケーションが Private Network の場合) NAT サーバーのポートを開く

アプリケーションが VPN 内にあり、 CloudSQL との通信ポートが開いていない場合はポートを開く

今回は NAT サーバーに SecurityGroup を追加して 3306 番ポートを開けた


CloudSQL で NAT サーバーの IP を承認する

CloudSQL のコンソール画面で アクセス制御承認 から NAT サーバーの IP を承認する

3_permit_ip.png


おまけ

アプリケーションを CloudSQL にある MySQL へ接続しようとしたところ、無理めなエラーメッセージの文字化けに遭遇したので、、、

4 15, 2016 11:25:46 <B8><E1><B8><E5> org.apache.catalina.core.StandardWrapperValve invoke

<BD><C5><C2><E7>: <A5><B5><A1><BC><A5>֥<EC><A5>å<C8> project-dispatcher <A4><CE>Servlet.service()<A4><AC><CE><A4>
<F2><C5><U+A932><A4>ޤ<B7><A4><BF>
java.net.ConnectException: <C0><DC>³<A4><AC><A5><BF><A5><A4><A5><A5><A6><A5>Ȥ<B7><A4>ޤ<B7><A4><BF>

日本語を捨てることで文字化けを回避するに至る場面ではかなり途方にくれました

Tomcat catalina.outの英語/日本語切り替え LANGの設定でOK | Rutakeの技術メモ

アドバイスをくれた皆さん、ありがとうございます!!