After I updated my Linux machine to kernel 4.1x, my program suddenly stopped working or precisely speaking, not working until 1 minute later. Once it runs, it runs smoothly afterward.
After spending hours of trial and error, I finally figured out that it is related to the package crypto/rand
. Once you read from the rand.Reader
, it stuck.
Analysis
There are actually two random number generators (RNG) in golang: math/rand
and crypto/rand
. The key difference between the two is that the former one is a pseudo-RNG (PRNG) and the latter one is a true RNG (and slower).
As a real RNG, it reads directly from /dev/urandom
on Linux, and it only can be done when Linux had collected enough entropy which is usually insufficient on startup. The official way to do it is to wait until enough entropy is collected, and it typically costs about 1 minute.
There is a discussion about the entropy problem in github:
https://github.com/golang/go/issues/22614
Solution
Formal solution:
- Wait for 1 minute. Simple and secure.
- Use random-seed service (
/etc/init.d/urandom
) to save the random seed on shutdown and feed back the seed to the system on boot. (Doesn't work on my system)
Simpler solution:
Install
haveged
. (Most repos have it in stock, but not installed by default). There is also a discuss about the security of haveged: https://security.stackexchange.com/questions/34523/is-it-appropriate-to-use-haveged-as-a-source-of-entropy-on-virtual-machines and looks like haveged is secure enough for normal use. Of course you could always usemath/rand
to get pesudo random number for situations that don't require high security, and it doesn't rely on entroy pool to work.Also, a package named
fastrand
(https://gitlab.com/NebulousLabs/fastrand) is available as a faster alternative to the officalcrypto/rand
which claims to be 10x faster than the latter one. The security is discussed here: https://www.reddit.com/r/golang/comments/616czq/fast_replacement_for_cryptorand_10x_faster_no/
0 comment