【问题标题】:Tomcat : Installing LetsEncrypt certificate for https, not workingTomcat:为 https 安装 LetsEncrypt 证书,不起作用
【发布时间】:2016-08-23 07:05:57
【问题描述】:

我有一个在我们的服务器上运行的 Apache Tomcat 实例,我正在尝试将 LetsEncrypt 用于 https。我找到了一些脚本来导入证书,我可以在密钥库中检查证书是否已导入。

很遗憾,https 无法正常工作。每当我尝试连接时,它都会一直等待(进度条旋转)。我不知道我做错了什么。

脚本:

cd /var/git/letsencrypt
#git pull origin master
iptables -I INPUT -p tcp -m tcp --dport 9999 -j ACCEPT
iptables -t nat -I PREROUTING -i $networkdevice -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9999

./letsencrypt-auto certonly --standalone --test-cert --break-my-certs -d $mydomain --renew-by-default --email $myemail --agree-tos


iptables -t nat -D PREROUTING -i $networkdevice -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 9999
iptables -D INPUT -p tcp -m tcp --dport 9999 -j ACCEPT

$keytooldir/keytool -delete -alias root -storepass NEWPASS -keystore $keystoredir
$keytooldir/keytool -delete -alias tomcat -storepass NEWPASS -keystore $keystoredir

openssl pkcs12 -export -in $certdir/fullchain.pem -inkey $certdir/privkey.pem -out $certdir/cert_and_key.p12 -name tomcat -CAfile $certdir/chain.pem -caname root -password pass:aaa

$keytooldir/keytool -importkeystore -srcstorepass aaa -deststorepass NEWPASS -destkeypass changeit -srckeystore $certdir/cert_and_key.p12 -srcstoretype PKCS12 -alias tomcat -keystore $keystoredir
$keytooldir/keytool -import -trustcacerts -alias root -deststorepass NEWPASS -file $certdir/chain.pem -noprompt -keystore $keystoredir

输出:

iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Checking for new version...
Requesting root privileges to run letsencrypt...

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/domina-name/fullchain.pem.
   Your cert will expire on 2016-07-27. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Certificate was added to keystore

Apache tomcat 连接器:

 <Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="200"
              scheme="https" secure="true" clientAuth="false"  sslProtocol="TLS"
                keystoreFile="/root/.keystore" keystorePass="newPASS" />

OpenSSL 连接输出:

openssl s_client -connect domain_name.de:443
CONNECTED(00000003)

卡在已连接状态。

我做错了什么。有任何想法吗?谢谢你。

更新

当我检查时,我得到了一个无法恢复密钥的异常。我认为可能是因为Tomcat需要Key-pass,所以我用以下命令更改了密钥的密码,但仍然错误:

openssl rsa -aes192 -in yourprivatekeywithoutpassword.pem -out newprivatekeywithpassword.pem

错误日志:

SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-nio-443"]
java.security.UnrecoverableKeyException: Cannot recover key
        at sun.security.provider.KeyProtector.recover(KeyProtector.java:328)
        at sun.security.provider.JavaKeyStore.engineGetKey(JavaKeyStore.java:146)
        at sun.security.provider.JavaKeyStore$JKS.engineGetKey(JavaKeyStore.java:56)
        at sun.security.provider.KeyStoreDelegator.engineGetKey(KeyStoreDelegator.java:96)
        at sun.security.provider.JavaKeyStore$DualFormatJKS.engineGetKey(JavaKeyStore.java:70)
        at java.security.KeyStore.getKey(KeyStore.java:1023)
        at sun.security.ssl.SunX509KeyManagerImpl.<init>(SunX509KeyManagerImpl.java:133)
        at sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:70)
        at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:256)

【问题讨论】:

    标签: java apache tomcat ssl


    【解决方案1】:

    我终于能够通过更改从中检索证书的服务器 URL 来解决这个问题。如您所见,我收到证书不受信任的错误。发生这种情况是因为证书来自临时服务器。

    我将更新中带有server参数的配置文件更改为

    https://acme-v01.api.letsencrypt.org/directory
    

    之后,我从letsEncrypt 检索了所有证书,并再次安装了它们。

    输出:

    openssl s_client -connect domain.de:443
    CONNECTED(00000003)
    depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
    verify return:1
    depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
    verify return:1
    depth=0 CN = domain.de
    verify return:1
    ---
      Verify return code: 0 (ok)
    

    这个问题特此解决并结束。感谢您的时间。

    【讨论】:

      【解决方案2】:

      我唯一能想到的是,你有一个不同的 keystorePass 和 keyPass,而没有在连接器上提供 keyPass。 Tomcat 尝试使用与密钥库相同的密码访问密钥,但失败并产生您看到的错误。

      在您的更新中,您更新了 pem 文件;您是否将其导入回密钥库以更新 tomcat 正在使用的内容?我假设你做到了,但必须要求完整性。如果你没有这样做,那么密钥密码更改对 tomcat 正在使用的密钥库没有任何作用。

      我能提供的唯一解决方案是将 keyPass 属性添加到您的连接器以查看是否有效。我在本地进行了测试,并且具有不同的密钥库和密钥密码确实会产生错误。将 keyPass 添加到连接器为我解决了这个问题。

      【讨论】:

      • 如果你所说的任何一个都是真的,我会很高兴,通过是相等的,脚本在评论代码以检索新密钥之后再次重新运行,因此不会覆盖,然后根据脚本重新导入。 ..我也很困惑发生了什么...与使用密码更改命令将算法更改为 aes-192 的命令有什么关系?
      • 它不应该,但要确定我必须测试它。您可以使用 jdb 进行一些调试,以验证传递给 JSSE 的 keyPass 和 keystorePasses 是您认为的那样。用JPDA_SUSPEND=y启动tomcat,用jdb附加,然后:使用stop at org.apache.tomcat.util.net.jsse.JSSESocketFactory:588,run,print keyPass,print keystorePass
      • 如果这些密码是正确的并且确实可以访问密钥库/密钥,那么我认为您可能遇到了 sun.security 中低于 tomcat 的错误。
      • 我该怎么办?
      【解决方案3】:

      对于你的问题,我想模块化你的问题。

      起初,

      iptables v1.4.21:无法初始化 iptables 表 `nat':表可以 不存在(你需要 insmod 吗?)也许 iptables 或你的内核 需要升级。

      对于这个问题,可以通过改变ip_tables位置来解决。命令如下所示:

      sudo modprobe ip_tables
      sudo echo 'ip_tables' >> /etc/modules
      

      完整部分,您可以通过此链接:iptables: Table does not exist (do you need to insmod?)

      资源链接:

      1. iptables v1.4.14: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
      2. iptables nat does not exist

      其次,我要修复部分

      java.security.UnrecoverableKeyException:无法恢复密钥

      当密钥管理器使用错误/错误的密码实际上不匹配或有时大写小写问题或您的密钥库可能已损坏时,实际上会发生此问题。 您必须确保 KeyStore 密码和 The Keypassword 相同。

      为此,您可以通过两种方式进行检查-

      You can change/list the key in keytool with the same password or another

      keytool -keypasswd -new changeit -keystore cacerts -storepass changeit -alias someapp -keypass password
      

      以上示例将密码从密码更改为changeit。如果私钥密码是密码,则此命令将成功。

      您也可以使用别名。您需要在自定义 X509KeyManager 中实现 getPrivateKey(String alias) 以考虑到这一点。特别是,它必须使用每个别名的正确密码从您的 KeyStore 实例加载密钥(请参阅getKey(String alias, char[] password))。

      归功于@bruno


      接下来,

      我看到的另一件事是,您有时在命令模式下使用NEWPASS,在tomcat 连接器中使用newPASS 作为密码。希望有一些不匹配。请检查并验证。

      Tomcat Recommendation for preparing the certificate keystore:

      Tomcat使用的默认密码是“changeit”(全小写), 尽管您可以根据需要指定自定义密码。你也会 需要在 server.xml 配置中指定自定义密码 文件

      您必须在此处使用与密钥库相同的密码 密码本身。这是 Tomcat 实现的限制。

      port 属性是 Tomcat 将使用的 TCP/IP 端口号 监听安全连接。您可以将其更改为任何端口号 您希望(例如 https 通信的默认端口, 是 443)。但是,特殊设置(超出本文档的范围) 在许多端口号低于 1024 的端口上运行 Tomcat 是必要的 操作系统。

      完成配置更改后,必须重启Tomcat

      你也可以通过SSL Support

      资源链接:

      1. Can not get key from KeyStore

      更新:

      如果第一部分不能正常工作,请按照@douglas's 服务提供商的回答如下:

      这是我们使用的虚拟化系统(OpenVZ)的限制, 基本的 iptables 规则是可能的,但那些使用 nat 表的规则是可能的。

      如果这确实是个问题,我们可以为您提供迁移到其他 我们开始为客户提供系统虚拟化 (KVM)。

      所以您必须将服务器迁移到新系统。可以的话可以试试。

      【讨论】:

      • 你提到的大部分信息都与密码有关,到处都是一样的。我用 newPass 手动替换了所有地方的密码,以便在 SO 中发布它,如果这造成了混乱,我很抱歉。证书已经在那里了。我在这个问题上前进了一点,我还在 Github 上发布了一个问题:github.com/letsencrypt/letsencrypt/issues/2920。关于我应该直接用这个更新问题还是将其添加为更新的任何建议。谢谢。
      • @WeareBorg 请将连接器端口 443 更改为 8443?如果有任何更新,请告诉我?
      • 改端口为8443,重启Tomcat,调用openssl连接8443,同样报错。
      • 能否请您通过此链接更多关注tomcat.apache.org/tomcat-6.0-doc/…
      • @WeareBorg 这是我的荣幸。再次感谢您分享您的答案和社区详细信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2018-09-20
      • 2019-03-26
      • 2016-08-19
      • 1970-01-01
      相关资源
      最近更新 更多