Java 如何使用 Play Framework 通过 SSL 连接到远程 MySQL 数据库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27536380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:32:37  来源:igfitidea点击:

How to connect to a remote MySQL database via SSL using Play Framework?

javamysqlscalaplayframeworkamazon-rds

提问by Michael Zajac

I deploy Play applications in distributed environments, backed by a remote MySQL database. Specifically, the applications are hosted on heroku, and the database is on Amazon RDS (though this really applies to any remote database connection). Since the database isn't just on localhost, I'd prefer that the remote MySQL connection is made through SSL for security.

我在分布式环境中部署 Play 应用程序,由远程 MySQL 数据库支持。具体来说,应用程序托管在 heroku 上,数据库在 Amazon RDS 上(尽管这确实适用于任何远程数据库连接)。由于数据库不仅仅在本地主机上,为了安全起见,我更喜欢通过 SSL 建立远程 MySQL 连接。

Given a CA certificate to trust, how can I configure a Play application to connect to the MySQL server through SSL, only if the host certificate can be verified?

给定要信任的 CA 证书,仅当可以验证主机证书时,如何配置 Play 应用程序以通过 SSL 连接到 MySQL 服务器?

Assume this as the current database configuration:

假设这是当前的数据库配置:

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://url.to.database/test_db"
db.default.user=root 
db.default.password="...."

采纳答案by Michael Zajac

Assuming you already have the CA certificate setup for the MySQL server (which is the case when using Amazon RDS), there are a few steps to make this work.

假设您已经为 MySQL 服务器设置了 CA 证书(使用 Amazon RDS 时就是这种情况),有几个步骤可以完成这项工作。

First, the CA certificate should be imported into a Java KeyStore file using keytool, which comes with the JDK. The KeyStore in this case will contain all of the CA certificates we want to trust. For Amazon RDS, the CA cert can be found here. With mysql-ssl-ca-cert.pemin your working directory, you can run the following command:

首先,应该使用JDK 附带的keytool将 CA 证书导入到 Java KeyStore 文件中。在这种情况下,KeyStore 将包含我们想要信任的所有 CA 证书。对于 Amazon RDS,可以在此处找到 CA 证书。随着mysql-ssl-ca-cert.pem在你的工作目录,可以运行下面的命令:

keytool -import -alias mysqlServerCACert -file mysql-ssl-ca-cert.pem -keystore truststore.jks

Which will create a new Java KeyStore file called truststore.jksafter prompting you to enter a KeyStore password and asking if you want to trust the certificate (yes, you do). If you already have a truststore file, you can run the same command, replacing truststore.jkswith the path to your existing KeyStore (you'll then be prompted for the password of the existing KeyStore, instead). I usually place truststore.jksin my confdirectory.

这将创建一个新的 Java KeyStore 文件,truststore.jks在提示您输入 KeyStore 密码并询问您是否要信任该证书(是的,您相信)后调用。如果您已经有一个信任库文件,您可以运行相同的命令,用truststore.jks现有密钥库的路径替换(然后会提示您输入现有密钥库的密码)。我通常放在truststore.jks我的conf目录中。

Second, in application.confyou need to add a few JDBC URL parameters to the database URL:

其次,application.conf需要在数据库URL中添加几个JDBC URL参数:

verifyServerCertificate=true- Refuse to connect if the host certificate cannot be verified.

verifyServerCertificate=true- 如果无法验证主机证书,则拒绝连接。

useSSL=true- Connect using SSL.

useSSL=true- 使用 SSL 连接。

requireSSL=true- Refuse to connect if the MySQL server does not support SSL.

requireSSL=true- 如果 MySQL 服务器不支持 SSL,则拒绝连接。

For example, if your current database URL is:

例如,如果您当前的数据库 URL 是:

db.default.url="jdbc:mysql://url.to.database/test_db"

Then it should now be:

那么现在应该是:

db.default.url="jdbc:mysql://url.to.database/test_db?verifyServerCertificate=true&useSSL=true&requireSSL=true"

Lastly, there are a few command-line options that need to be passed when starting the Play server to configure the truststore MySQL-Connector/J will use. Assuming my truststore.jksfile is located in the confdirectory, and the password is password, I would start my server (in dev mode) like this:

最后,在启动 Play 服务器以配置 MySQL-Connector/J 将使用的信任库时,需要传递一些命令行选项。假设我的truststore.jks文件位于conf目录中,密码是password,我会像这样启动我的服务器(在开发模式下):

activator run -Djavax.net.ssl.trustStore="conf/truststore.jks" -Djavax.net.ssl.trustStorePassword="password"


In addition to this, I also like to make sure that it's impossible to connect to the database without using SSL, just in case the options somehow get messed up at the application level. For example if db.default.user=root, then when logged in as rootin the MySQL server, run the following queries:

除此之外,我还想确保在不使用 SSL 的情况下无法连接到数据库,以防万一选项在应用程序级别以某种方式混乱。例如,如果db.default.user=root,则root在以 MySQL 服务器身份登录时,运行以下查询:

GRANT USAGE ON *.* TO 'root'@'%' REQUIRE SSL;
FLUSH PRIVILEGES;

回答by privatejava

Just to update on All.

只是为了更新所有。

  1. You can download the bundle certificate which contains many certificates of Amazon from here https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem.
  2. If you see the content of that pem it contains many certificates. Split it to multiple PEM files where each file will contain like this

    -----BEGIN CERTIFICATE-----
        [main content]
    -----END CERTIFICATE-----
    
  3. Then run this command for every cert file that you created

    keytool -import \
    -keystore  $JAVA_HOME/jre/lib/security/cacerts \
    -storepass changeit -noprompt \
    -alias $ALIAS -file $YOUR_INDIVIDUAL_PEM_FILE
    
  1. 您可以从这里https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem下载包含许多亚马逊证书的捆绑证书。
  2. 如果您看到该 pem 的内容,它包含许多证书。将其拆分为多个 PEM 文件,其中每个文件将包含这样

    -----BEGIN CERTIFICATE-----
        [main content]
    -----END CERTIFICATE-----
    
  3. 然后为您创建的每个证书文件运行此命令

    keytool -import \
    -keystore  $JAVA_HOME/jre/lib/security/cacerts \
    -storepass changeit -noprompt \
    -alias $ALIAS -file $YOUR_INDIVIDUAL_PEM_FILE
    

Just for making your life easy somebody has just created bash script for this : https://gist.github.com/shareefhiasat/dabe5e96dbd7123c7b101aac1c0eca8a

只是为了让您的生活更轻松,有人为此创建了 bash 脚本:https: //gist.github.com/shareefhiasat/dabe5e96dbd7123c7b101aac1c0eca8a