【问题标题】:Slow startup on Tomcat 7.0.57 because of SecureRandom由于 SecureRandom,Tomcat 7.0.57 启动缓慢
【发布时间】: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.

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

谢谢!

【问题讨论】:

标签: java tomcat7


【解决方案1】:

@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"

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

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

我使用的是 Java 1.7 和 Ubuntu 14.04.1。

【讨论】:

    【解决方案2】:

    背景资料

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

    当生成时间超过十分之一秒(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.
    

    【讨论】:

      【解决方案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

        【讨论】:

        【解决方案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

        【讨论】:

        • 我有一个后续问题。 stackoverflow.com/questions/40383430/…。在生产中可以这样做吗?这会对安全性产生任何影响(例如 Session ID 变得可预测)?
        • 我认为在生产环境中使用@random_dude 的解决方案会更安全。
        • 在我的带有 OpenJDK 11.0.7 的 Ubuntu 18.04 中,它位于 `$JAVA_HOME/conf/security/ 中。
        猜你喜欢
        • 1970-01-01
        • 2017-03-15
        • 2021-04-27
        • 2018-08-25
        • 2015-08-26
        • 1970-01-01
        • 1970-01-01
        • 2015-10-13
        • 1970-01-01
        相关资源
        最近更新 更多