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


21

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

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


良い質問です。具体的な答えはできませんが、「エントロピープール」は、未使用時に増加するものではないということは理にかなっています。 /dev/random結局のところ、安全な暗号化の目的で使用されるものであり、実装は単純である余裕はありません。1つの説明はここで最後の点でほのめかしされる可能性があります。en.wikipedia.org/wiki/Entropy_pool#Using_observed_events(「...キーと初期化ベクトルを持つストリーム暗号の維持」で始まる) - >プールがされて置き換えられたときに十分なデータが蓄積されました。
goldilocks

いずれにせよ、Linuxのエントロピー計算/dev/randomは非常に偽物であることに注意してください。エントロピープールが一度いっぱいになると、/dev/urandomと同じくらい良好になり/dev/randomます。
ジル 'SO-悪であるのをやめる'

1
@techrafうわー、その答えは速くなった。2.5年後に答えを得るとは思っていませんでした。
wingedsubmariner

回答:


20

エントロピーはを介して失われるだけでなく/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

エントロピーも消費するバックグラウンドプロセスがある場合があることに注意してください。適切なカーネルでトレースポイントを使用すると、エントロピープールを変更するプロセスを確認できます。-gすべてのCPU上のコールチェーン()を含むランダムサブシステムに関連するすべてのトレースポイントを記録する使用例()-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 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)

...

スワッパー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)

どうやらこれは、エントロピーを入力プールから出力プールに転送することにより、エントロピーの浪費を防ぐために起こります:

/*
 * 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良い観察、定期的に呼び出すことcatは、理論的には見えないはずの同じエントロピー流出を持つべきです。「十分な」エントロピーがある場合、エントロピーは別のプールに移動することがわかります。
Lekensteyn

4

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

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

  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がエントロピーを消費するため、最良のアイデアではありません。(これについても別の回答が表示されました。)また、このためのCコードもいくつかあり、昨日見つけようとしました。それを見つけて後で答えを更新できるかどうかを確認します。


auditdは、読み取りをログに記録できます/dev/random(このサイトには同様の例があります)。
ジル「SO-悪であるのをやめる」

1
代わりに、次のPerlを使用してはどうwatch catuse Fcntl 'SEEK_SET'; open(my $fh,"<", "/proc/sys/kernel/random/entropy_avail"); while (1) { print <$fh>; sleep(1); seek($fh,0,SEEK_SET); }
gmatht
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.