¿Cómo evitar que se agote /dev/random? - mod_ssl apache

En algunos sistemas no se recomiendo abusar de /dev/random sin embargo es posible tunear el sistema para que las funciones críticas lo utilicen sin problema.

Publicado por AlbertoBSD el 2019-12-15 23:38:35

¿Por qué es importante la disponibilidad de números aleatorios "seguros" en el sistema?

En esta era de información la seguridad de la misma es muy importante. Si estas preocupado por que la información sensible que viaja entre tu pagina y el navegador de tus visitantes no sea leída (espiada) por cualquiera que este Sniffeando en la red lo primero que realizamos es proveer nuestra pagina por un canal seguro SSL.

Posteriormente lo ideal sería asegurarse que el módulo SSL utilice la mejor semilla de números aleatorios disponible en el sistema /dev/random

Veamos la configuración del modulo ssl de Apache referente a la utilización de números aleatorios:

En debian: /etc/apache2/mods-available/ssl.conf

<IfModule mod_ssl.c>
	SSLRandomSeed startup builtin
	SSLRandomSeed startup file:/dev/urandom 512
	SSLRandomSeed connect builtin
	SSLRandomSeed connect file:/dev/urandom 512
	#Mas configuracion que no nos interesa de momento.
</IfModule>

Esta podría ser la configuración por defecto de la mayoría de los servidores sin tunear. Por lo menos es la que aparece por defecto en Debian 10.1 LAMP

Ahora si vemos la documentacion https://httpd.apache.org/docs/current/mod/mod_ssl.html

builtin

This is the always available builtin seeding source. Its usage consumes minimum CPU cycles under runtime and hence can be always used without drawbacks. The source used for seeding the PRNG contains of the current time, the current process id and a randomly chosen 128 bytes extract of the stack. The drawback is that this is not really a strong source and at startup time (where the scoreboard is still not available) this source just produces a few bytes of entropy. So you should always, at least for the startup, use an additional seeding source.

Segun la documentacion esta función builtin siempre esta disponible pero al parecer no se considera una semilla segura para el PRNG del modssl

Lo ideal seria:

  • Quitar esa linea builtin tanto del startup como del connect
  • Cambiar /dev/urandom por /dev/random

Para realizar esto último es necesario tener algunas consideraciones, ya que en muchos sistemas linux el device /dev/random se puede agotar rápidamente y si se configura el modulo ssl con la configuración sugerida es posible que las conexiones entrantes se queden colgadas hasta que el archivo /dev/random recupere un poco de Entropía y de esto se encarga el kernel

Source disponibles de Entropía

En los sistemas Linux existen varios sources de entropía sin embargo algunos de estos no están disponibles en servidores

  • Tiempos de pulsaciones en teclado (No disponible en servidores)
  • Tiempos de acceso a escritura/lectura en Disco
  • Movimientos de Mouse (No disponible en servidores)
  • Hardware RNG

La mejor opciones es tener algún hardware RNG disponible para, sin embargo muchas veces esto no siempre es posible.

En el caso de contar con algún Hardware RNG tenemos la mitad del camino ganada

Lo primero es configurar rngd

rngd

This daemon feeds data from a random number generator to the kernel's random number entropy pool, after first checking the data to ensure that it is properly random.

Como vemos es posible configurar un source adicional para /dev/random adicional a la entropía que el mismo Kernel acumula

Tenemos que asegurarnos que rngd detecte nuestro hardware RNG mediante el comando rngd -v

Available entropy sources:
        DRNG

Donde DRNG es el hardware de Intel para la generación de números aleatorios

Ahora tenemos 2 formas de configurar rngd la primera es si tenemos Hardware RNG y la segunda si no

  • Si tenemos Hardware RNG los parametros de rngd serial los siguientes --foreground --random-step=32 --fill-watermark=2048
  • NO tenemos hardware RNG los parámetros podrian ser los siguientes: --foreground --rng-device=/dev/urandom --random-step=32 --fill-watermark=2048

En el primer caso se llena el buffer de /dev/random hasta llegar a 2048 bytes con datos obtenidos directamente de la función del procesador Intel® Digital Random Number Generator (DRNG) para el ejemplo mostrado en este caso

En el segundo caso se llena el buffer de /dev/random hasta 2048 con datos de /dev/urandom aunque parezca un tanto recursivo, con esto en caso de no contar con hardware RNG nos aseguramos de siempre estar enviando la entropia disponible en el kernel + el relleno de /dev/urandom al mod_ssl como una semilla inicial para las conexiones entrantes.

Al solo llenarlo hasta 2048 bytes cuando el buffer total es de 4096 bytes nos aseguramos de que los datos que el kernel siga generando por su parte se coloquen al final del buffer quedando algo mas o menos asi

  • [bytes 0 - (X menor que 2048)] Datos ya existentenes el buffer
  • [bytes (X menor que 2048) - 2048] Datos enviados por DRNG o /dev/random
  • [bytes mayores a 2048] Datos nuevos generados por el Kernel

Para monitorear el estatus actual de la entropía tenemos el siguiente comando

cat /proc/sys/kernel/random/entropy_avail

Ahora que ya nos aseguramos que el device /dev/random no se agotara podremos tunear un poco la configuración de mod_ssl, en mi caso a quedado de la siguiente forma

<IfModule mod_ssl.c>
	SSLRandomSeed startup file:/dev/random 1024
	SSLRandomSeed connect file:/dev/random 1024
	#Mas configuracion que no nos interesa de momento.
</IfModule>

Después de reiniciar el servidor apache podremos comprobar que la cantidad de entropía disponible comienza a variar, pero nunca baja de 2048 bytes

He comprobado esta configuración en un servidor con aproximadamente 100 usuarios distintos conectados por https en cada minuto y la entropía disponible varía algo pero nunca baja de 2048

please login
Login to comment
Loging with github