web-dev-qa-db-ja.com

エントロピーを何が食べているのですか?または、entropy_availは実際には何を示していますか?

以下は、Raspberry Piでの/proc/sys/kernel/random/entropy_availの値を示すグラフです。 この答え これは正しくない可能性があります それを次のように説明します:

/proc/sys/kernel/random/entropy_availは、単に/dev/randomから現在読み取ることができるビット数を提供するだけです。それ以上の読み取りを試みると、より多くのエントロピーが利用可能になるまでブロックされます。

パターンは常に同じ「安定した」鋸パターンになり、1分ごとに約130ビット減少します。エントロピーが大きくなりすぎると、何かがそれを「食べて」700-800の範囲に戻ります。デバイスを再起動しても、エントロピーは1分ごとに消費されますが、より小さなチャンクであるので、700〜800の範囲に再び成長することができます。

どのようにグラフを解釈しますか?何が起こっているのですか?

乱数ジェネレーターを使用するプロセスだけがあった場合、entropy_availが値の提供を停止すると、/dev/randomが(デバイスのハードウェアを使用して)バランスを失ったときに無限に増加するか、200のレベルまで減少するはずです。

また、いずれかの監視方法(以下のチェックを参照)がエントロピーに影響を与えた場合は、エントロピーを1分間隔で急激に増減させるのではなく、毎秒減少させる必要があります。

(マシンをアイドル状態にしておくと、安定した「鋸」パターンが数日間続きますが、スクリーンショットを短時間で撮りました)


グラフ

  • マシンは長時間アイドル状態です:

    enter image description here

  • 19:14:45頃に、別のマシンがPiのapt-cacherにアクセスしました-エントロピーが増加しました(ネットワーク使用から推測)。その後、19:16:30に「通常のレベル」への低下が通常よりも大きくなりました(これも再現可能です。entropy_availが大きくなりすぎると、低下が速くなります)。

    enter image description here

  • マシンを再起動すると、エントロピーは「通常」のレベルに達するまで増大します。

    enter image description here

    enter image description here

  • 再びアイドル状態になります:

    enter image description here

  • 再起動後、エントロピー減少の時点が変化しますが、それでも1分ごとに発生します。

    enter image description here


小切手

  • netdata (監視プログラム)を停止し、watch -n1 cat /proc/sys/kernel/random/entropy_availで確認しました。 entropy_availの値は、通常の1分間隔で800まで増加し、680まで減少します。

  • アドバイスに従って「/ dev/randomと/ dev/urandomにアクセスするためにすべてのプロセスをトレースします」私はinotifywaitからのアイデア)でチェックしましたDebianでの同様の質問への回答 )VMそして/dev/randomがドロップした瞬間に/dev/urandomまたはentropy_availにアクセスできません(もちろん、手動でイベントをログに記録して確認します)。

  • entropy-watcher を使用して、watchを使用しないことをお勧めします。結果は、着実に増加し、1分ごとに急激に減少することと一致しています。

    833 (-62)
    836 (+3)
    838 (+2)
    840 (+2)
    842 (+2)
    844 (+2)
    846 (+2)
    848 (+2)
    850 (+2)
    852 (+2)
    854 (+2)
    856 (+2)
    858 (+2)
    860 (+2)
    862 (+2)
    864 (+2)
    866 (+2)
    868 (+2)
    871 (+3)
    873 (+2)
    811 (-62)
    

同じ現象を説明するUnix StackExchangeに関する2つの質問(後で発見):

20
techraf

まず、 "_/proc/sys/kernel/random/entropy_avail_が単に現在_/dev/random_"から読み取れるビット数を与えるという主張は誤りです。

_entropy_avail_フィールドは _input_pool.entropy_count_ を読み取り、「出力」プールはurandom(非ブロッキングプール)およびrandom(ブロッキングプール)。


この答え で述べたように、新しいプロセスの生成はASLRなどのエントロピーを消費します。監視プログラムは、呼び出しごとに新しいプロセスを生成します。おそらく監視ツールが同じことを行います(おそらく、ステータスを取得するために外部プログラムを呼び出す必要がある他の監視ソースの1つを介して)。

エントロピープールをドレインせずに監視するには、エントロピーウォッチャープログラムを試すことができます(リンクされた回答を参照)。

_entropy-watcher_の数値を注意深く見ると、間隔を置いて約64ビットのエントロピーを失うようです。他の回答の分析に基づくと、これは、エントロピーを「出力プール」に移動して無駄を省いた結果であると思われます。これはLinux v4.6で観察され、将来の実装は異なる可能性があります。

ソースコード(v_4.6の_drivers/char/random.c_)に基づいて、出力プール(_/dev/{u,}random_またはget_random_bytes())を読み取ると_extract_entropy{,_user}_が呼び出され、_xfer_secondary_pool_およびaccount。ブロッキングプールには、プロパティlimit set(_r->limit == 1_)があり、両方の機能に影響します。

  • account()の場合、エントロピーが低すぎると、ブロッキングプールからデータが返されません。非ブロッキング出力プールの場合、残りのエントロピーは消費されますが、データは引き続き返されます。
  • xfer_secondary_pool()は、出力プールで十分なエントロピーが利用できることを保証します。 blocking出力プールのエントロピーが不十分な場合、(可能な場合)入力プールから一部を取得します。
  • 非ブロッキング出力プールのxfer_secondary_pool()は、_/proc/sys/kernel/random/urandom_min_reseed_secs_パラメータに従って特別に動作します。この値がゼロ以外の場合、最後の転送から少なくとも_urandom_min_reseed_secs_秒が経過した場合にのみ、エントロピーが入力プールから取得されます。デフォルトでは、この値は60秒に設定されています。

最後のポイントは、最終的に60秒ごとに入力プールにエントロピーの流出が見られる理由を説明しています。一部のコンシューマーが非ブロッキング出力プール(TCPシーケンス番号、ASLR、_/dev/urandom_、getrandom()、...)からランダムなバイトを要求すると、128ビットが入力プールから非ブロッキング出力プールを再シードします。

8
Lekensteyn