39

I'm using Tomcat 7.0.57 on CentOS 6.6 32 bit and openJDK7. When I start 14 different instances of Tomcat on my server(production environment), many of them take too much time to start.

This is part of the startup log, which tells me where is taking all the time

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.

What's the best practice/solution for this problem?

Thanks!

Jose Monreal Bailey
  • 461
  • 1
  • 5
  • 12

10 Answers10

22

I faced same issue of tomcat being too slow to start. I followed this article on DigitalOcean and installed haveged instead of using urandom.

haveged is a solution which will not compromise on security.

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

How to install haveged

Follow the steps in this article. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

I have posted it here

Community
  • 1
  • 1
so-random-dude
  • 15,277
  • 10
  • 68
  • 113
  • 5
    plusOne..this is the solution which actually doesn't compromise security, especially on a LIVE env. – senseiwu Feb 24 '17 at 11:11
  • 2
    Excellent answer thanks. I first ran into this problem on tomcat upgrading from tomcat 8.0.x to 8.5.x and migrating from AWS to google cloud at the same time. After reading the article it looks like google cloud's CentOS 7 instances don't generate entropy as well as AWS's default CentOS image. Writing my findings here in case anyone is googling these specific technology terms. – Reece Apr 10 '19 at 20:43
20

The secure random calls may be blocking as there is not enough entropy to feed them in /dev/random.

If you have the line

securerandom.source=file:/dev/random

in /jre/lib/security/java.security, changing this to urandom may improve things (although this is probably already the default).

Alternatively there are some suggestions on how to feed the pool here

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

Community
  • 1
  • 1
henry
  • 5,923
  • 29
  • 46
  • I have a follow up question. http://stackoverflow.com/questions/40383430/tomcat-takes-too-much-time-to-start-java-securerandom. Is it ok to do so in production? Will this have any impact on security (like Session ID becoming predictable)? – so-random-dude Nov 02 '16 at 15:20
  • 1
    It would be safer in a production environment to use the solution by @random_dude , I think. – Erica Kane Jun 16 '17 at 21:00
  • In my Ubuntu 18.04 with OpenJDK 11.0.7 this is in `$JAVA_HOME/conf/security/. – Rick May 22 '20 at 10:59
4

Here are some specific instructions to adjust just tomcat as per Henry's answer

create /etc/tomcat/fastersecurerandom.properties

securerandom.source=file:/dev/urandom

edit JAVA_OPTS inside /etc/tomcat/tomcat.conf

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

FYI I found I could not set multiple JAVA_OPTS with JAVA_OPTS="$JAVA_OPTS ..." despite the commented out examples. Poor old confused tomcat 7 wouldn't start as per a warning in /var/log/messages

On different versions/flavours you may find variations on where is best to set the environment variables for tomcat. The best way to debug if they are taking affect is is to check the command running like this:

$ 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
KCD
  • 9,873
  • 5
  • 66
  • 75
  • 2
    You can just add `-Djava.security.egd=file:/dev/urandom` to the JAVA_OPTS or java VM options. For more information open **jre/lib/security/java.security** file, search for `securerandom.source` and you can find the doc there. – Nagy Attila Nov 02 '16 at 11:13
  • Yeah that sounds more sensible – KCD Nov 02 '16 at 22:06
  • According to Tomcat website, add this Java property: -Djava.security.egd=file:/dev/./urandom – Rob Stoecklein Jun 13 '18 at 23:17
1

Instead of changing the file java.security directly, at least with Java 8 it documents to support the following system property already:

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

In the context of Tomcat, that can be used to create a file bin/setenv.sh containing the following line:

CATALINA_OPTS=-Djava.security.egd=file:///dev/urandom
Thorsten Schöning
  • 3,501
  • 2
  • 25
  • 46
0

I changed /jre/lib/security/java.security, below: securerandom.source=file:/dev/./urandom

刘同彬
  • 197
  • 2
  • 12
0

@KCD s answer above almost worked for me, I needed to massage it a bit - as follows:

  1. my tomcat was tomcat7 , so I created my fastersecurerandom.properties file in the /etc/tomcat7 directory,

  2. As per another page, I had to change the contents of fastersecurerandom.properties from securerandom.source=file:/dev/urandom
    to
    securerandom.source=file:/dev/./urandom

  3. I didn't have a tomcat.conf file, so I added to my /etc/init.d/tomcat7 (tomcat's startup script - I know) , just before the line - catalina_sh() {
    JAVA_OPTS="$JAVA_OPTS -Djava.security.properties=/etc/tomcat7/fastersecurerandom.properties"

Note: I added 7 to tomcat here too.

It was worthwhile doing a ps -deaf | grep tomcat to first confirm that the new -D setting was getting through to the command, and also to check that it was referring to the correct file, and that the file was there. This is when I noticed the missing 7.

I was on Java 1.7, and on Ubuntu 14.04.1.

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
nby
  • 119
  • 1
  • 3
0

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

0

Background info

This is not an answer in itself. But it's some background info, in case you're wondering where this log line comes from.

This log line gets triggered when generation takes longer than a tenth of a second (100 miliseconds)

This line used to be level INFO in 2014...

... but got changed to level WARN in 2017...

...to make it stand out more in the logs. The motivation for that change was this bug report here:

Source

The message is triggered here: 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)));
}

And the human readable English text comes from here: 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.
StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
0

if in case you are using spring security add web security class.

@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ...
        http.cors();
     //other configure params.
        http.csrf().disable();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", corsConfiguration);

        return source;
    }
}
helvete
  • 2,455
  • 13
  • 33
  • 37
0

In spring boot, u can use this code block:

   @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf().csrfTokenRepository(new CookieCsrfTokenRepository())
            .requireCsrfProtectionMatcher(httpServletRequest -> httpServletRequest.getMethod().equals("none"));
    return http.build();
}

its ok for me!!