/dev/urandom에서 어느 프로세스가 얼마나 많은 엔트로피를 사용하고 있는지 확인하는 방법

/dev/urandom에서 어느 프로세스가 얼마나 많은 엔트로피를 사용하고 있는지 확인하는 방법

Doing은 fuser -v /dev/urandom현재 어떤 프로세스가 열려 있는지 알려 주지만 /dev/urandom그것만 알려줍니다. 시간이 지남에 따라 각각의 엔트로피가 얼마나 소모되는지 확인할 수 있는 것이 있습니까? 예를 들어, 한 프로세스는 매분 약 1비트의 엔트로피를 사용하는 반면 다른 프로세스는 초당 약 8비트를 사용하고 있을 수 있습니다. 나는 그것을 결정할 수 있는 어떤 방법을 원합니다.

답변1

엔트로피가 소모되지 않기 때문에 짧은 대답은 0입니다.

이있다일반적인 오해해당 엔트로피는 소비됩니다. 즉, 무작위 비트를 읽을 때마다 무작위 소스에서 일부 엔트로피가 제거됩니다. 이것은 잘못된 것입니다.엔트로피를 '소비'하지 않습니다.. 예,Linux 문서가 잘못되었습니다.

Linux 시스템의 수명 주기에는 두 단계가 있습니다.

  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비트의 엔트로피를 사용합니다.

답변2

자동화되지는 않았지만 strace와 같은 도구를 사용하여 urandom과 관련된 파일 설명자에서 읽기를 감시할 수 있습니다. 그런 다음 읽기 속도를 얻기 위해 특정 기간 동안 읽은 데이터의 양을 확인합니다.

답변3

Linux에서 어떤 프로세스가 entropy_available을 고갈시킬 수 있는지 모르거나 의심하지 않는 경우 문제에 접근할 수 있는 몇 가지 방법이 있습니다.

언급한 대로 strace를 사용할 수 있는데, 이는 어떤 프로세스를 살펴보고 싶은지에 대한 유용한 통찰력을 얻는 데 좋습니다.

auditd를 사용하여 어떤 프로세스를 감사할 수 있나요?열려 있는/dev/random 또는 /dev/urandom, 그러나 이는 읽혀진 데이터의 양을 알려주지 않습니다(로깅 문제를 방지하기 위해). 다음은 규칙을 나열한 다음 두 개의 시계를 추가하는 몇 가지 명령입니다.

auditctl -l
auditctl -w /dev/random
auditctl -w /dev/urandom
auditctl -l

이제 상자에 SSH를 실행합니다(또는 /dev/urandom 또는 dd와 같은 유사한 항목이 열리도록 알고 있는 다른 작업을 수행합니다).

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라는 두 가지 프로세스가 있습니다. strace를 사용해 보자. lsof는 chrony가 파일 디스크립터 3을 사용하여 읽기 위해 /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 그래프를 보세요...

설명과 함께 시간 경과에 따른 node_entropy_available_bits를 보여주는 Prometheus 그래프

tuned로도 반복할 수 있습니다... (이번에는 파일 설명자 5에 대해서만 타임스탬프와 grep 필터를 추가합니다(읽기 등의 호출은 이것을 첫 번째 인수로 갖습니다).

[root@metrics-d02 vagrant]# strace -p 2525 -f -tt -T 2>&1 | grep '(5,'

Red Hat에는 더 자세한 내용을 논의하는 블로그가 있습니다.CSPRNG(암호적으로 안전한 의사 난수 생성기). 프로세스가 난수에 액세스할 수 있는 몇 가지 다른 방법에 대해 설명합니다.

  • getrandom() 시스템 호출 <-- RHEL7.4+에 권장되며 엔트로피 풀이 초기화된 후 차단 없는 고품질
  • /dev/random <-- 쉽게 차단됩니다.
  • /dev/urandom <-- 풀이 시작되기 전에 사용하면 문제가 발생합니다. 절대 차단하지 않습니다. 대부분의 응용 프로그램이 사용해야 하는 것입니다.
  • AT_RANDOM <-- execve-time에 한 번 16개의 무작위 바이트를 설정합니다.

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/urandom API를 사용하여 본 것처럼 놀랄 일이 아닙니다.

따라서 그래프의 우울증을 설명하려고 하면 /dev/*random을 여는 것이 없으며 열려 있는 것도 현재 사용하고 있지 않으며 getrandom()을 호출하는 것도 없는 것 같습니다... 다른 것이 있습니까? [/dev/random 뒤의 풀]에서 데이터를 소비하시겠습니까? 커널은 어떻습니까? ASLR(Address Space Layout Randomization)과 같은 기능을 고려하십시오.

https://access.redhat.com/solutions/44460 [구독 필요]

[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space 
2

여기서 '2'는 mmap 및 스택 등이 로드되는 위치를 무작위화하는 것 외에도 힙 무작위화도 활성화한다는 의미입니다. 그걸 끄면 어떻게 될까요?

[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예를 들어.

관련 정보