web-dev-qa-db-ja.com

エントロピーを排出し続けるものは何ですか?

私が行った場合 watch cat /proc/sys/kernel/random/entropy_avail私のシステムのエントロピーは、180〜190の範囲に達するまでゆっくりと増加し、その時点で約120〜130に低下します。エントロピーの低下は約20秒ごとに発生するようです。 lsofがプロセスに/dev/randomまたは/dev/urandom 開いた。エントロピーを排出しているのは何ですか?カーネルにもエントロピーが必要ですか、それとも、より大きなプールをより小さく、より品質の高いプールに再処理していますか?

これはベアメタルマシン上にあり、SSL/SSH/WPA接続はありません。

21

エントロピーは/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

エントロピーも消費するバックグラウンドプロセスが存在する場合があることに注意してください。適切なカーネルでトレースポイントを使用すると、エントロピープールを変更するプロセスを確認できます。すべてのCPU(-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:random:extract_entropy:ffffffff8173e956 pool: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:ランダム: 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呼び出し元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)
{
    ...
}
20
Lekensteyn

lsofは監視に最適なツールではありません/dev/randomプロセスによって読み取られたものがvery短時間で終了するため。どのプロセスが読み取りを行っているかを知る良い方法はわかりませんが、inotifyを使用すると、監視できますif読んだ。

ここには基本的に2つの方法があります。

  1. N秒後に要約を取得するには:

    inotifywatch -v -t 60 /dev/random 
    
  2. liveアクセスイベントの表示:

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

どちらもプロセスを提供せず、後者は読み取りのサイズを提供しません。 1つ目は、次のような要約を提供します。

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コードもいくつか持っており、昨日それを見つけようとしました。見つけて後で回答を更新できるかどうか確認します。

4
Runium