在 TOMCAT5.5 上 SSL 的 APR 实现和 SSL 的 JSSE 实现有啥区别
Posted
技术标签:
【中文标题】在 TOMCAT5.5 上 SSL 的 APR 实现和 SSL 的 JSSE 实现有啥区别【英文标题】:What is the difference between APR implementation of SSL and JSSE implementation of SSL on TOMCAT5.5在 TOMCAT5.5 上 SSL 的 APR 实现和 SSL 的 JSSE 实现有什么区别 【发布时间】:2011-03-05 23:05:39 【问题描述】:我在 TOMCAT 5.5 上配置 SSL 以支持 HTTPS,所以我参考了http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html,它详细说明了如何实现 SSL。
本文档描述了两种实现 SSL 的方式,即 APR 实现和 JSSE 实现。我想知道它们之间的区别是什么,包括它们的缺点和优点。
【问题讨论】:
【参考方案1】:不同之处在于 JDK 使用自己的 SSL 实现,而 APR 使用计算机上安装的内容,即大多数情况下的 OpenSSL。
如果你对 https 有中低流量,Java 解决方案很好,但对于非常重的负载(例如当大多数页面在 https 上运行时),OpenSSL 原生解决方案要好得多,并且可以重新编译和优化,因此它会运行得更快并且消耗更少的资源。 然而,APR+OpenSSL 的主要缺点是它需要更多的配置和调整 + 测试,Java 版本开箱即用。
我通常的做法是始终使用默认的 Java SSL 解决方案和监控工具,如果流量变大,然后,然后才花精力调整 APR 解决方案。
【讨论】:
衷心感谢您的帮助。这个很好的答案对我帮助太大了!再次谢谢你! 用于 JSSE 的 TG,因为它不易受到心脏出血的影响 (qnalist.com/questions/4812562/…) 最后我检查了它是完全自动配置的,只要你有可用的 Tomcat Native 库。为了使 APR 更简单,本机库甚至可以在 RPM 中使用。换句话说,如果您使用的是标准的现代发行版,那么您没有理由不通过 Tomcat Native 库使用 APR。【参考方案2】:下表取自Tomcat official documents,显示了连接器之间的关系。表中描述的最重要的区别是:
从 Tomcat 5.5.x 开始支持 APR,在 Tomcat 6.x 中添加了 NIO,在 Tomcat 8.x 中添加了 NIO2。 APR 只能使用 OpenSSL,但 NIO 和 NIO2 可以使用 JSSE 或 OpenSSL。 执行 SSL 握手时 APR 会阻塞,而其他两个则不会。另请注意this statement,它显示了自Tomcat 8.5 以来JSSE 和OpenSSL 的配置属性之间的良好兼容性:
NIO 和 NIO2 连接器使用 JSSE Java SSL 实现或 OpenSSL 实现,而 APR/native 连接器仅使用 OpenSSL。在 Tomcat 8.5 之前,JSSE 和 OpenSSL 使用了不同的配置属性。从 Tomcat 8.5 开始,JSSE 和 OpenSSL 都尽可能使用通用配置属性。此外,如果使用 JSSE OpenSSL 实现,可以使用 JSSE 或 APR 属性设置配置(注意:但不能在同一配置中同时使用这两种类型)。这是为了帮助在 SSL 连接器的连接器实现之间进行更简单的切换。
Tomcat SSL how-to 有a section,它深入挖掘了连接器之间的关系。以下是强制 NIO 或 NIO2 使用 JSSE 的方法:
<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO implementation -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
port="8443" .../>
<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO2 implementation -->
<Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
port="8443" .../>
下面是如何配置 NIO 以使用 OpenSSL(与 NIO2 类似):
<!-- Define an HTTP/1.1 Connector on port 8443, JSSE NIO implementation and OpenSSL -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443"
sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
.../>
最后,配置 APR:
<!-- Define an HTTP/1.1 Connector on port 8443, APR implementation -->
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
port="8443" .../>
【讨论】:
【参考方案3】:低于 5.5.29 的 Tomcat 版本是否不支持新的连接器属性“allowUnsafeLegacyRenegotiation”并且如果您使用旧的 java 机器(jvm 1.6 或更早版本,没有安全补丁)并且不想更新或 java不是 Tomcat 的唯一方法 - 是使用 APR。 见:
About security patches against RFC 5746 CVE-2009-3555
About Tomcat patches
About MITM vulnerability
【讨论】:
那么 Java 8 中的新 JSSE 呢?他们说它支持通过“现代” CPU 上的 AES 加密指令进行硬件加速,它还会比 APR 更慢(或更糟)吗?【参考方案4】:使用 APR 时,Tomcat 可能会使用易受 Heartbleed 错误 (http://heartbleed.com) 影响的 OpenSSL 引擎。 然后你可以简单地从 APR 切换到你的 server.xml:
<-- Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
port="8443" .../>
致不易受此错误影响的 Java SSL 实现:
<-- Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
port="8443" .../>
或者,如果您仍然想使用 APR,请确保使用已使用不易受 Heartbleed 攻击的 OpenSSL 版本(OpenSSL 1.0.1g 或更高版本)编译的 Tomcat Native 库,请参阅https://issues.apache.org/bugzilla/show_bug.cgi?id=56363。
【讨论】:
以上是关于在 TOMCAT5.5 上 SSL 的 APR 实现和 SSL 的 JSSE 实现有啥区别的主要内容,如果未能解决你的问题,请参考以下文章
tomcat runing on daemon with apr and ssl mode