在虚拟机中重新播种 /dev/urandom 需要多长时间?

信息安全 linux SSH 虚拟化 随机的
2021-08-19 06:09:40

/dev/random我已经阅读了很多关于和之间的区别/dev/urandom我了解普遍的建议是使用/dev/urandom. 解释——256 位的“适当”随机性是几乎所有加密应用程序所需的全部——对我来说很有意义。
一些有用的资源:
- https://pthree.org/2014/07/21/the-linux-random-number-generator/
- http://www.2uo.de/myths-about-urandom/

首次启动后的虚拟机 (VM) 或 Live CD 的状态有时被识别为本指南的异常边缘情况,因为/dev/urandom可能没有正确播种。

在所有其他可能用途的上下文中/dev/urandom,我可以看到这是一个极端情况。但是,鉴于您是第一次使用 VM,您可能想要做的第一件事似乎是调用 on /dev/urandom,例如生成 SSH 密钥。

所以,如果你假设你的虚拟机是最坏的(例如它被克隆了,或者重启后新播种的随机数不好),你能做些什么来确保它/dev/urandom是好的?

懒惰的做法似乎是让虚拟机运行一会儿,直到随机事件重新植入输入池。尴尬的部分是空闲的虚拟机执行此操作非常缓慢。

我想测试发生这种情况需要多长时间,我尝试这样做:

此命令从池中提取 32 字节/256 位(并以十六进制显示)
head -c 32 </dev/random | xxd -p

一旦输入池的熵计数达到最低水平(用 可见cat /proc/sys/kernel/random/entropy_avail),上面的命令将阻塞,直到新的随机事件进入输入池。这向我表明,如果我们重复运行上述命令,对其计时,并将结果写入一个名为randomtest它的文件,这将指示重新填充输入池需要多长时间。

我尝试编写一个这样做的单行命令:
for n in {1..10}; do (/usr/bin/time -f "%E Real" sh -c 'printf "%-10s" $(head -c 32 </dev/random | xxd -p)' 2>&1) >> randomtest; done

更具可读性:

for n in {1..10};
do (/usr/bin/time -f "%E Real" sh -c \
    'printf "%-10s" $(head -c 32 </dev/random | xxd -p)' 2>&1) \
    >> randomtest; 
done

我知道启动进程(甚至是上面的 cat 命令)会占用输入池,所以这将提供一个保守的估计。值得一提的是,我让上述命令在不活动的 VM 上运行,新的 32 字节序列之间的时间稳定在 15-20 分钟。

我的问题:

  • 该命令的输出是否成功测试了我认为它的作用?
  • 有没有更简单的方法来测试同样的东西?
  • /dev/urandom与让虚拟机闲置相比,是否有一种不同/更好的“懒惰”方式来刷新输入池和重新播种
3个回答

我不是关于两者之间细微差别的专家urandomrandom但根据您的描述,您的测试似乎正确地估计了重新填充输入池的时间。我不知道有任何工具可以进行这种测试。

不过,有一种更好的方法来重新播种urandom以防止陈旧状态影响随机数据的质量,那就是将随机数据写入urandom.

这可以cloud-init通过使用哈希函数运行一些实例元数据并将其写入urandom. 这也可以是使用 Chef、Ansible、Puppet 等的配置管理解决方案的一部分,并从本地机器中提取随机种子。

请注意,这不会增加总熵数,它只会设置更新鲜的种子。man 4 random

写入 /dev/random 或 /dev/urandom 将使用写入的数据更新熵池,但这不会导致更高的熵计数。这意味着它会影响从两个文件中读取的内容,但不会加快从 /dev/random 中读取的速度。

如果您没有硬件rng,您可以通过haveged.daemonhost

我在我的Alpine Linux 安装脚本luks中使用它来提供足够的熵来在全新安装上创建文件系统。

这不能回答你的任何问题。它只是解决了你的一些陈述。

/dev/random我已经阅读了很多关于和之间的区别/dev/urandom我了解普遍的建议是使用/dev/urandom...

/dev/random不应该使用。根据 Linux Kernel Crypto 邮件列表上的 Theodore Ts'o 的说法,/dev/random它已被认为已弃用大约十年。来自 Re: [RFC PATCH v12 3/4] Linux 随机数生成器

几乎没有人使用 /dev/random。它本质上是一个已弃用的接口;十多年来一直推荐的主要接口是 /dev/urandom,现在是 getrandom(2)。我们每 5 分钟只需要 384 位的随机性来重新播种 CRNG,即使考虑到当前使用的非常保守的熵估计,这也足够了。

这是故意的。我更关心我们在 ARM32 和 MIPS 嵌入式设备上获得初始启动时 CRNG 初始化,远远超过我关心在 x86 系统上的 /dev/random 上提供大量信息论熵。 ..


首次启动后的虚拟机 (VM) 或 live CD 的状态有时被识别为本指南的异常边缘情况,因为 /dev/urandom 可能没有正确播种...

现代 Linux 操作系统使用基于硬件的生成器来收集一些熵。例如,在 x86 上,rdrand(或者是它rdseed)用于某些位。生成器不是唯一的来源,但它在关键时刻提供了帮助。

systemd 长期以来一直是个问题。/dev/urandom它在准备好之前提取熵。由于 systemd 挂起,尝试阻止/dev/urandom会导致系统挂起。另请参阅为什么 getrandom 阻塞不适用于 /dev/urandom问题 4167,systemd 在初始化之前从 urandom 读取

您可能还想阅读 Stephan Mueller 对 Linux RNG 的一些分析。他也是 Linux Crypto 的常客。


...如果您假设您的虚拟机最糟糕(例如它被克隆,或者重新启动后新播种的随机数不好),您可以做些什么来确保 /dev/urandom 是好的?

这些被称为回滚攻击。

我知道的唯一补救措施是对冲。回想一下,如果可用,您应该在提取熵之前重新播种 prng。对冲时,你使用对方的熵,并与自己的熵混合。所以,比如说,在 TLS 中,你把对方的随机数混合到你的 prng 中。由于攻击者无法控制对方,即使虚拟机被重置,您也会产生不同的流。

另见:


/dev/urandom在虚拟机中重新播种需要多长时间?

安装一个熵收集守护进程,比如 haveged。它不断地收集熵并为你处理事情。

熵收集守护进程是 Debian 的必备工具。我测试过的每个 Debian 版本——从 ARM 到 MIPS 和 x86——都会遭受熵耗尽。其中包括 Armbian 和 Ubuntu 等衍生产品。您必须安装该rng-tools软件包,因为默认情况下未安装它。