Що продовжує зливу ентропії?


21

Якщо я це watch cat /proc/sys/kernel/random/entropy_availбачу, ентропія моїх систем повільно зростає, поки вона не досягне діапазону 180-190, після чого вона знижується приблизно до 120-130. Здається, краплі ентропії відбуваються приблизно кожні двадцять секунд. Я спостерігаю це, навіть коли lsofкаже, що жоден процес не має /dev/randomі не /dev/urandomвідкривається. Що зводить ентропію? Чи потрібне ядро ​​також ентропії, або, можливо, воно переробляє більший пул у менший пул кращої якості?

Це на машині з чистого металу, без з'єднань SSL / SSH / WPA.


Добре запитання, і хоча я не можу дати тобі конкретної відповіді, для мене має сенс, що "пул ентропії" - це не просто те, що повинно збільшуватися, якщо його не використовувати. /dev/randomзрештою, це те, що використовується для захищених криптографічних цілей, і реалізація не може дозволити собі бути наївною. Одним з пояснень може бути натякають в останній момент тут: en.wikipedia.org/wiki/Entropy_pool#Using_observed_events (починаючи з «Підтримувати потоковий шифр з ключем і вектором ініціалізації ...») -> пул замінюється , коли досить дані накопичені.
goldilocks

Зауважте, що в будь-якому випадку, обчислення ентропії Linux в цій системі /dev/randomє дуже хибною - колись пул ентропії один раз був заповнений, /dev/urandomтак само добре /dev/random.
Жил "ТАК - перестань бути злим"

1
@techraf Вау, ця відповідь отримала велику швидкість. Я ніколи не сподівався отримати відповідь через 2,5 роки.
крила підводного човна

Відповіді:


20

Ентропія втрачається не тільки через /dev/{,u}random, але ядро ​​також бере частину. Наприклад, нові процеси мають рандомізовані адреси (ASLR), а мережевим пакетам потрібні випадкові порядкові номери. Навіть модуль файлової системи може видалити деяку ентропію. Дивіться коментарі в драйверах / char / random.c . Також зауважте, що це entropy_availстосується пулу введення , а не пулів виходів (в основному не блокує /dev/urandomі блокує /dev/random).

Якщо вам потрібно дивитися пул ентропії, не використовуйте watch cat, що буде споживати ентропію при кожному виклику cat. Раніше я також хотів спостерігати за цим пулом, оскільки GPG дуже повільно генерує ключі, тому я написав програму C з єдиною метою дивитися пул ентропії: https://git.lekensteyn.nl/c-files/tree /entropy-watcher.c .

Зауважте, що можуть бути фонові процеси, які також вимагають ентропії. Використовуючи траєкторії на відповідному ядрі, ви можете побачити процеси, що змінюють пул ентропії. Приклад використання, який записує всі точки трасування, пов'язані з випадковою підсистемою, включаючи callchain ( -g) на всіх процесорах ( -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: випадковий: extra_entropy: ffffffff8173e956 пул: nbytes 8 entropy_count 921 calller _xfer_secondary_pool
                  5eb857 extra_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: випадковий: debit_entropy: ffffffff8173e956: debit_bits 64
                  5eb3e8 account.part.12 (/lib/modules/4.6.2-1-ARCH/build/vmlinux)
                  5eb770 extra_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 пул: біти 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)
{
    ...
}

2
+1, вказуючи на те, що навіть начебто "невинні" операції, такі як запуск програми, можуть виснажити невелику кількість ентропії.
CVn

Однак це пояснення трохи суперечить ситуації, описаній у питанні, чи не так? Там ентропія (за якою контролюється watch) постійно зростає, після чого різко падає. Якщо watchспоживати ентропію під час кожного читання, вона фактично повинна постійно зменшуватися.
techraf

@techraf Хороше спостереження, періодично звертаючись catдо теоретично, має бути однаковий ентропійний стік, який не повинен бути видно. Виявляється, що ентропія переміщується до іншого пулу, коли є "достатня" ентропія.
Лекенштейн

4

lsof - не найкращий інструмент для моніторингу,/dev/randomоскільки процес читання за часом закінчується за дуже короткий час. Я не знаю хорошого методу отримання того, який процес робить читання, але за допомогоюinotifyви можете контролювати, чи є читання.

Тут є два принципи:

  1. Отримайте підсумок через N секунд за допомогою:

    inotifywatch -v -t 60 /dev/random 
    
  2. Перегляд живих подій доступу:

    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збирає вживання ентропії. (Я бачу, що зараз з'явилася ще одна відповідь, яка також згадує про це.) У мене також є якийсь код С для цього і я намагався знайти його вчора. Я побачу, чи зможу це знайти, і відповідь оновитиму пізніше.


auditd може входити до читання /dev/random(я знаю, що на цьому сайті є подібні приклади).
Жил "ТАК - перестань бути злим"

1
Як щодо використання наступного perl замість 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.