随机数生成器RNG

为何需要rng和虚拟化virtio-rng

KVM虚拟机中安装CentOS内核源代码时,你会发现需要生成PGP密钥来给模块签名,此时系统会提示需要rngd需要读取/dev/random/dev/urandom设备来生成密钥。如果libvirtd创建的虚拟机没有包含这个虚拟随机数生成器设备,会导致安装过程卡住长时间无法结束。

在KVM虚拟机中运行FreeBSD系统,启动虚拟机时,如果你仔细观察启动信息,会看到FreeBSD启动时提示kernel: random device not loaded; using insecure entropy。这也是因为KVM虚拟机没有提供虚拟随机数生成器导致的。

随机数生成器rng

为了能够生成安全的不被轻易破解的加密密钥,需要一个随机数源。通常,数字随机性越大,越能够得到更佳的唯一密钥。用于生成随机数的是通常从计算机环境"噪声"获得,或者使用硬件的随机数生成器。

rngd服务,是rng-tools软件包的部分,能够使用环境噪声和硬件随机数生成器来生成熵。这个服务检查是否有充分随机的随机性源来提供数据并存储它到内核的随机数熵池(random-number entropy pool)。这个随机数是通过/dev/random/dev/urandom字符设备来生成的。

随机数生成器(Random Number Generator, RNG)是生成伪随机数的机制。伪随机数字可以用于生成SSH key,进程随机PID,TCP序列号以及UUID等。使用加密(文件系统,邮件等等)需要大量的伪随机数。

要允许应用程序获得伪随机数,至少有2个内核块设备:

  • /dev/urandom 提供标准质量的随机数,不管是否有熵都可以工作:当需要大量的随机数的时候,随机性质量会下降(这是因为/dev/urandom设备是一个不中断源,会重用内核熵池,所以提供的是无限的伪随机数)。

  • /dev/random 提供高质量随机数,但是缺乏熵的时候会停止工作:在Linux内核保留了一个4KB的熵池(entropy pool)(这个熵池的大小见/proc/sys/kernel/random/poolsize);当这个pool空的时候,内核阻塞。

为了得到优质的伪随机数,需要一些entropy)。这个是由操作系统搜集的随机性因素:

  • 键盘实践,网络流量,鼠标移动,中断,ide计时等内部源

  • 在Intel IvyBridge和Haswell处理器提供的RDRAND这种特定处理器指令

  • 通过virtio-rng半虚拟化设备实现虚拟机随机设备(参考Red Hat文档Access to Random Numbers Made Easy in RHEL7

  • 独立的、外部、物理设备(称为TPM,即Trusted Platform Module)

以下实践是为了在KVM虚拟机中安装CentOS内核源代码,解决数字签名使用到的随机数生成问题,部署安装rng的实践

安装rng-tools

以下命令安装rng-tools

启动及检查rngd服务(CentOS 6)

启动及检查rngd服务(CentOS 7)

rngd也支持指定随机数设备输入(默认是/dev/hwrandom

或者-o--random-device指定选择内核随机数输出(默认是/dev/random)。

rng-tools阮籍包也包含了rngtest工具,可以用来检查数据的随机性,要检测/dev/random的输出随机性水平,可以使用rngtest工具如下

虚拟机中部署rng

这个/sbin/rngd属于软件包 rng-tools ,可以通过 sudo yum install rng-tools。但是在kvm虚拟机中执行:

提示错误

尝试加载sudo modprobe intel-rng,但是提示错误

尝试启动rngd服务,提示缺少/dev/tpm0设备文件

参考 RHEL7: How to get started with random number generator.

CentOS 6 rng

对于虚拟机,需要使用virtio-rng设备

添加

这里设置<rate bytes=’1024′ period=’1000’/>是为了防范guest虚拟机每秒消耗多于1KB的伪随机数。否则,一个guest虚拟机有可能会消耗掉所有的可用伪随机数,而其他虚拟机则无法分享。

然后再次启动

重启虚拟机后设置rngd启动

检查内核模块可以看到系统加载了virtio_rng

  • 然后创建一个伪随机设备

CentOS6虚拟机启动rngd后进程会D住,堆栈显示

参考后文的"CentOS 7 rng"部分和how to increase entropy in Centos 6.2?,修改rngd使用的设备配置,即编辑/etc/sysconfig/rngd,设置

然后就可以启动CentOS 6虚拟机的rngd服务

CentOS 7 rng

同样,对于虚拟机,需要先增加virtio_rng设备

添加

然后再次启动,发现启动后centos7_vm内部的rngd进程也是D住的

检查服务启动日志

检查了虚拟机内部,已经生成了/dev/random/dev/urandom设备

  • 检查rng

这里需要先停止rngd然后才能使用rngd -v检查,否则会卡住

  • 在KVM物理服务器,可以使用如下命令检查有哪些虚拟机使用了virt-rng设备

  • 再次CentOS 7 虚拟机,发现重启后 rngd服务启动失败

这是因为默认使用的/dev/tpm0设备不存在。需要修改配置让rngd不要使用硬件熵源:

修改/etc/systemd/system/rngd.service,替换

然后重新加载systemd

再次启动rngd

然后检查就可以看到rngd服务工作正常

haveged服务

HAVEGE是一个从内部CPU硬件状态(缓存,分支预测因子,TLBs)作为不确定根源的随机数生成器。可以作为rgnd的替代。这个软件包是通过EPEL仓库提供

测试

要了解熵池的补充数度有多快,可以使用如下命令

注意:由于4KB的熵池限制,你不能获得大于4095的值。

测试当前熵池源的质量,使用命令:

虚拟机内部使用rngd经验小结

  • 通过virsh edit VM编辑KVM虚拟机的配置,增加

  • 虚拟机重启后会在虚拟机内部增加/dev/random/dev/urandom两个设备

  • 需要配置rngd服务启动参数,增加-r /dev/urandom,否则会导致rngd进程启动后D住

    • CentOS 6 修改/etc/sysconfig/rngd设置参数EXTRAOPTIONS="-r /dev/urandom"

    • CentOS 7 复制配置文件cp /usr/lib/systemd/system/rngd.service /etc/systemd/system,并修改ExecStart=/sbin/rngd -f -r /dev/urandom

参考

Last updated

Was this helpful?