Entropi tidak hanya hilang melalui /dev/{,u}random
, kernel juga membutuhkan beberapa. Misalnya, proses baru memiliki alamat acak (ASLR) dan paket jaringan memerlukan nomor urut acak. Bahkan modul sistem file dapat menghapus beberapa entropi. Lihat komentar di driver/char/random.c. Perhatikan juga bahwa entropy_avail
mengacu pada kumpulan input, bukan kumpulan keluaran (pada dasarnya /dev/urandom
non-pemblokiran dan /dev/random
pemblokiran ).
Jika Anda perlu memperhatikan kumpulan entropi, jangan gunakan watch cat
, yang akan menggunakan entropi pada setiap pemanggilan cat
. Di masa lalu saya juga ingin menonton kumpulan ini karena GPG sangat lambat dalam menghasilkan kunci, oleh karena itu saya menulis program C dengan tujuan tunggal untuk menonton kumpulan entropi:https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c.
Perhatikan bahwa mungkin ada proses latar belakang yang juga mengonsumsi entropi. Menggunakan tracepoints pada kernel yang sesuai, Anda dapat melihat proses yang mengubah kumpulan entropi. Contoh penggunaan yang mencatat semua tracepoint yang terkait dengan subsistem acak termasuk rantai panggilan (-g
) di semua CPU (-a
) mulai mengukur setelah 1 detik untuk mengabaikan prosesnya sendiri (-D 1000
) dan menyertakan stempel waktu (-T
):
sudo perf record -e random:\* -g -a -D 1000 -T sleep 60
Bacalah dengan salah satu dari perintah ini (ganti pemilik perf.data
sesuai kebutuhan):
perf report # opens an interactive overview
perf script # outputs events after each other with traces
perf script
output memberikan wawasan yang menarik dan menunjukkan kapan sekitar 8 byte (64 bit) entropi terkuras secara berkala di mesin saya:
kworker/0:2 193 [000] 3292.235908: random:extract_entropy: ffffffff8173e956 pool: nbytes 8 entropy_count 921 caller _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: random:credit_entropy_bits: ffffffff8173e956 pool: bits 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)
Rupanya ini terjadi untuk mencegah pemborosan entropi dengan mentransfer entropi dari kumpulan input ke kumpulan keluaran:
/*
* 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)
{
...
}
lsof bukan alat terbaik untuk memantau /dev/random
seperti yang dibaca oleh suatu proses berakhir dalam sangat waktu singkat. Saya tidak tahu metode yang baik untuk mendapatkan proses apa yang sedang dibaca, tetapi menggunakan inotify
Anda dapat memantau jika ada bacaan.
Di sini pada dasarnya ada dua cara:
-
Dapatkan ringkasan setelah N detik dengan:
inotifywatch -v -t 60 /dev/random
-
Lihat langsung mengakses acara:
inotifywait -m --timefmt '%H:%M:%S' --format '%T: %e' /dev/random
Tidak ada yang akan memberi Anda proses dan yang terakhir tidak akan memberi Anda ukuran baca. Yang pertama akan memberi Anda ringkasan seperti di:
total access close_nowrite open filename
18 16 1 1 /dev/random
Jika Anda menjalankannya dan lakukan dd if=/dev/random of=/tmp/foo bs=1 count=3
, Anda mengerti.
Bagaimanapun. Ini tidak akan memberi Anda kutu ketika kernel mengkonsumsi dari kumpulan.
Saat memeriksa status entropi menggunakan
watch cat /proc/sys/kernel/random/entropy_avail
bukan ide terbaik karena setiap cat
akan mengkonsumsi entropi. (Saya melihat sekarang muncul jawaban lain yang juga menyebutkan ini.) Saya juga memiliki beberapa kode C untuk ini dan mencoba menemukannya kemarin. Saya akan melihat apakah saya dapat menemukannya dan memperbarui jawabannya nanti.