【问题标题】:How to configure a Play application to use Let's Encrypt certificate?如何配置 Play 应用程序以使用 Let's Encrypt 证书?
【发布时间】:2016-11-15 08:24:51
【问题描述】:

获得证书后,如何从中生成 JKS 密钥库?

如何配置 Play 应用程序以使用此密钥库?

我还有什么需要做的吗?

【问题讨论】:

标签: https playframework lets-encrypt


【解决方案1】:

这是获取(更新)letsencrypt 证书的脚本:

#!/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

您可以安排一个 cron 作业来定期运行此脚本,因为letsencrypt 证书目前在 90 天后过期。

获得证书后,您需要修改应用程序启动脚本如下:

/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

快到了。当您运行该应用程序时,您将获得来自SSL LabsA- 评级。评级下调与Forward Secrecy有关。为了解决前向保密问题(并获得完整的 A 评级),您需要通过实现自定义 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
  }
}

别忘了设置

play.server.https.engineProvider=controllers.CustomSslEngineProvider

在您的 application.conf 中。

使用 Play 2.5.x 测试

【讨论】:

  • “mv /etc/letsencrypt”不是一个好主意。可能会毁坏他人的证件和档案。如果您确实想使用干净的目录,可以使用 --config-dir 选项:letsencrypt.readthedocs.io/en/latest/using.html
  • 当然。我只有一张证书,所以我不在乎。这个答案是关于配置 Play 而不是管理证书。随意修改示例脚本。
  • 非常有用的答案。只是有点过时了。我刚才必须这样做,这是我的文件:stackoverflow.com/a/62659945/49153
【解决方案2】:

我在各种论坛中搜索,最后我想出了一个非常快速(并且几乎是自动化)的解决方案: 首先,在他们建议的letsencrypt网站上,运行这些:

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot 

然后运行

sudo certbot certonly --standalone -d domain.name.com

(对于通配符,它​​有点复杂,但这个过程的其余部分应该是相同的)

此时它应该告诉您密钥在哪里,在某个目录上,例如 /etc/letsencrypt/live/domain.name.com/*.pem(三个密钥:fullchain、privkey 和一个链)

然后运行openssl(编辑域名和密码)

sudo openssl pkcs12 
        -export -in /etc/letsencrypt/live/domain.name.com/fullchain.pem 
        -inkey /etc/letsencrypt/live/domain.name.com/privkey.pem 
        -out cert_and_key.p12 
        -CAfile /etc/letsencrypt/live/domain.name.com/chain.pem 
        -caname root 
        -passout pass:<insert some password here>

然后是keytool(编辑keystore路径和密码)

sudo keytool 
  -importkeystore 
  -srcstorepass <the password you inserted above>
  -destkeystore <path/key>.jks 
  -srckeystore cert_and_key.p12 
  -srcstoretype PKCS12 
  -storepass <the password you inserted above>

最后你应该在上面写的路径上找到 jks 键。

在 application.conf 中:

play.server.https.keyStore.path = "<path/key>.jks"
play.server.https.keyStore.type = "JKS"
play.server.https.keyStore.password = "<the password you inserted above>"

在 Ubuntu 16 和 18 上使用 Play 2.6.15 测试

【讨论】:

  • 太好了,我有 apache CDN 和 playframework,我为 apache 添加了letsencrypt,然后配置这部分并与 play2.5 配合良好
【解决方案3】:

我最近不得不这样做,这是我的文件:

#!/usr/bin/env bash

sudo killall java #stop the application gracefully

rm -rf /etc/letsencrypt.bak

cp -r /etc/letsencrypt /etc/letsencrypt.bak

certbot renew --standalone

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

在此之后,您需要在使用与接受的答案相同的格式运行应用程序时设置属性:

sudo /path/to/app -Dhttp.port=80 -Dhttps.port=443 -Dplay.server.https.keyStore.path=/etc/letsencrypt/live/api.ali.actor/keyStore.jks -Dplay.server.https.keyStore.password=your_password -Djdk.tls.ephemeralDHKeySize=2048 -Djdk.tls.rejectClientInitiatedRenegotiation=true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2017-07-05
    • 2016-08-09
    • 2017-01-18
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多