如果watch cat /proc/sys/kernel/random/entropy_avail
可以,我的系统熵会随着时间的推移缓慢增加,直到达到180-190范围,然后下降到120-130左右。熵的下降似乎大约每二十秒发生一次。即使lsof
说没有进程/dev/random
或没有进程,我也观察到这一点/dev/urandom
。是什么在消散熵?内核是否还需要熵,还是正在将较大的池重新处理为较小的质量更好的池?
这是在没有SSL / SSH / WPA连接的裸机上。
如果watch cat /proc/sys/kernel/random/entropy_avail
可以,我的系统熵会随着时间的推移缓慢增加,直到达到180-190范围,然后下降到120-130左右。熵的下降似乎大约每二十秒发生一次。即使lsof
说没有进程/dev/random
或没有进程,我也观察到这一点/dev/urandom
。是什么在消散熵?内核是否还需要熵,还是正在将较大的池重新处理为较小的质量更好的池?
这是在没有SSL / SSH / WPA连接的裸机上。
Answers:
熵不仅通过丢失/dev/{,u}random
,内核也需要一些熵。例如,新进程具有随机地址(ASLR),网络数据包需要随机序列号。甚至文件系统模块也可以消除一些熵。请参阅drivers / char / random.c中的注释。另请注意,它entropy_avail
是指输入池,而不是输出池(基本上是非阻塞/dev/urandom
和阻塞/dev/random
)。
如果您需要观察熵池,请不要使用watch cat
,因为每次调用都会消耗熵cat
。过去,我还想观察这个池,因为GPG生成密钥的速度非常慢,因此我编写了一个C程序,其唯一目的是观察熵池:https : //git.lekensteyn.nl/c-files/tree /entropy-watcher.c。
请注意,可能存在一些也会消耗熵的后台过程。在适当的内核上使用跟踪点,您可以看到修改熵池的过程。用法示例记录了与随机子系统有关的所有跟踪点,包括-g
所有CPU ()上的调用链(),-a
在1秒后开始测量以忽略其自身的进程(-D 1000
)并包括时间戳(-T
):
sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
使用以下两个命令之一读取它(perf.data
根据需要更改所有者):
perf report # opens an interactive overview
perf script # outputs events after each other with traces
的perf script
输出给出了一个有趣的见解,并显示时关于熵的8个字节(64位)被周期性地在我的机器排出:
kworker / 0:2 193 [000] 3292.235908:random:extract_entropy:ffffffff8173e956池:nbytes 8 entropy_count 921个调用者_xfer_secondary_pool 5eb857 extract_entropy(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5eb984 _xfer_secondary_pool(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5ebae6 push_to_pool(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 293a05 process_one_work(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 293ce8 worker_thread(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 299998 kthread(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 7c7482 ret_from_fork(/lib/modules/4.6.2-1-ARCH/build/vmlinux) kworker / 0:2 193 [000] 3292.235911:random:debit_entropy:ffffffff8173e956:debit_bits 64 5eb3e8 account.part.12(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5eb770 extract_entropy(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5eb984 _xfer_secondary_pool(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5ebae6 push_to_pool(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 293a05 process_one_work(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 293ce8 worker_thread(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 299998 kthread(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 7c7482 ret_from_fork(/lib/modules/4.6.2-1-ARCH/build/vmlinux) ... swapper 0 [002] 3292.507720:随机:credit_entropy_bits:ffffffff8173e956池:bits 2 entropy_count 859 entropy_total 2主叫方add_interrupt_randomness 5eaab6 credit_entropy_bits(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 5ec644 add_interrupt_randomness(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2d5729 handle_irq_event_percpu(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2d58b9 handle_irq_event(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2d8d1b handle_edge_irq(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 230e6a handle_irq(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 7c9abb do_IRQ(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 7c7bc2 ret_from_intr(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 6756c7 cpuidle_enter(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2bd9fa call_cpuidle(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2bde18 cpu_startup_entry(/lib/modules/4.6.2-1-ARCH/build/vmlinux) 2510e5 start_secondary(/lib/modules/4.6.2-1-ARCH/build/vmlinux)
显然,这是通过将熵从输入池传递到输出池来防止熵的浪费:
/*
* Credit (or debit) the entropy store with n bits of entropy.
* Use credit_entropy_bits_safe() if the value comes from userspace
* or otherwise should be checked for extreme values.
*/
static void credit_entropy_bits(struct entropy_store *r, int nbits)
{
...
/* If the input pool is getting full, send some
* entropy to the two output pools, flipping back and
* forth between them, until the output pools are 75%
* full.
*/
...
schedule_work(&last->push_work);
}
/*
* Used as a workqueue function so that when the input pool is getting
* full, we can "spill over" some entropy to the output pools. That
* way the output pools can store some of the excess entropy instead
* of letting it go to waste.
*/
static void push_to_pool(struct work_struct *work)
{
...
}
watch
)稳定增长,然后急剧下降。如果watch
每次读取都消耗熵,则它实际上应该稳定地减少。
cat
在理论上应该具有相同的熵耗,这是不可见的。事实证明,当存在“足够”的熵时,熵将移动到另一个池中。
lsof并不是最好的监视工具,/dev/random
因为一个进程的读取在很短的时间内就结束了。我不知道获取读取过程的好方法,但是使用inotify
它可以监视是否存在读取。
这里基本上有两种方法:
N秒后使用以下方法获取摘要:
inotifywatch -v -t 60 /dev/random
查看实时访问事件:
inotifywait -m --timefmt '%H:%M:%S' --format '%T: %e' /dev/random
两者都不会给您处理,而后者不会给您带来读取的空间。第一个将为您提供摘要,如下所示:
total access close_nowrite open filename
18 16 1 1 /dev/random
如果您运行该程序并执行dd if=/dev/random of=/tmp/foo bs=1 count=3
,您就会明白。
无论如何。当内核从池中使用时,这不会给您带来麻烦。
当涉及到使用以下方法检查熵的状态时
watch cat /proc/sys/kernel/random/entropy_avail
并不是最好的主意,因为每个人cat
都会消耗熵。(我现在看到它弹出另一个也提到此问题的答案。)我也对此有一些C代码,并试图在昨天找到它。我将查看是否可以找到它并稍后更新答案。
/dev/random
(我知道该网站上有类似的示例)。
watch cat
: use Fcntl 'SEEK_SET'; open(my $fh,"<", "/proc/sys/kernel/random/entropy_avail"); while (1) { print <$fh>; sleep(1); seek($fh,0,SEEK_SET); }
/dev/random
毕竟,它是用于安全加密目的的东西,并且实现不能过于幼稚。可能在这里的最后一点暗示了一种解释:en.wikipedia.org/wiki/Entropy_pool#Using_observed_events(从“用密钥和初始化向量维护流密码开始”)-> 只要足够,池就会被替换数据已累积。