在具有Java 8的嵌入式Tomcat 8.5上启用TLS握手的可观察性(日志记录/指标)

时间:2018-09-12 07:16:15

标签: java spring-boot tomcat ssl embedded-tomcat-8

我们正在运行Spring Boot API,其中我们在API本身中终止TLS。几次我们都观察到CPU使用率过高,这是由于广泛的搜索是由于有人创建了许多连接(由于拒绝了客户端证书而导致合法或错误的连接)或未使用TLS恢复造成的。

为了防止将来进行这些漫长而昂贵的搜索,我们希望能够记录握手失败或成功的时间以及原因以及是否正在使用会话恢复。

我们并不特别依赖于当前的堆栈,也可以升级到其他服务器,例如Undertow或WebFlux,和/或新版本的Java也可以。同样,如果可以帮助实现此目标,则可以使用APR,NIO或本机绑定。

以下其他问题表明,目前还没有开箱即用的解决方案,建议扩展JSSEImplementationcreate customised SSL Socket Factory,或将NIO适配器的级别转换为Debug。这些解决方案很脆弱,我想知道是否存在基于事件或回调的更可扩展的机制。另外,我们可以启用Java的握手日志,但是这些日志很冗长,这样做会导致性能严重下降。

更新1: 我尝试使用自定义SSLServerSocketFactory的方法。 sun.security.ssl.SSLServerSocketFactoryImpl绑定时返回sun.security.ssl.SSLServerSocketImpl,接受时返回漂亮的SSLSocket。我可以包装该accept方法以始终添加完成处理程序。唯一的缺点是:SSLServerSocketFactoryImpl是最终的,所以我不能只包装它。这意味着我需要复制很多代码,并且仍然只能为我提供成功握手的指标。复制代码将是维护负担,因为这是JRE特定的代码。

2 个答案:

答案 0 :(得分:0)

我的答案可能不是您期望的,但这是我自己要做的。

首先,我从未在自定义软件上启用SSL。 Java,C#,Python,Javascript都不是。在我所有的解决方案中,它们都通过纯HTTP运行。

我委派给NGINX的所有TLS内容。这是可靠的。很快它有很多选择。它具有通用和详细的日志。它具有一些基本的访问控制和DDoS保护。它封装了部署的详细信息,并为多个提供的服务提供了单一外观。

开销很小,即使在适度的硬件上也可以很好地运行。

您需要两个功能:反向代理和详细日志记录。

最简单的配置文件如下:

server {
        listen 443 ssl;

        server_name example.com;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;

        location / {
                # Transfer all request to the actual server using HTTP
                proxy_pass http://<server-in-intranet>:12345;
                proxy_set_header Host $host;
        }
        # TLS handshake errors are reported at the info level
        error_log /var/log/nginx/example.com/error.log info;
        # Extra ideas about SSL logging: 
        #   https://docs.nginx.com/nginx/admin-guide/monitoring/logging/#tls_sample

        # The certificates from Let's Encrypt are installed by Certbot
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
}

通过此配置,服务器https://example.com/可以为实际服务器的内容提供服务,该内容通过HTTPS通过Intranet运行于Intranet内部某个地方,而实际服务器是普通HTTP。

使用此设置,我可以运行用Go,Javascript和Python编写的服务器,这些服务器可以在不同的计算机上运行,​​但是可以通过单一访问点(例如https://global.name/service1/https://global.name/service2/https://global.name/service3/

答案 1 :(得分:0)

这是负载均衡器后面的一个单独的服务器还是一组服务器?

您可以考虑“重新部署”服务器,从而使您的服务器具有相同的配置,但启用了JAVA OPT调试ssl:handshake。

现在,在负载平衡器上,将流量的部分引导到调试服务器,以对您感兴趣的活动进行采样。

或者,您在另一台启用了调试功能的端口上的同一服务器上部署tomcat的另一个实例。 (这远不及想法,它增加了您提到的服务器负载,在请求增加时可能已经遇到麻烦了。)

因此,也许您没有负载均衡器,但是您可能有防火墙,请查看防火墙是否为有状态的并且可以为您“分流”。

如果当前服务器是linux服务器,则可以在上面提到的“双重本地安装”示例中使用iptables进行此操作。像这样的东西:https://www.webair.com/community/simple-stateful-load-balancer-with-iptables-and-nat/

没有复杂的解决方案。

如果您没有负载均衡器,则不妨考虑一下它,因为它为您提供了灵活的灵活性来应对各种情况,不仅如此。

祝你好运

大卫