Apa yang terus menguras entropi?

21

Jika saya lakukan, watch cat /proc/sys/kernel/random/entropy_availsaya melihat bahwa sistem saya entropi perlahan-lahan meningkat dari waktu ke waktu, sampai mencapai kisaran 180-190 di mana titik itu turun menjadi sekitar 120-130. Penurunan entropi tampaknya terjadi setiap dua puluh detik. Saya mengamati bahkan ini ketika lsofmengatakan bahwa tidak ada proses memiliki /dev/randomatau /dev/urandomterbuka. Apa yang menguras entropi? Apakah kernel juga perlu entropi, atau mungkin sedang memproses ulang pool yang lebih besar menjadi pool yang lebih kecil dan berkualitas lebih baik?

Ini pada mesin bare-metal, tanpa koneksi SSL / SSH / WPA.

wingedsubmariner
sumber
Pertanyaan yang bagus, dan walaupun saya tidak bisa memberikan jawaban yang spesifik, masuk akal bagi saya bahwa "kumpulan entropi" bukan hanya sesuatu yang seharusnya meningkat ketika tidak digunakan. /dev/randomBagaimanapun, adalah sesuatu yang digunakan untuk tujuan kriptografi yang aman, dan implementasinya tidak bisa naif. Satu penjelasan mungkin diisyaratkan pada poin terakhir di sini: en.wikipedia.org/wiki/Entropy_pool#Using_observed_events (dimulai dengan "Mempertahankan stream cipher dengan kunci dan vektor Inisialisasi ...") -> kolam diganti setiap kali cukup data telah terakumulasi.
goldilocks
Perhatikan bahwa bagaimanapun juga, perhitungan entropi Linux /dev/randomcukup banyak - setelah kumpulan entropi telah penuh satu kali, /dev/urandomsama baiknya /dev/random.
Gilles 'SO- stop being evil'
1
@ Techraf Wow, jawaban itu jadi cepat. Saya tidak pernah berharap mendapatkan jawaban 2,5 tahun kemudian.
wingedsubmariner

Jawaban:

20

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 yang entropy_availmerujuk pada kumpulan input , bukan kumpulan output (pada dasarnya non-blocking /dev/urandomdan blocking /dev/random).

Jika Anda perlu menonton kumpulan entropi, jangan gunakan watch cat, yang akan mengkonsumsi entropi di setiap doa cat. Di masa lalu saya juga ingin menonton pool ini karena GPG sangat lambat dalam menghasilkan kunci, oleh karena itu saya menulis sebuah program C dengan tujuan tunggal untuk menonton pool entropi: https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c .

Perhatikan bahwa mungkin ada proses latar belakang yang juga mengonsumsi entropi. Menggunakan tracepoint pada kernel yang sesuai, Anda dapat melihat proses yang memodifikasi kumpulan entropi. Contoh penggunaan yang mencatat semua tracepoint yang terkait dengan subsistem acak termasuk callchain ( -g) pada semua CPU ( -a) mulai mengukur setelah 1 detik untuk mengabaikan prosesnya sendiri ( -D 1000) dan termasuk cap waktu ( -T):

sudo perf record -e random:\* -g -a -D 1000 -T sleep 60

Bacalah dengan salah satu dari perintah ini (ganti pemilik perf.datasesuai kebutuhan):

perf report  # opens an interactive overview
perf script  # outputs events after each other with traces

The perf scriptOutput memberikan wawasan yang menarik dan menunjukkan ketika sekitar 8 byte (64 bit) entropi secara berkala dikeringkan pada mesin saya:

kworker / 0: 2 193 [000] 3292.235908: acak: extract_entropy: ffffffff8173e956 kumpulan: nbytes 8 entropy_count 921 pemanggil _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: acak: debit_entropy: ffffffff8173e956: debit_bits 64
                  5eb3e8 akun.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: acak: credit_entropy_bits: ffffffff8173e956 kumpulan: bit 2 entropy_count 859 entropy_total 2 pemanggil 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)

Tampaknya 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)
{
    ...
}
Lekensteyn
sumber
2
+1 untuk menunjukkan bahwa bahkan operasi yang tampaknya "tidak berbahaya" seperti memulai program dapat menguras sejumlah kecil entropi.
CVn
Namun penjelasan ini agak bertentangan dengan situasi yang dijelaskan dalam pertanyaan, bukan? Di sana entropi (dipantau dengan watch) tumbuh mantap kemudian turun tajam. Jika watchdikonsumsi entropi pada setiap bacaan, itu seharusnya benar-benar berkurang terus.
techraf
@ Techraf Pengamatan yang baik, secara berkala memohon catharus dalam teori memiliki saluran entropi yang sama yang seharusnya tidak terlihat. Ternyata entropi dipindahkan ke kumpulan yang berbeda ketika ada entropi "cukup".
Lekensteyn
4

lsof bukan alat terbaik ke monitor/dev/randomsebagai salah satu dibaca oleh suatu proses adalah lebih dalam yang sangat waktu singkat. Saya tidak tahu metode yang bagus untuk mendapatkan proses membaca, tetapi menggunakaninotifyAnda dapat memonitor jika ada membaca.

Di sini pada dasarnya ada dua cara:

  1. Dapatkan ringkasan setelah N detik dengan:

    inotifywatch -v -t 60 /dev/random 
    
  2. Lihat acara akses langsung :

    inotifywait -m --timefmt '%H:%M:%S' --format '%T: %e' /dev/random
    

Tidak akan memberi Anda proses dan yang terakhir tidak akan memberi Anda ukuran membaca. Yang pertama akan memberi Anda ringkasan seperti pada:

total  access  close_nowrite  open  filename
18     16      1              1     /dev/random

Jika Anda menjalankan dan melakukan itu dd if=/dev/random of=/tmp/foo bs=1 count=3, Anda mendapatkan idenya.

Bagaimanapun. Ini tidak akan memberi Anda kutu ketika kernel mengkonsumsi dari pool.


Ketika datang untuk memeriksa status menggunakan entropi

watch cat /proc/sys/kernel/random/entropy_avail

bukan ide terbaik karena masing-masing catakan mengkonsumsi entropi. (Saya melihat sekarang muncul jawaban lain yang juga menyebutkan ini.) Saya juga punya beberapa kode C untuk ini dan mencoba untuk menemukannya kemarin. Saya akan melihat apakah saya dapat menemukannya dan memperbarui jawaban nanti.

Runium
sumber
auditd dapat login membaca dari /dev/random(saya tahu ada contoh serupa di situs ini).
Gilles 'SO- berhenti bersikap jahat'
1
Bagaimana dengan menggunakan perl berikut sebagai pengganti 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); }
gmatht