由于 SecureRandom,Tomcat 7.0.57 启动缓慢

Posted

技术标签:

【中文标题】由于 SecureRandom,Tomcat 7.0.57 启动缓慢【英文标题】:Slow startup on Tomcat 7.0.57 because of SecureRandom 【发布时间】:2015-03-27 21:59:17 【问题描述】:

我在 CentOS 6.6 32 位和 openJDK7 上使用 Tomcat 7.0.57。 当我在我的服务器(生产环境)上启动 14 个不同的 Tomcat 实例时,其中许多实例需要太多时间才能启动。

这是启动日志的一部分,它告诉我一直在哪里

Jan 28, 2015 2:49:41 PM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [199,620] milliseconds.

这个问题的最佳实践/解决方案是什么?

谢谢!

【问题讨论】:

这和熵有关 来源:wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source 我在移动设备上,所以我没有我的链接,但请使用 /dev/urandom。使用非阻塞生成器没有明显的缺点。 【参考方案1】:

@KCD 上面的回答几乎对我有用,我需要稍微按摩一下 - 如下:

    我的 tomcat 是 tomcat7 ,所以我在 /etc/tomcat7 目录中创建了我的 fastersecurerandom.properties 文件,

    根据another page,我不得不更改fastersecurerandom.properties的内容 从 securerandom.source=file:/dev/urandomsecurerandom.source=file:/dev/./urandom

    我没有tomcat.conf 文件,所以我添加到我的/etc/init.d/tomcat7(tomcat 的启动脚本 - 我知道),就在行之前 - catalina_sh() JAVA_OPTS="$JAVA_OPTS -Djava.security.properties=/etc/tomcat7/fastersecurerandom.properties"

注意:我在这里也添加了7tomcat

值得做一个ps -deaf | grep tomcat 首先确认新的-D 设置正在通过命令,并检查它是否引用了正确的文件,并且该文件在那里。这是我注意到缺少的7

我使用的是 Java 1.7 和 Ubuntu 14.04.1。

【讨论】:

【参考方案2】:

背景资料

这本身并不是一个答案。但这是一些背景信息,以防您想知道这条日志行的来源。

当生成时间超过十分之一秒(100 毫秒)时,将触发此日志行

此行在 2014 年曾是级别 INFO...

https://github.com/apache/tomcat/blame/fdd86cf2e0b851aced2f460c765fea5293a30940/java/org/apache/catalina/util/SessionIdGeneratorBase.java#L273

...但在 2017 年更改为 WARN 级别...

https://github.com/apache/tomcat/commit/d0fc016424c2110fdf40fd02fb90b23a6bba150c

...让它在日志中更加突出。该更改的动机是此处的错误报告:

Bug 61180 - Change log level of sessionIdGeneratorBase.createRandom to warn rather than info

来源

消息在这里触发: https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/util/SessionIdGeneratorBase.java#L272

long t2 = System.currentTimeMillis();
if ((t2 - t1) > 100) 
log.warn(sm.getString("sessionIdGeneratorBase.createRandom",
        result.getAlgorithm(), Long.valueOf(t2 - t1)));

人类可读的英文文本来自这里: https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/util/LocalStrings.properties#L46

sessionIdGeneratorBase.createRandom=Creation of SecureRandom instance for session ID generation using [0] took [1] milliseconds.

【讨论】:

【参考方案3】:

配置spring boot

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            .cors().and().csrf().disable()

            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS) //using JWT
                .and()
            .authorizeRequests()
                .antMatchers(PUBLIC_ENDPOINTS).permitAll()
                .anyRequest().authenticated()
                .and()
            .addFilterBefore(authFilter(), UsernamePasswordAuthenticationFilter.class);

.cors().and().csrf().disable()

【讨论】:

这是做什么的?这如何解决问题?【参考方案4】:

不是直接更改文件java.security,至少在 Java 8 中,它已经记录了支持以下系统属性:

-Djava.security.egd=file:/dev/random

在 Tomcat 的上下文中,可用于创建包含以下行的文件 bin/setenv.sh

CATALINA_OPTS=-Djava.security.egd=file:///dev/urandom

【讨论】:

【参考方案5】:

我面临同样的issue tomcat 启动太慢。我跟着this article on DigitalOcean 安装了haveged 而不是使用urandom。

haveged 是一种不会损害安全性的解决方案。

haveged 允许根据 处理器上的代码执行时间。因为这几乎是不可能的 一段代码花费相同的确切时间来执行,即使在 同环境同硬件,单机运行时序 或多个程序应该适合播种随机源。这 haveged 实现为您系统的随机源提供种子(通常 /dev/random) 使用处理器时间戳计数器的差异 (TSC) 重复执行循环后

如何安装haveged

按照本文中的步骤操作。 https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

我已经发布了here

【讨论】:

plusOne..这是实际上不会危及安全性的解决方案,尤其是在 LIVE 环境中。 很好的答案,谢谢。我在从 tomcat 8.0.x 升级到 8.5.x 并同时从 AWS 迁移到 google cloud 时遇到了这个问题。阅读文章后,看起来谷歌云的 CentOS 7 实例不会像 AWS 的默认 CentOS 映像那样生成熵。在这里写下我的发现,以防有人在谷歌上搜索这些特定的技术术语。【参考方案6】:

这里有一些具体的说明,可以根据亨利的回答只调整 tomcat

创建/etc/tomcat/fastersecurerandom.properties

securerandom.source=file:/dev/urandom

/etc/tomcat/tomcat.conf 内编辑JAVA_OPTS

JAVA_OPTS="-Djava.security.properties=/etc/tomcat/fastersecurerandom.properties"

仅供参考,尽管有注释掉的示例,但我发现我无法使用 JAVA_OPTS="$JAVA_OPTS ..." 设置多个 JAVA_OPTS。根据/var/log/messages中的警告,可怜的老糊涂的tomcat 7不会启动

在不同的版本/风格上,您可能会发现在哪里最好为 tomcat 设置环境变量。如果它们生效,最好的调试方法是检查运行的命令,如下所示:

$ ps aux | grep java
tomcat    4821  4.7 13.9 2626888 263396 ?      Ssl  22:31   0:23 /usr/lib/jvm/jre/bin/java -DJENKINS_HOME=/opt/jenkins/ -Xmx512m -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true -Djava.security.properties=/etc/tomcat/fastersecurerandom.properties -classpath /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat/temp -Djava.util.logging.config.file=/usr/share/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start

【讨论】:

您可以将-Djava.security.egd=file:/dev/urandom 添加到 JAVA_OPTS 或 java VM 选项中。欲了解更多信息,请打开 jre/lib/security/java.security 文件,搜索 securerandom.source 即可找到该文档。 是的,听起来更明智 根据Tomcat网站,添加这个Java属性:-Djava.security.egd=file:/dev/./urandom【参考方案7】:

我更改了/jre/lib/security/java.security,如下: securerandom.source=file:/dev/./urandom

【讨论】:

添加它有效。你可以看到:wiki.apache.org/tomcat/HowTo/FasterStartUp【参考方案8】:

安全随机调用可能会被阻塞,因为没有足够的熵将它们输入 /dev/random。

如果你有这条线

securerandom.source=file:/dev/random

在 /jre/lib/security/java.security 中,将其更改为 urandom 可能会有所改善(尽管这可能已经是默认设置)。

或者,这里有一些关于如何喂池的建议

https://security.stackexchange.com/questions/89/feeding-dev-random-entropy-pool

【讨论】:

我有一个后续问题。 ***.com/questions/40383430/…。在生产中可以这样做吗?这会对安全性产生任何影响(例如 Session ID 变得可预测)? 我认为在生产环境中使用@random_dude 的解决方案会更安全。 在我的带有 OpenJDK 11.0.7 的 Ubuntu 18.04 中,它位于 `$JAVA_HOME/conf/security/ 中。

以上是关于由于 SecureRandom,Tomcat 7.0.57 启动缓慢的主要内容,如果未能解决你的问题,请参考以下文章

SecureRandom生成随机数超慢 导致tomcat启动时间过长的解决办法

JDK8+tomcat8环境tomcat启动时SecureRandom 非常慢解决办法

tomcat启动慢, Creation of SecureRandom instance for session ID generation using [SHA1PRNG]took [xx] mil

Tomcat启动时Creation of SecureRandom instance for session ID很慢

tomcat:8005端口启动失败的解决办法

重启tomcat后,访问登陆接口响应慢--Creation of SecureRandom instance for session ID generation using [SHA1PRNG] to