![如何让 Docker 容器获得足够的熵?](https://linux22.com/image/771737/%E5%A6%82%E4%BD%95%E8%AE%A9%20Docker%20%E5%AE%B9%E5%99%A8%E8%8E%B7%E5%BE%97%E8%B6%B3%E5%A4%9F%E7%9A%84%E7%86%B5%EF%BC%9F.png)
每当我cat /proc/sys/kernel/random/entropy_avail
进入我的 Docker 容器(基于 Linux 5.10)时,我都会得到两位数的结果,这显然低得可笑。据说低于 4 位的任何结果都是不好的,而将其保持在接近 4096(最大值)是理想的。
我读过有关一个名为的熵收集守护进程的文章haveged
,但它据称自 Linux 内核 5.6 以来就已经过时了,所以我不确定这是否仍然是正确的解决方案。
为什么运行 5.10 内核的 Docker 容器内的熵这么低,我该如何解决这个问题?
我最初发现这个问题是因为 Python 的“每日名言”脚本一直选择相同的几句名言。我没有手动播种 Python 的标准 Random 模块,但根据其文档和源代码,它应该从系统熵中自行播种(直接通过getentropy(3)
或获取(getrandom(2)
如果可用的话),我假设它们在典型的现代 Linux 环境中会这样,或者通过/dev/random
或以/dev/urandom
其他方式,或者在万不得已的情况下回退到使用系统时间和 PID)。所以我猜我的熵太低了,以至于getentropy(3)
返回的熵很差?无论如何,用系统时间手动播种 Python 的 Random 模块解决了这个问题。
但是,现在我担心我的执行 TLS 的 Web 服务器和身份验证服务器(它们都在类似的 Docker 容器中运行)可能没有足够的熵来生成强密钥、一次性密码本和质询等等。因此,我想弄清楚如何保证我的 Docker 容器获得足够的熵来很好地完成它们的工作。
这不是关键的国家基础设施,也不是适合安装硬件 RNG 模块的东西。这些只是云托管的 Docker 容器,所以我希望能找到一个可以在我的 Docker 容器/镜像中实现的解决方案。
答案1
由于您正在与内核对话,因此它实际上与 docker 根本无关:
$ cat /proc/sys/kernel/random/entropy_avail
3771
$ docker run -it --rm busybox cat /proc/sys/kernel/random/entropy_avail
3781
$ cat /proc/sys/kernel/random/entropy_avail
3800
如果主机上获得更多的熵,则容器中也会获得更多的熵。
答案2
最近看到当天相同报价的轶事并不能证明您的 RNG 有问题。
对于除安全关键加密之外的所有情况,请使用 Python 的 Random(而非 SystemRandom)。默认情况下,它会自行播种。请注意,任何合理唯一的整数都可以用作种子,通过播种另一个整数来检测 RNG 的质量的可能性极小。
那么 SystemRandom 呢?这是 Python 的 API,用于获取特定于平台的非确定性 RNG,因此更适合加密使用。
随机位在 Linux 上并不罕见或特殊,这是一个神话。内核的 CSPRNG 很好,一旦初始化,就可以在非阻塞模式下(/dev/urandom、带有 GRND_NONBLOCK 的 getrandom)用于大量随机位。实际上从 5.6 开始,它就是这样工作的,Linux 不再有阻塞池。/dev/random 仅在内核 rng 初始化之前在启动时阻塞。从长远来看,这是一个真正的解决方案,升级内核,程序就可以拥有任意数量的位。
问题是,人们仍然认为阻塞 API 更好,尽管当阻塞池耗尽时会导致拒绝服务。Python 在早期的启动脚本中修复了阻塞池耗尽的问题……在 Linux 上通过设置 os.urandom() 阻塞。。唉。