Como determinar quais processos estão usando quanta entropia de/dev/urandom

Como determinar quais processos estão usando quanta entropia de/dev/urandom

Doing fuser -v /dev/urandomme diz quais processos estão /dev/urandomabertos no momento, mas apenas isso. Existe alguma maneira de determinar alguma coisa sobre quanta entropia cada um está consumindo ao longo do tempo? Por exemplo, pode ser que um processo esteja consumindo cerca de 1 bit de entropia a cada minuto, enquanto outro processo esteja consumindo cerca de 8 bits por segundo; Eu gostaria de alguma maneira de determinar isso.

Responder1

A resposta curta é 0, porque a entropia não é consumida.

Existe umequívoco comumque a entropia é consumida – que cada vez que você lê um bit aleatório, isso remove alguma entropia da fonte aleatória. Isto está errado.Você não “consome” entropia. Sim,a documentação do Linux erra.

Durante o ciclo de vida de um sistema Linux, existem dois estágios:

  1. Inicialmente, não há entropia suficiente. /dev/randombloqueará até achar que acumulou entropia suficiente; /dev/urandomfelizmente fornece dados de baixa entropia.
  2. Depois de um tempo, entropia suficiente está presente no conjunto gerador aleatório. /dev/randomatribui uma taxa falsa de “alho-porro de entropia” e bloqueia de vez em quando; /dev/urandomfelizmente fornece dados aleatórios com qualidade criptográfica.

O FreeBSD acerta: no FreeBSD, /dev/random(ou /dev/urandom, que é a mesma coisa) bloqueia se não tiver entropia suficiente e, quando isso acontece, continua vomitando dados aleatórios. No Linux, nem /dev/randomé /dev/urandomútil.

Na prática, use /dev/urandom, e certifique-se, ao provisionar seu sistema, de que o pool de entropia seja alimentado (da atividade do disco, da rede e do mouse, de uma fonte de hardware, de uma máquina externa,…).

Embora você possa tentar ler quantos bytes são lidos /dev/urandom, isso é completamente inútil. A leitura de /dev/urandomnão esgota o conjunto de entropia. Cada consumidor usa até 0 bits de entropia por qualquer unidade de tempo que você queira nomear.

Responder2

Embora não seja automatizado, você pode usar uma ferramenta como strace para observar leituras do(s) descritor(es) de arquivo relacionado(s) ao urandom. Em seguida, veja quantos dados são lidos em um período específico para obter a taxa de leitura.

Responder3

Existem algumas maneiras de abordar o problema se você não souber (ou não suspeitar) qual processo pode estar esgotando o entropy_available no Linux.

Conforme mencionado, você pode usar strace, o que é ótimo para obter informações úteis sobre quais processos você deseja examinar.

Você poderia usar auditd para auditar quais processosabrir/dev/random ou /dev/urandom, mas isso não informa quantos dados são lidos (para evitar problemas de registro). Aqui estão alguns comandos para listar as regras e depois adicionar dois relógios

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

Agora faça SSH na caixa (ou faça outra coisa que você sabe que deve resultar na abertura de /dev/urandom ou similar, como dd).

ausearch -ts recente | aureport -f

No meu caso, vejo algo como o seguinte:

[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

Desative esses relógios

auditctl -W /dev/random
auditctl -W /dev/urandom

Lembre-se, porém, de que isso capturará apenas dados para chamadas do sistema que não são de leitura/gravação, etc., portanto, se houver algo que já esteja aberto, você não o verá sendo lido.

No entanto, percebi (usando Prometheus e node_exporter) que ainda estava vendo um padrão dente de serra em que a VM (CentOS 7 sem nada para coletar entropia) relatava entropy_available aumentando para quase 200 e, ao fazer isso, cairia de volta para 0.

O lsof (do fusor, se preferir) oferece alguma coisa?

[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

Observe o dispositivo de caracteres, números maiores e menores; testando de outra forma... (não tenho certeza se isso seria útil, apenas pensando em termos de coisas como o Docker, que não está rodando nesta VM)

[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

Ok, então temos dois processos, chronyd e tuned. Vamos usar strace. lsof nos disse que chrony tinha /dev/urandom aberto para leitura usando o descritor de arquivo 3

[root@metrics-d02 vagrant]# strace -p 2184 -f
strace: Process 2184 attached
select(6, [1 2 5], NULL, NULL, {98, 516224}
.... (I'm waiting)

Portanto, o chronyd está aguardando alguma atividade, com um tempo limite de 98 segundos a partir do momento em que iniciou esta chamada de sistema.

Enquanto espero, devo destacar que minha atividade no sistema provavelmente aumentará a estimativa dos kernels de bits aleatórios disponíveis. (entropy_available)... então sente-se e observe o gráfico do Prometheus...

Gráfico do Prometheus mostrando node_entropy_available_bits ao longo do tempo com descrições

Podemos repetir com tune também... (desta vez adicionando alguns timestamps e um filtro grep apenas para o descritor de arquivo 5 (as chamadas read etc. teriam isso como primeiro argumento)

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

A Red Hat tem um blog que discute mais detalhadamenteCSPRNG (gerador de números aleatórios pseudo-aleatórios criptograficamente seguros). Ele discute algumas outras maneiras pelas quais os processos podem obter acesso a números aleatórios:

  • chamada de sistema getrandom() <- recomendado para RHEL7.4+, alta qualidade sem bloqueio após a inicialização do pool de entropia
  • /dev/random <- bloqueará facilmente
  • /dev/urandom <-- problema quando usado antes do pool ser iniciado. 'Nunca bloqueará'; deve ser o que a maioria dos aplicativos deve usar.
  • AT_RANDOM <- define 16 bytes aleatórios uma vez no tempo de execução

Embora AT_RANDOM não seja útil, ele está presente em todos os processos, portanto, apenas o ato de iniciar um processo deve esgotar pelo menos um pouco.

Você perceberá agora que o que mostrei acima usando lsof não é suficiente, não revela o uso de getrandom(). Mas como getrandom() é uma chamada de sistema, deveríamos ser capazes de revelar seu uso usando 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)

Fiquei entediado e entrei na caixa e vi muitas coisas interessantes e legais, mas nada de getrandom(), o que não deveria ser uma surpresa, pois vimos isso usando a API /dev/urandom anteriormente.

Então, tentando levar em conta as depressões no gráfico, nada está abrindo /dev/*random, e nada que o tenha aberto está usando-o no momento, e nada parece estar chamando getrandom()... Há mais alguma coisa que poderia consumir dados do [pool atrás de /dev/random]? E o kernel? Considere funcionalidades como ASLR (Address Space Layout Randomisation):

https://access.redhat.com/solutions/44460 [requer assinatura]

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

'2' aqui significa que além de randomizar onde coisas como mmap e stack (etc.) são carregadas, ele também permitirá a randomização de heap. O que acontece se desligarmos isso

[root@metrics-d02 vagrant]# echo 0 > /proc/sys/kernel/randomize_va_space
[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space 
0

(Resposta: a mesma coisa... talvez alguém possa ilustrar isso melhor)

O kernel também estará onde AT_RANDOM está definido. Aqui está um exemplo simples que você pode usar strace para observar que ele não chama /dev/*random ou 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

Espero que seja útil.

Na prática, eu examinaria primeiro as cargas de trabalho Java, pois é onde normalmente sou mais afetado por isso. Verhttps://blogs.oracle.com/luzmestre/why-does-my-weblogic-server-takes-a-long-time-to-startPor exemplo.

informação relacionada