是什么不断消耗熵?

win*_*ner 22 linux random

如果我这样做,watch cat /proc/sys/kernel/random/entropy_avail我会看到我的系统熵随着时间的推移缓慢增加,直到达到 180-190 范围,此时它下降到 120-130 左右。熵的下降似乎每二十秒发生一次。即使lsof说没有进程已经/dev/random/dev/urandom打开,我也观察到这一点。什么在消耗熵?内核是否也需要熵,或者它可能正在将较大的池重新处理成更小、质量更好的池?

这是在裸机上,没有 SSL/SSH/WPA 连接。

Lek*_*eyn 22

熵不仅通过 丢失/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 /熵观察者.c

请注意,可能存在也会消耗熵的后台进程。在适当的内核上使用跟踪点,您可以看到修改熵池的进程。记录与随机子系统相关的所有跟踪点的示例用法,包括-g所有 CPU ( ) 上的调用链 ( ) 在-a1 秒后开始测量以忽略其自己的进程 ( -D 1000) 并包括时间戳 ( -T):

sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
Run Code Online (Sandbox Code Playgroud)

使用以下任一命令读取它(perf.data根据需要更改所有者):

perf report  # opens an interactive overview
perf script  # outputs events after each other with traces
Run Code Online (Sandbox Code Playgroud)

perf script输出给出了一个有趣的见解,并显示时关于熵的8个字节(64位)被周期性地在我的机器排出:

kworker/0:2 193 [000] 3292.235908: random:extract_entropy: ffffffff8173e956 pool: nbytes 8 entropy_count 921 caller _xfer_secondary_pool
                  5eb857 提取熵 (/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 提取熵 (/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)

...

交换器 0 [002] 3292.507720:随机:credit_entropy_bits:ffffffff8173e956 池:位 2 entropy_count 859 entropy_total 2 caller 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)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • +1 指出即使是看似“无害”的操作(例如启动程序)也会消耗少量熵。 (2认同)