fuser -v /dev/urandom
を実行すると、現在/dev/urandom
が開いているプロセスがわかりますが、それだけです。それぞれが時間の経過とともにどれだけのエントロピーを使い果たしているかについて何かを決定することはありましたか?たとえば、あるプロセスが毎分約1ビットのエントロピーを使用しているのに対し、別のプロセスは毎秒約8ビットを使用している可能性があります。それを判断する方法が欲しいのですが。
エントロピーが消費されないため、短い答えは0です。
一般的な誤解 エントロピーが消費されるというものがあります—ランダムビットを読み取るたびに、これによりランダムソースからエントロピーが削除されます。これは間違っています。 エントロピーを「消費」しません 。はい、 Linuxのドキュメントで間違っています 。
Linuxシステムのライフサイクルには、次の2つの段階があります。
/dev/random
は、十分なエントロピーを蓄積したと見なすまでブロックします。 /dev/urandom
は低エントロピーデータを喜んで提供します。/dev/random
は「エントロピーネギ」の偽のレートを割り当て、時々ブロックします。 /dev/urandom
は暗号品質のランダムデータを喜んで提供します。FreeBSDはそれを正しく理解します。FreeBSDでは、/dev/random
(または同じことである/dev/urandom
)は、十分なエントロピーがない場合はブロックし、エントロピーが十分になると、ランダムデータを吐き出し続けます。 Linuxでは、/dev/random
も/dev/urandom
も役に立ちません。
実際には、/dev/urandom
を使用し、システムをプロビジョニングするときに、エントロピープールが供給されることを確認します(ディスク、ネットワーク、およびマウスアクティビティから、ハードウェアソースから、外部マシンからなど)。
/dev/urandom
から読み取られるバイト数を読み取ろうとすることもできますが、これはまったく意味がありません。 /dev/urandom
から読み取っても、エントロピープールは使い果たされません。各コンシューマーは、名前を付けたい時間の単位ごとに0ビットのエントロピーを使用します。
自動化されていませんが、straceなどのツールを使用して、urandomに関連するファイル記述子からの読み取りを監視できます。次に、特定の期間に読み取られたデータの量を確認して、読み取り速度を取得します。
Linuxでentropy_availableを使い果たしている可能性のあるプロセスがわからない(または疑わない)場合は、問題に取り組む方法がいくつかあります。
前述のように、straceを使用できます。これは、どのプロセスを調べたいかについての有用な洞察を得るのに最適です。
Auditdを使用して、どのプロセスopen/ dev/randomまたは/ dev/urandomを監査できますが、読み取られるデータの量はわかりません(ロギングの問題を防ぐため)。ここにいくつかのコマンドがルールをリストしてから2つの時計を追加します
auditctl -l
auditctl -w /dev/random
auditctl -w /dev/urandom
auditctl -l
次に、ボックスにSSHで接続します(または、ddなどの/ dev/urandomまたは同様のものを開く結果になるはずの何かを実行します)。
ausearch-ts最近| aureport -f
私の場合、次のようなものが表示されます。
[root@metrics-d02 vagrant]# ausearch -ts recent | aureport -f
File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 07/01/20 01:13:36 /dev/urandom 2 yes /usr/bin/dd 1000 6383
2. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6389
3. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6388
4. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6390
5. 07/01/20 01:16:44 /dev/urandom 2 yes /usr/sbin/sshd 1000 6408
それらの時計を無効にしてください
auditctl -W /dev/random
auditctl -W /dev/urandom
ただし、これは読み取り/書き込みなどではないシステムコールのデータのみをキャプチャするため、すでに開いているものがある場合は、読み取られていることはわかりません。
しかし、(Prometheusとnode_exporterを使用して)まだ鋸歯状のパターンが見られ、VM(エントロピーを収集するものがないCentOS 7)がentropy_availableが200近くまで上昇していることを報告していることに気付きました。そのため、0に急落します。
Lsof(必要に応じてフューザーの)は何かを提供しますか?
[root@metrics-d02 vagrant]# lsof /dev/random /dev/urandom
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
chronyd 2184 chrony 3r CHR 1,9 0t0 5339 /dev/urandom
tuned 2525 root 5r CHR 1,9 0t0 5339 /dev/urandom
ただし、文字デバイスのメジャー番号とマイナー番号に注意してください。別の方法でテストしています...(これが役立つかどうかはわかりません。このVMで実行されていないDockerなどの観点から考えてみてください)
[root@metrics-d02 vagrant]# ls -l /dev/*random
crw-rw-rw-. 1 root root 1, 8 Dec 19 01:24 /dev/random
crw-rw-rw-. 1 root root 1, 9 Dec 19 01:24 /dev/urandom
[root@metrics-d02 vagrant]# lsof | grep '1,[89]'
chronyd 2184 chrony 3r CHR 1,9 0t0 5339 /dev/urandom
tuned 2525 root 5r CHR 1,9 0t0 5339 /dev/urandom
gmain 2525 2714 root 5r CHR 1,9 0t0 5339 /dev/urandom
tuned 2525 2715 root 5r CHR 1,9 0t0 5339 /dev/urandom
tuned 2525 2717 root 5r CHR 1,9 0t0 5339 /dev/urandom
tuned 2525 2754 root 5r CHR 1,9 0t0 5339 /dev/urandom
さて、chronydとtunedの2つのプロセスがあります。 straceを使ってみましょう。 lsofは、chronyがfile-discriptor3を使用して読み取るために/ dev/urandomを開いていると語った
[root@metrics-d02 vagrant]# strace -p 2184 -f
strace: Process 2184 attached
select(6, [1 2 5], NULL, NULL, {98, 516224}
.... (I'm waiting)
そのため、chronydは、このシステムコールを開始してから98秒のタイムアウトで、何らかのアクティビティを待機しています。
私が待っている間、システムでの私の活動が、利用可能なランダムビットのカーネル推定を増加させる可能性があることを強調する必要があります。 (entropy_available)...だから、座ってプロメテウスのグラフを見てください...
調整して繰り返すこともできます...(今回は、ファイル記述子5専用のタイムスタンプとgrepフィルターを追加します(読み取りなどの呼び出しでは、これが最初の引数になります)
[root@metrics-d02 vagrant]# strace -p 2525 -f -tt -T 2>&1 | grep '(5,'
Red Hatには、さらに議論するブログがあります CSPRNG(Cryptographically Secure Psuedo Random Number Generator) 。プロセスが乱数にアクセスできる他のいくつかの方法について説明します。
AT_RANDOMは有用ではありませんが、すべてのプロセスに存在するため、プロセスを開始するだけで、少なくとも少しは無駄になるはずです。
Lsofを使用して上に示したものでは不十分であり、getrandom()の使用を明らかにしていないことに気付くでしょう。ただし、getrandom()はシステムコールであるため、auditctlを使用してその使用法を明らかにできるはずです。
[root@metrics-d02 vagrant]# auditctl -a exit,always -F Arch=b64 -S getrandom
[root@metrics-d02 vagrant]# auditctl -l
-a always,exit -F Arch=b64 -S getrandom
[root@metrics-d02 vagrant]# tail -F -n0 /var/log/audit/audit.log
... (now we wait)
私は退屈してボックスにSSHで接続し、興味深いクールなものをたくさん見ましたが、getrandom()はありませんでした。これは、以前に/ dev/urandomAPIを使用して見たのと同じくらい驚くべきことではありません。
したがって、グラフのくぼみを説明しようとすると、/ dev/* randomを開いているものはなく、現在開いているものも使用しておらず、getrandom()を呼び出していないようです...他に何かありますか[/ dev/randomの背後にあるプール]からデータを消費しますか?カーネルはどうですか?アドレス空間配置のランダム化(ASLR)などの機能を検討してください。
https://access.redhat.com/solutions/4446 [サブスクリプションが必要]
[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space
2
ここでの「2」は、mmapやstack(など)などがロードされる場所のランダム化に加えて、ヒープのランダム化も有効にすることを意味します。それをオフにするとどうなりますか
[root@metrics-d02 vagrant]# echo 0 > /proc/sys/kernel/randomize_va_space
[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space
0
(回答:同じこと...おそらく他の誰かがこれをさらに説明することができます)
カーネルは、AT_RANDOMが設定される場所でもあります。これは、straceを使用して/ dev/* randomまたはgetrandom()を呼び出さないことを確認できる簡単な例です。
[vagrant@metrics-d02 ~]$ cat at_random.c
#include <stdio.h>
#include <stdint.h>
#include <sys/auxv.h>
#define AT_RANDOM_LEN 16
int main(int argc, char *argv[])
{
uintptr_t at_random;
int i;
at_random = getauxval(AT_RANDOM);
for (i=0; i<AT_RANDOM_LEN; i++) {
printf("%02x", ((uint8_t *)at_random)[i]);
}
printf("\n");
/* show that it's a one-time thing */
for (i=0; i<AT_RANDOM_LEN; i++) {
printf("%02x", ((uint8_t *)at_random)[i]);
}
printf("\n");
}
[vagrant@metrics-d02 ~]$ make at_random
cc at_random.c -o at_random
[vagrant@metrics-d02 ~]$ ./at_random
255f8d5711b9aecf9b5724aa53bc968b
255f8d5711b9aecf9b5724aa53bc968b
[vagrant@metrics-d02 ~]$ ./at_random
ef4b25faf9f435b3a879a17d0f5c1a62
ef4b25faf9f435b3a879a17d0f5c1a62
それがお役に立てば幸いです。
実際には、最初にJavaワークロードを最初に調べます。これは、私が通常これに最も噛まれている場所だからです。 https://blogs.Oracle.com/luzmestre/を参照)例として、why-does-my-weblogic-server-takes-a-long-time-to-start 。