Cómo determinar qué procesos están usando cuánta entropía de /dev/urandom

Cómo determinar qué procesos están usando cuánta entropía de /dev/urandom

Hacer fuser -v /dev/urandomme dice qué procesos tengo /dev/urandomabiertos actualmente, pero solo eso. ¿Hay alguna forma de determinar algo sobre cuánta entropía está consumiendo cada uno con el tiempo? Por ejemplo, podría ser que un proceso esté consumiendo aproximadamente 1 bit de entropía cada minuto, mientras que otro proceso esté consumiendo aproximadamente 8 bits por segundo; Me gustaría alguna forma de determinar eso.

Respuesta1

La respuesta corta es 0, porque no se consume entropía.

Hay unMalentendido comúnesa entropía se consume, que cada vez que lees un bit aleatorio, esto elimina algo de entropía de la fuente aleatoria. Esto está mal.No “consume” entropía. Sí,la documentación de Linux se equivoca.

Durante el ciclo de vida de un sistema Linux, existen dos etapas:

  1. Al principio no hay suficiente entropía. /dev/randombloqueará hasta que crea que ha acumulado suficiente entropía; /dev/urandomfelizmente proporciona datos de baja entropía.
  2. Después de un tiempo, hay suficiente entropía en el grupo de generadores aleatorios. /dev/randomasigna una tasa falsa de “puerro de entropía” y bloquea de vez en cuando; /dev/urandomfelizmente proporciona datos aleatorios de calidad criptográfica.

FreeBSD lo hace bien: en FreeBSD, /dev/random(o /dev/urandom, que es lo mismo) se bloquea si no tiene suficiente entropía y, una vez que la tiene, sigue arrojando datos aleatorios. En Linux ni /dev/randomni /dev/urandomes lo útil.

En la práctica, use /dev/urandomy asegúrese de que cuando aprovisione su sistema se alimente el grupo de entropía (desde la actividad del disco, la red y el mouse, desde una fuente de hardware, desde una máquina externa,…).

Si bien podría intentar leer de cuántos bytes se leen /dev/urandom, esto es completamente inútil. Leer desde /dev/urandomno agota el conjunto de entropía. Cada consumidor utiliza 0 bits de entropía por cualquier unidad de tiempo que desee nombrar.

Respuesta2

Si bien no está automatizado, puede usar una herramienta como strace para observar las lecturas de los descriptores de archivos relacionados con urandom. Luego vea cuántos datos se leen durante un período de tiempo específico para obtener la velocidad de lectura.

Respuesta3

Hay algunas formas de abordar el problema si no sabe (o no sospecha) qué proceso puede estar agotando entropy_available en Linux.

Como se mencionó, puede usar strace, que es excelente para obtener información útil sobre qué procesos es posible que desee examinar.

Podrías usar auditd para auditar qué procesosabierto/dev/random o /dev/urandom, pero eso no le dirá cuántos datos se leen (para evitar problemas de registro). Aquí hay algunos comandos que enumeran las reglas y luego agregan dos relojes.

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

Ahora SSH en el cuadro (o haga algo más que sepa que debería dar como resultado la apertura de /dev/urandom o similar, como dd).

ausearch -ts reciente | aureport -f

En mi caso veo algo como lo siguiente:

[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

Desactive esos relojes

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

Sin embargo, recuerde que esto solo capturará datos para llamadas al sistema que no son de lectura/escritura, etc., por lo que si hay algo que ya lo tiene abierto, no verá que se esté leyendo.

Sin embargo, noté (usando Prometheus y node_exporter) que todavía veía un patrón de dientes de sierra por el cual la VM (CentOS 7 sin nada para recolectar entropía) informaba que entropy_available aumentaba hasta casi 200 y al hacerlo volvía a caer a 0.

¿lsof (de fusor si lo prefiere) ofrece algo?

[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

Sin embargo, tenga en cuenta los números mayores y menores del dispositivo de caracteres; probando de otra manera... (No estoy seguro de si esto sería útil, solo pienso en términos de cosas como Docker, que no se ejecuta en esta 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

Bien, entonces tenemos dos procesos, chronyd y tuned. Usemos strace. lsof nos dijo que chrony tenía /dev/urandom abierto para leer usando el descriptor de archivo 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)

Entonces chronyd está esperando alguna actividad, con un tiempo de espera de 98 segundos desde que inició esta llamada al sistema.

Mientras espero, debo resaltar que mi actividad en el sistema probablemente aumentará la estimación del kernel de bits aleatorios disponibles. (entropía_disponible)... así que siéntate y mira el gráfico de Prometheus...

Gráfico de Prometheus que muestra node_entropy_available_bits a lo largo del tiempo con descripciones

También podemos repetir con tuned... (esta vez agregando algunas marcas de tiempo y un filtro grep solo para el descriptor de archivo 5 (las llamadas de lectura, etc. tendrían esto como primer argumento)

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

Red Hat tiene un blog que analiza más a fondoCSPRNG (generador de números pseudoaleatorios criptográficamente seguro). Analiza algunas otras formas en que los procesos pueden obtener acceso a números aleatorios:

  • llamada al sistema getrandom() <-- recomendado para RHEL7.4+, alta calidad sin bloqueo después de que se haya inicializado el grupo de entropía
  • /dev/random <-- bloqueará fácilmente
  • /dev/urandom <-- problema cuando se usa antes de que se haya iniciado el grupo. "Nunca bloqueará"; debería ser lo que deberían usar la mayoría de las aplicaciones.
  • AT_RANDOM <-- establece 16 bytes aleatorios una vez en tiempo ejecutivo

Si bien AT_RANDOM no es útil, está presente en todos los procesos, por lo que el simple hecho de iniciar un proceso debería consumir al menos un poco.

Ahora te darás cuenta de que lo que he mostrado arriba usando lsof no es suficiente, no revela el uso de getrandom(). Pero dado que getrandom() es una llamada al sistema, deberíamos poder revelar su 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)

Me aburrí y entré a la caja, y vi muchas cosas interesantes, pero no getrandom(), lo cual no debería ser una sorpresa, ya que lo vimos usando la API /dev/urandom anteriormente.

Entonces, al tratar de tener en cuenta las depresiones en el gráfico, nada abre /dev/*random, y nada que lo tenga abierto lo está usando actualmente, y nada parece estar llamando a getrandom()... ¿Hay algo más que pueda ¿Consumir datos del [grupo detrás de /dev/random]? ¿Qué pasa con el núcleo? Considere funciones como la aleatorización del diseño del espacio de direcciones (ASLR):

https://access.redhat.com/solutions/44460 [requiere suscripción]

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

'2' aquí significa que además de aleatorizar dónde se cargan elementos como mmap y stack (etc.), también permitirá la aleatorización del montón. ¿Qué pasa si apagamos eso?

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

(Respuesta: lo mismo... quizás alguien más pueda ilustrar esto mejor)

El kernel también será donde se establezca AT_RANDOM. Aquí hay un ejemplo simple que puede usar strace para observar que no llama a /dev/*random o 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 sea útil.

En la práctica, primero miraría las cargas de trabajo de Java, ya que es ahí donde normalmente me molesta más esto. Verhttps://blogs.oracle.com/luzmestre/porque-mi-servidor-weblogic-toma-mucho-tiempo-para-iniciarpara un ejemplo.

información relacionada