How to configure the Play application to use Let encrypt certificate?

Once I get the certificate, how do I create a JKS key store?

How to configure the Play app to use this keystore?

Anything else I need to do?

+6
source share
1 answer

Here is the script to get (renew) the letencrypt certificate:

#!/bin/bash /path/to/your/app/stop # stop the play application; especially if it is running on port 80 otherwise the certificate generation will fail rm -rf /etc/letsencrypt.bak mv /etc/letsencrypt /etc/letsencrypt.bak ./letsencrypt-auto certonly --standalone -n -m email@example.com --agree-tos -d example.com -d www.example.com cd /etc/letsencrypt/live/example.com openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out cert_and_key.p12 -CAfile chain.pem -caname root -passout pass:your_password keytool -importkeystore -srcstorepass your_password -destkeystore keyStore.jks -srckeystore cert_and_key.p12 -srcstoretype PKCS12 -storepass your_password /path/to/your/app/start # start the application 

You can schedule a cron job to run this script periodically, as authentication certificates expire after 90 days.

After receiving the certificate, you need to change the launch of the script application as follows:

 /path/to/your/app/app_name_script -Dhttps.port=443 -Dplay.server.https.keyStore.path=/etc/letsencrypt/live/example.com/keyStore.jks -Dplay.server.https.keyStore.password=your_password -Djdk.tls.ephemeralDHKeySize=2048 -Djdk.tls.rejectClientInitiatedRenegotiation=true # ... more parameters if required 

Almost there. When you launch the application, you get an A - rating from SSL Labs . The downgrade is due to Forward Secrecy . To understand the Forward Secrecity problem (and get a full A rating), you need to specify the order of the cipher suites by running your own SSLEngineProvider:

 package controllers import java.nio.file._ import java.security.KeyStore import javax.net.ssl._ import play.core.ApplicationProvider import play.server.api._ class CustomSslEngineProvider(appProvider: ApplicationProvider) extends SSLEngineProvider { val priorityCipherSuites = List( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA") def readPassword(): Array[Char] = System.getProperty("play.server.https.keyStore.password").toCharArray def readKeyInputStream(): java.io.InputStream = { val keyPath = FileSystems.getDefault.getPath(System.getProperty("play.server.https.keyStore.path")) Files.newInputStream(keyPath) } def readKeyManagers(): Array[KeyManager] = { val password = readPassword() val keyInputStream = readKeyInputStream() try { val keyStore = KeyStore.getInstance(KeyStore.getDefaultType) keyStore.load(keyInputStream, password) val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm) kmf.init(keyStore, password) kmf.getKeyManagers } finally { keyInputStream.close() } } def createSSLContext(): SSLContext = { val keyManagers = readKeyManagers() val sslContext = SSLContext.getInstance("TLS") sslContext.init(keyManagers, Array.empty, null) sslContext } override def createSSLEngine(): SSLEngine = { val ctx = createSSLContext() val sslEngine = ctx.createSSLEngine val cipherSuites = sslEngine.getEnabledCipherSuites.toList val orderedCipherSuites = priorityCipherSuites.filter(cipherSuites.contains) ::: cipherSuites.filterNot(priorityCipherSuites.contains) sslEngine.setEnabledCipherSuites(orderedCipherSuites.toArray) val params = sslEngine.getSSLParameters params.setUseCipherSuitesOrder(true) sslEngine.setSSLParameters(params) sslEngine } } 

Do not forget to install

play.server.https.engineProvider = controllers.CustomSslEngineProvider

in the .conf application .

Tested with game 2.5.x

+9
source

All Articles