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

我在分布式环境中部署Play应用程序,由远程MySQL数据库支持。 具体来说,应用程序托管在heroku上,数据库位于Amazon RDS上(尽管这实际上适用于任何远程数据库连接)。 由于数据库不仅仅是在localhost上,我更喜欢远程MySQL连接是通过SSL进行安全的。

给定要信任的CA证书,只有在可以validation主机证书的情况下,如何配置Play应用程序才能通过SSL连接到MySQL服务器?

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

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

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

首先,应使用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 

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

其次,在application.conf您需要向数据库URL添加一些JDBC URL参数:

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

useSSL=true – 使用SSL连接。

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

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

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

那么它现在应该是:

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

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

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

除此之外,我还想确保在不使用SSL的情况下连接到数据库是不可能的,以防万一选项在应用程序级别被搞砸了。 例如,如果db.default.user=root ,那么当以root身份登录MySQL服务器时,请运行以下查询:

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