web-dev-qa-db-ja.com

/ dev / urandomからどのくらいのエントロピーを使用しているかを判断する方法

fuser -v /dev/urandomを実行すると、現在/dev/urandomが開いているプロセスがわかりますが、それだけです。それぞれが時間の経過とともにどれだけのエントロピーを使い果たしているかについて何かを決定することはありましたか?たとえば、あるプロセスが毎分約1ビットのエントロピーを使用しているのに対し、別のプロセスは毎秒約8ビットを使用している可能性があります。それを判断する方法が欲しいのですが。

5
Matthew Cline

エントロピーが消費されないため、短い答えは0です。

一般的な誤解 エントロピーが消費されるというものがあります—ランダムビットを読み取るたびに、これによりランダムソースからエントロピーが削除されます。これは間違っています。 エントロピーを「消費」しません 。はい、 Linuxのドキュメントで間違っています

Linuxシステムのライフサイクルには、次の2つの段階があります。

  1. 最初は、十分なエントロピーがありません。 /dev/randomは、十分なエントロピーを蓄積したと見なすまでブロックします。 /dev/urandomは低エントロピーデータを喜んで提供します。
  2. しばらくすると、ランダムジェネレータープールに十分なエントロピーが存在します。 /dev/randomは「エントロピーネギ」の偽のレートを割り当て、時々ブロックします。 /dev/urandomは暗号品質のランダムデータを喜んで提供します。

FreeBSDはそれを正しく理解します。FreeBSDでは、/dev/random(または同じことである/dev/urandom)は、十分なエントロピーがない場合はブロックし、エントロピーが十分になると、ランダムデータを吐き出し続けます。 Linuxでは、/dev/random/dev/urandomも役に立ちません。

実際には、/dev/urandomを使用し、システムをプロビジョニングするときに、エントロピープールが供給されることを確認します(ディスク、ネットワーク、およびマウスアクティビティから、ハードウェアソースから、外部マシンからなど)。

/dev/urandomから読み取られるバイト数を読み取ろうとすることもできますが、これはまったく意味がありません。 /dev/urandomから読み取っても、エントロピープールは使い果たされません。各コンシューマーは、名前を付けたい時間の単位ごとに0ビットのエントロピーを使用します。

自動化されていませんが、straceなどのツールを使用して、urandomに関連するファイル記述子からの読み取りを監視できます。次に、特定の期間に読み取られたデータの量を確認して、読み取り速度を取得します。

1
MJD

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)...だから、座ってプロメテウスのグラフを見てください...

Prometheus graph showing node_entropy_available_bits over time with descriptions

調整して繰り返すこともできます...(今回は、ファイル記述子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) 。プロセスが乱数にアクセスできる他のいくつかの方法について説明します。

  • getrandom()システムコール<-RHEL7.4 +に推奨、エントロピープールが初期化された後にブロックすることなく高品質
  • / dev/random <-簡単にブロックします
  • / dev/urandom <-プールが開始される前に使用された場合の問題。 '決してブロックしません';ほとんどのアプリケーションが使用する必要があります。
  • AT_RANDOM <-実行時に16個のランダムバイトを1回設定します

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

0
Cameron Kerr