由于 SecureRandom,Tomcat 7.0.57 启动缓慢

Slow startup on Tomcat 7.0.57 because of SecureRandom

我在 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.

这个问题最好的 practice/solution 是什么?

谢谢!

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

如果你有

securerandom.source=file:/dev/random

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

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

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

我更改了 /jre/lib/security/java.security,如下所示: securerandom.source=文件:/dev/./urandom

这里有一些具体的说明,可以根据亨利的回答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。可怜的老糊涂 tomcat 7 不会按照 /var/log/messages

中的警告启动

在不同的 versions/flavours 上,您可能会发现在何处最适合为 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

我遇到了同样的问题 of tomcat being too slow to start. I followed this article on DigitalOcean 并安装了 haveged 而不是使用 urandom。

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

haveged allows generating randomness based on variations in code execution time on a processor. Since it's nearly impossible for one piece of code to take the same exact time to execute, even in the same environment on the same hardware, the timing of running a single or multiple programs should be suitable to seed a random source. The haveged implementation seeds your system's random source (usually /dev/random) using differences in your processor's time stamp counter (TSC) after executing a loop repeatedly

如何安装 haveged

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

我发了

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

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

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

    securerandom.source=file:/dev/./urandom

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

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

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

我在 Java 1.7 和 Ubuntu 14.04.1.

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

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

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

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

配置spring开机

@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()

背景资料

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

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

这条线在 2014 年曾经是 INFO 级别...

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

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

来源

这里触发消息: 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.