我正在开发一个服务器,还有一些开发人员正在连接它。
此服务器使用Java的TLS实现SSLEngine
。
我们看到,首先,每个新连接都会有很长的延迟(30-40秒)。我们将其缩小以反转DNS查找超时。我们通过将所有IP放在HOSTS
文件中来解决这个问题。
现在,问题是我们将逐步扩大我们的用户群,我不想编辑HOSTS
文件,特别是因为我们无法保证他们将拥有静态IP
有没有办法在Java的SSL / TLS中禁用反向DNS查找步骤?
我想将此作为可配置参数,以便我们可以在开发过程中将其关闭。
答案 0 :(得分:11)
当我尝试仅通过IP地址创建SSL套接字连接时,我今天遇到了同样的问题。这导致反向DNS查找尝试,因此它真的很慢......
对我来说,解决方案只是在为SSL连接创建InetAddress时,将虚拟空字符串作为主机名传递。也就是说,我改变了
InetAddress.getByAddress(addrBytes)
到
InetAddress.getByAddress("", addrBytes)
并且它不再进行反向DNS查找。
答案 1 :(得分:3)
这个问题出现在2006年的Sun JSSE forums上。底线是它似乎只出现在Windows java运行时。在this bug report中,底部是一个提议的解决方案。这是another proposed solution:
基本上,SSL握手期间的反向DNS查找会导致很长时间 超时。
要解决此问题,请将服务器地址缓存为InetAddress对象 并且只要你创建一个新的,就在Socket构造函数中重用它 连接到您的服务器。
希望其中一个适合你。
答案 2 :(得分:0)
Ari将空主机名传递给InetAddress
的解决方案适用于连接到单个主机,但是当通过IP地址连接到多个主机时,它有一些副作用。 Java使用元组<remote-hostname, port>
缓存SSLSession对象。这可以在OpenJDK here中看到。因此,先前连接的TLS设置(在我的情况下特别是TLS协议版本)被应用于到不同主机的新连接(因为两者共享相同的空主机名)。就我而言,新主机拒绝了前一主机协商的降级TLS v1协议,导致TLS握手错误。
解决方案是根据远程IP地址构建一个唯一的主机名,如下所示:
String hostname = String.format("host-%s", BaseEncoding.base16().encode(address.getAddress()));
InetAddress newAddress = InetAddress.getByAddress(hostname, address.getAddress());
因此,反向DNS查找Java执行被禁用,但缓存的TLS设置只能应用于远程主机,而不会产生串扰效应。