Control de tiempo y rendimiento

Una de las prioridades durante el desarrollo de Nmap ha sido siempre el rendimiento. Un sondeo por omisión (nmap <nombre_de_sistema>) de cualquier sistema en una red local tarda un quinto de segundo. Esto es menos que el tiempo que uno tarda en parpadear, pero se va sumando al tiempo que se tarda cuando se realiza un sondeo sobre decenas o centenares o miles de equipos. Además, ciertas opciones de sondeo como puedan ser el sondeo UDP y la detección de versiones pueden incrementar los tiempos de sondeos de forma sustancial. También puede afectar a este tiempo algunas configuraciones de sistemas cortafuegos, especialmente cuando implementan limitaciones a la tasa de respuestas. Aunque Nmap trabaja en paralelo y tiene muchos algoritmos avanzados para acelerar estos sondeos, el usuario tiene el control en última instancia de cómo funciona éste. Los usuarios con experiencia pueden definir las órdenes a Nmap cuidadosamente para obtener sólo la información que necesitan mientras que, al mismo tiempo, cumplen las limitaciones de tiempo que tengan.

Algunas técnicas que pueden ayudar a mejorar los tiempos de sondeo son el limitar el número de pruebas que no sean críticas y actualizar a la última versión de Nmap (se hacen mejoras de rendimiento con cierta frecuencia). La optimización de los parámetros de control de tiempo pueden introducir también diferencias significativas. Las opciones aplicables se detallan a continuación.

Algunas opciones aceptan un parámetro tiempo. Este valor se especifica, por omisión, en milisegundos, aunque puede seguirlo de ‘s’, ‘m’, o ‘h’ para indicar segundos, minutos, u horas. Por tanto, el valor 900000, 900s, y 15m hacen exáctamente lo mismo al aplicarse a la opción --host-timeout.

--min-hostgroup <numsists>; --max-hostgroup <numsists> (Ajustar el tamaño del grupo para los sondeos paralelos)

Nmap tiene la capacidad de hacer un sondeo de puertos o versiones sobre múltiples sistemas en paralelo. Hace eso dividiendo el espacio de direcciones IP en grupos y analizando un grupo cada vez. Habitualmente es más eficiente utilizar grupos grandes. La contrapartida es que los resultados por sistema no se pueden dar hasta que se ha terminado de analizar todo el grupo. En este caso, si Nmap empezara con un tamaño de grupo de 50, el usuario no obtendría ningún resultado hasta que termine con los primeros 50 (excepto las actualizaciones que envía el modo detallado)

Nmap tiene una implementación de compromiso por omisión para resolver este conflicto. Empieza los sondeos con un tamaño de grupo inferior a cinco para que los primeros resultados se obtengan con rapidez y después se incrementa el tamaño de grupo hasta, como mucho, 1024. El número exacto por omisión depende de las opciones dadas en la ejecución. Nmap utiliza grupos más grandes para los sondeos UDP y para aquellos sondeos TCP con pocos puertos por razones de eficiencia.

Nmap nunca excede el tamaño indicado cuando éste se especifica con --max-hostgroup. Si se indica un valor mínimo en --min-hostgroup Nmap intentará mantener el tamaño de los grupos por encima de ese nivel. Nmap puede tener que utilizar grupos más pequeños si no hay suficientes sistemas objetivo en una interfaz dada para cumplir el mínimo especificado. Se pueden especificar ambos valores para mantener el tamaño de grupo dentro de un rango específico, aunque ésto es poco habitual.

El uso principal de esta opción es el de especificar el tamaño de grupo mínimo para que los sondeos se ejecuten más rápidamente. 256 es un valor habitual para sondear la red en trozos del tamaño de una clase C. Si se trata de un sondeo con muchos puertos no sirve de mucho incrementar ese número. Si los sondeos son de pocos puertos puede ayudar utilizar un tamaño de grupo de 2048 o más elementos.

--min-parallelism <numsondas>; --max-parallelism <numsondas> (Ajustar el número de sondas enviadas en paralelo)

Esta opción controla el número de sondas activas para un grupo de sistemas. Éstas se utilizan para los sondeos de puertos y el descubrimiento de equipos. Por omisión, Nmap calcula un valor ideal del número de sondas a enviar en paralelo basado en el rendimiento de la red. Si se pierden paquetes Nmap reduce este valor para ir más lento y permitir menos sondas activas. El valor ideal de las sondas se incrementará a medida que la red muestre que puede utilizarse de nuevo. Estas opciones ponen un valor mínimo o máximo a esa variable. Por omisión, el valor ideal puede ser inferior a 1 si la red no es fiable e incrementarse a varios cientos si ésta funciona correctamente.

Lo más habitual es fijar el valor --min-parallelism a un número mayor que uno para que los sondeos contra sistemas o redes poco eficientes sean rápidos. Esta es una opción que tiene sus riesgos, ya que si se define un valor demasiado elevado se puede reducir la precisión del sondeo. Si se fija también se impide a Nmap controlar el paralelismo de forma dinámica basándose en las condiciones de la red. Un valor razonable puede ser diez, aunque sólo debe ajustarse como último recurso.

A veces se fija la opción --max-parallelism a uno para evitar que Nmap envíe más de una sonda a la vez a los sistemas. Esto puede ser útil conjuntamente con --scan-delay (del que se habla más adelante), aunque habitualmente es suficiente con utilizar este último por sí sólo.

--min-rtt-timeout <tiempo>, --max-rtt-timeout <tiempo>, --initial-rtt-timeout <tiempo> (Ajustar expiración de sondas)

Nmap mantiene un valor de expiración en ejecución para saber cuánto tiempo debe esperar para recibir la respuesta a una sonda o para retransmitir la sonda. Este valor está calculado en base a los tiempos de respuesta de las sondas previamente enviadas. El valor de expiración puede llegar a ser de varios segundos si se demuestra que la latencia de la red es significativa y variable. También empieza en un valor conservador (alto) y puede mantenerse en ese valor durante un tiempo cuando Nmap sondee equipos que no respondan.

Se pueden recortar los tiempos de análisis de forma apreciable si se especifican valores para --max-rtt-timeout y --initial-rtt-timeout por debajo de los de por omisión. Esto es especialmente verdadero en sondeos en los que no se envían paquetes ICMP (-P0) y en aquellos realizados en redes con mucho filtrado. Sin embargo, no se debería establecer a valores muy agresivos. El sondeo puede acabar tardando más de lo esperado si se especifica un valor bajo que hace que las sondas expiren y se retransmitan mientras está llegando la respuesta.

En el caso de que todos los sistemas estén en una red local al equipo que sondea, un valor razonablemente agresivo para --max-rtt-timeout es 100 milisegundos. Si se está rutando, primero envíe un ping a un equipo en la red con la herramienta ICMP ping, o con una herramienta para construir paquetes a medida como hping2 dado que es más probable que atraviese cualquier cortafuegos. Consulte el tiempo máximo de la ronda (tiempo entre solicitud y respuesta) después de haber enviado unos diez paquetes. Una vez obtenido ese valor puede utilizarlo el doble de éste para --initial-rtt-timeout y triplicarlo o cuadruplicarlo para --max-rtt-timeout. Yo no configuro habitualmente el valor máximo rtt por debajo de 100ms, independientemente del valor que den los ping. Ni tampoco lo pongo por encima de 1000ms.

La opción --min-rtt-timeout se utiliza rara vez, aunque puede ser útil cuando la red es tan poco fiable que incluso los valores por omisión son demasiado agresivos. Dado que Nmap sólo reduce el tiempo al mínimo cuando la red parece fiable este valor es poco habitual y debería reportarse como una errata en la lista de correo nmap-dev.

--max-retries <reintentos> (Especifica el número máximo de sondas de puertos que se retransmiten)

Un puerto podría estar filtrado si Nmap no recibe ninguna respuesta a una sonda de análisis de puertos. O puede que la sonda o la respuesta a ésta se perdiera en la red. También puede darse el caso de que el sistema objetivo tenga una limitación de tasa de tráfico que haga que la respuesta quede bloqueada temporalmente. Así, Nmap lo intenta de nuevo retransmitiendo la sonda inicial. Puede que lo haga más de una vez, si Nmap detecta que hay problemas en el funcionamiento de la red, antes de abandonar los sondeos de un puerto. Cuando el rendimiento es crítico, se pueden acelerar los sondeos limitando el número de retransmisiones permitidas. Puede especificar --max-retries 0 para que no se haga ninguna retransmisión, aunque no se recomienda.

El valor por omisión (cuando no hay una plantilla -T) es permitir las retransmisiones. Nmap generalmente sólo hará una retransmisión si la red parece fiable y el sistema objetivo no tiene una limitación de tasa de tráfico. Es por esto por lo que la mayoría de los sondeos no se verán afectados si reduce el valor de --max-retries a un valor pequeño, como pudiera ser tres. Estos valores pueden hacer que los sondeos a equipos lentos (limitados en tasa) sean más rápidos. Puede que pierda información cuando Nmap dé por finalizado el análisis de un puerto antes de tiempo, aunque eso puede ser mejor que hacer que la expire el --host-timeout y se pierda toda la información del objetivo.

--host-timeout <tiempo> (Abandona equipos objetivo lentos)

Hay algunos equipos en los que simplemente se tarda demasiado en sondearlos. Esto puede deberse a hardware de red de bajo rendimiento o poco fiable o bien a software, limitaciones de tasas de paquetes o un cortafuegos demasiado restrictivo. Puede llegar a darse que Nmap dedica la mayor parte del tiempo de análisis en sondear un porcentaje reducido de sistemas. A veces es mejor reducir las bajas y saltarse esos sistemas inicialmente. Esto puede hacerse con la opción --host-timeout, indicando el tiempo máximo que está dispuesto a esperar. Yo especifico habitualmente 30m para asegurarse de que Nmap no gasta más de media hora en un solo sistema. Tenga en cuenta que Nmap puede estar sondeando otros equipos al mismo tiempo durante esa media hora, por lo que no se pierde todo ese tiempo. Cualquier sistema que expire se salta. No se imprimirá la tabla de puertos, la detección de sistema operativo o la detección de versiones para ese sistema.

--scan-delay <tiempo>; --max-scan-delay <tiempo> (Ajusta la demora entre sondas)

Esta opción hace que Nmap espere al menos el tiempo indicado entre cada sonda enviada a un sistema determinado. Esto es muy útil cuando se quiere limitar la tasa de tráfico. Los sistemas Solaris (entre otros) responderán a paquetes de sondeos UDP con sólo un mensaje ICMP por segundo. Enviar más que eso con Nmap sería perder el tiempo. Un valor de 1s para --scan-delay hará que Nmap se mantenga a esa velocidad reducida. Nmap intenta detectar limitaciones de tasa y ajustar la demora del sondeo como considere necesario, pero a veces viene bien especificarlo de forma explícita si ya sabe qué valor es mejor.

El sondeo se ralentiza de forma drástica cuando Nmap incrementa el valor del tiempo de espera para poder tratar las limitaciones de tasa. Puede utilizar la opción --max-scan-delay para indicar el tiempo máximo de espera que permitirá Nmap. Si especifica un valor muy pequeño tendrá retransmisiones inútiles de paquetes y posiblemente no detecte puertos para los que el objetivo implemente tasas de tráfico estrictas.

También se puede usar --scan-delay para evitar sistemas de detección y prevención de intrusos (IDS/IPS) basados en umbrales.

-T <Paranoid|Sneaky|Polite|Normal|Aggressive|Insane> (Fija una plantilla de tiempos)

Algunas personas encuentran confusos los controles de grano fino explicados previamente, aunque éstos sean muy potentes y efectivos. Además, se puede a veces tardar más tiempo en encontrar los valores más apropiados que en hacer el análisis que se quiere optimizar. Nmap ofrece un acercamiento más sencillo, basado en seis plantillas de tiempos. Puede especificar cualquiera de éstas con la opción -T seguido de un número o su nombre. Los nombre de las plantillas son: paranoico (0), sigiloso (1), amable (2), normal (3), agresivo (4) y loco (5) (respectivamente "paranoid", "sneaky", "polite", "normal", "aggressive" e "insane", N. de. T.). Las primeras dos se utilizan para evadir IDS. El modo amable reduce el sondeo para que éste utilice menos ancho de banda y menos recursos de los sistemas analizados. El modo normal es el valor por omisión, así que la opción -T3 no hace nada realmente. El modo agresivo hace que los sondeos sean más rápidos al asumir que está en una red razonablemente más rápida y fiable. En modo loco asume que está en una red extraordinariamente rápida o que está dispuesto a sacrificar fiabilidad por velocidad.

Estas plantillas permiten que el usuario especifique cuan agresivo quiere ser, al mismo tiempo que deja que sea Nmap el que escoja los valores exactos de tiempos. Las plantillas hacen también algunos ajustes menores de velocidad para los cuales no existe aún una opción de control de grano fino. Por ejemplo, -T4 prohíbe que la expiración en sondeos dinámicos exceda los 10ms para puertos TCP y -T5 limita ese valor a 5 milisegundos. Las plantillas pueden utilizarse combinadas con controles de grano fino, siempre que se especifique primero la plantilla. Si no lo hace así los valores especificados por la plantilla modificarán los valores que defina como opción. Le recomiendo utilizar -T4 cuando sondee redes razonablemente modernas y fiables. Mantenga esa opción al principio de la línea de órdenes aún cuando especifique otras opciones de control de grano fino para poder beneficiarse de las optimizaciones menores que activa.

Le recomiendo que empiece siempre con -T4 si está utilizando una conexión de banda ancha o conexión Ethernet decente. Algunas personas adoran la opción -T5 aunque es demasiado agresiva para mi gusto. Otras personas especifican la opción -T2 porque piensan que es menos probable que bloqueen sistemas o porque se consideran a sí mismos amables en general. Muchas veces no se dan cuenta de lo lenta que -T Polite es realmente. Su sondeo puede llegar a tardar diez veces más que un sondeo por omisión. Dado que las caídas de sistemas y problemas de ancho de banda son raros con las opciones de tiempos por omisión (-T3), lo recomiendo habitualmente para las personas cuidadosas. Para reducir estos problemas es más efectivo omitir la detección de versiones que jugar con los valores de tiempos.

Mientras que puede ser útil evitar alarmas de IDS con -T0 y -T1, éste tardará mucho más tiempo para sondear miles de sistemas o puertos. Para este tipo de sondeos puede que prefiera fijar los valores exactos de tiempos que necesita antes que utilizar los valores predefinidos para -T0 y -T1.

Los efectos principales del uso de T0 es la serialización de los sondeos de forma que sólo se sondea un puerto cada vez, y se espera cinco minutos antes de enviar cada sonda. Las opciones T1 y T2 son similares pero sólo esperan 15 y 0.4 segundos entre sondas, respectivamente. El comportamiento por omisión de Nmap es T3, que incluye sondeos en paralelo. T4 es equivalente a especificar --max-rtt-timeout 1250 --initial-rtt-timeout 500 --max-retries 6 y fija el valor máximo para las demoras de sondeos TCP a 10 milisegundos. T5 hace lo mismo que --max-rtt-timeout 300 --min-rtt-timeout 50 --initial-rtt-timeout 250 --max-retries 2 --host-timeout 15m así como definir el valor máximo para las demoras de sondeos TCP a 5ms.