以下は、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分間隔で急激に増減させるのではなく、毎秒減少させる必要があります。
(マシンをアイドル状態にしておくと、安定した「鋸」パターンが数日間続きますが、スクリーンショットを短時間で撮りました)
グラフ
マシンは長時間アイドル状態です:
19:14:45頃に、別のマシンがPiのapt-cacher
にアクセスしました-エントロピーが増加しました(ネットワーク使用から推測)。その後、19:16:30に「通常のレベル」への低下が通常よりも大きくなりました(これも再現可能です。entropy_avail
が大きくなりすぎると、低下が速くなります)。
マシンを再起動すると、エントロピーは「通常」のレベルに達するまで増大します。
再びアイドル状態になります:
再起動後、エントロピー減少の時点が変化しますが、それでも1分ごとに発生します。
小切手
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つの質問(後で発見):
まず、 "_/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ビットが入力プールから非ブロッキング出力プールを再シードします。