Use of /dev/random in gradle


(Sandy Sim) #1

We are using gradle to build and test our system.
We have automated testing using jenkins, and found an issue where gradle or some sub-process was blocking on some of the jenkins slaves due to entropy starvation.

I’m just wondering how/why gradle is using /dev/random - if it is, and also if there is something like the java securerandom.source setting that we could change so that gradle will read from /dev/urandom instead.

we run gradle wrapper…

Gradle 2.13

Build time: 2016-04-25 04:10:10 UTC
Build number: none
Revision: 3b427b1481e46232107303c90be7b05079b05b1c

Groovy: 2.4.4
Ant: Apache Ant™ version 1.9.6 compiled on June 29 2015
JVM: 1.7.0_80 (Oracle Corporation 24.80-b11)
OS: Linux 3.13.0-92-generic amd64


Unexpected CryptoAPI failure
(Lari Hotari) #2

Gradle uses the JVM and doesn’t do decisions about using /dev/random or /dev/urandom.

For OpenJDK and Oracle JVM, there is an idiom to pass -Djava.security.egd=file:/dev/./urandom in JVM args to use /dev/urandom instead of /dev/random.

Here’s an example to achieve it for the Gradle daemon client and Gradle daemon processes:
export GRADLE_OPTS="-Djava.security.egd=file:/dev/./urandom -Xmx1g -Dorg.gradle.jvmargs='-Djava.security.egd=file:/dev/./urandom -Xmx1g'"

You would also have to pass the system property to test runners when running on CI:

if(System.getenv('BUILD_NUMBER')) {
   tasks.withType(Test) { systemProperty 'java.security.egd', 'file:/dev/./urandom' }
}

You might want to run haveged in your Jenkins slaves instead of doing this.


(Sandy Sim) #3

Thank you for your reply.

I tried exporting GRADLE_OPTS as you suggested.
If I watch the output of lsof | grep /dev/random I still see that the gradle daemon process is using /dev/random.

If I poke around in /proc, the command line for one of the sub processes looks like this:
/usr/lib/jvm/java-7-oracle/bin/java -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp^@/home/ssim/.gradle/wrapper/dists/gradle-2.13-bin/4xsgxlfjcxvrea7akf941nvc7/gradle-2.13/lib/gradle-launcher-2.13.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 2.13

Do you know if there’s a way to set the entropy source for those sub processes?

No hurry, we installed rngd on the slaves and things are going fine now.


(Lari Hotari) #4

@simsandyca

Seems that you have your problem solved with rngd. In general, security experts don’t recommend feeding /dev/random from /dev/urandom, so that’s something to keep in mind. haveged provides a more secure alternative than rngd when you don’t have a hardware entropy device available. haveged is available in modern distros and that’s why I usually recommend using that instead of rngd.

Back to your question about the sub processes. If you have a Gradle daemon without the argument, that means that you didn’t properly set org.gradle.jvmargs in GRADLE_OPTS. When org.gradle.jvmargs is set in GRADLE_OPTS, it has to be single quoted as in this example:

export GRADLE_OPTS="-Dorg.gradle.jvmargs='-Djava.security.egd=file:/dev/./urandom -Xmx1g'"

However if you use gradle.properties (in project dir or ~/.gradle) to set org.gradle.jvmargs, there should be no quotes in the value:

org.gradle.jvmargs=-Djava.security.egd=file:/dev/./urandom -Xmx1g

As I mentioned in my previous reply, there are also the test runners, that have to be configured. It’s a lot simpler to just install haveged if it’s possible to do that. I’d only use -Djava.security.egd=file:/dev/./urandom in cases when there wouldn’t be a possibility to use haveged (or rngd with a hardware entropy device).